c语言 字符串大数相加,大数相加c语言实现

本文介绍了一种使用C语言实现的大整数加法算法。通过数组存储任意位数的整数,并采用动态内存分配确保能处理任意长度的输入。文章详细展示了如何逐位进行加法运算并处理进位,同时提供了完整的源代码。
摘要由CSDN通过智能技术生成

c语言中int类型是有一定的范围的,例如在32位的情况下可以表示的最大整数是2^31 – 1 = 2147483647 。

如果想要进行更多位数的整数加法,可以用数组,分别对每个位进行计算。

合法数字检查

输入的时候应检查输入的是否是合法的数字,若不是则应进行处理。

分配空间

本文中的程序可以接收任意多位数的输入,因为采用的是运行时根据输入的位数分配空间的。

存放结果的数组,比两个数组中位数最多的那个位数还要多2,一个用来保存可能的进位(例如9+9 两个一位数结果是二位数),另一个用来保存表示字符串结束的空字符’\0′

输入54321和192后,在内存中是这样表示的

c2a138391a7c63120d37616d4e16575a.gif

个位对齐

数字按照字符的形式存入数组后,进行运算的时候还需要从个位开始算起,所以应该将num2向右移动,让个位对齐。

也可以将各个位数字逆序,这样从下标0开始,就是对齐的个位数字。

逆序的过程可以顺便把字符变为对应十进制数字,只需要减去’0’即可。

本程序中对齐后效果如下

c2a138391a7c63120d37616d4e16575a.gif

n1和n2分配空间大小是最长数字的位数+1 ,最高位后面全部置0.这样是为了计算时候的方便。

这样下标0是个位 下标1是十位 下标2是百位……

计算

c2a138391a7c63120d37616d4e16575a.gif

c语言代码

#include

#include

#include

#include

#define INIT_LENGTH 20//数字位数的起始大小

char * inputBigNum(void);//接收标准输入的数字 存入内存后返回地址 返回的地址需要free

char * bigNumAdd(const char *num1, const char *num2);//计算num1+num2 结果是一个指针 用完后需要free

int main(void)

{

char *num1;//数字1指针

char *num2;//数字2指针

char *res;//存放结果的指针

printf("Input the first num:\n");

num1 = inputBigNum();

while (num1 == NULL)//判断非法数字

{

printf("Invalid num, please input again:\n");

num1 = inputBigNum();

}

printf("Input the second num:\n");

while ((num2 = inputBigNum()) == NULL)//判断非法数字

{

printf("Invalid num, please input again:\n");

num2 = inputBigNum();

}

res = bigNumAdd(num1, num2);//计算

printf("num1: %s\n", num1);

printf("num2: %s\n", num2);

printf("res: %s\n", res);

free(num1);

free(num2);

free(res);

return 0;

}

/*

* 根据输入数字个数分配内存(采用翻倍增加空间的方式 有效利用率大于50%)

* 如果输入中有非数字 返回NULL

* 如果输入是合法数字 返回一个存放该数字字符串的指针

* 返回有效指针时,记得用完后释放内存

*/

char * inputBigNum(void)

{

char *p;

int i = 0;

int current_capacity = INIT_LENGTH;

char ch;

int ok = 1;

if ((p = (char *)malloc(INIT_LENGTH * sizeof(char))) == NULL)

exit(-1);

while ((ch = getchar()) != '\n')

{

p[i++] = ch;

if (ch < '0' || ch > '9')

{

ok = 0;

}

//已经写入了i个数字

if (i+1 == current_capacity)

{

if ((p = (char *)realloc(p, current_capacity * 2 * sizeof(char))) == NULL)

exit(-1);

current_capacity *= 2;

}

}

p[i] = '\0';

if (ok == 0)

{

free(p);

return NULL;

}

else

{

return p;

}

}

/*

* 计算num1 + num2 结果是字符串形式

* 返回存放结果的字符串地址,记得用完后free

*/

char * bigNumAdd(const char *num1, const char *num2)

{

int i;

int num1_len;//num1的数字位数

int num2_len;//num2的数字位数

int res_len;//计算结果的数字位数 包括最后的空字符'\0'

char *n1;//临时存放num1

char *n2;//临时存放num2

char *res;//存放结果

int c = 0;//每一位上的进位 个位上的进位初始时是0

//计算长度

num1_len = strlen(num1);

num2_len = strlen(num2);

res_len = num1_len > num2_len ? num1_len : num2_len;

//分配内存 两个加数最高位的更高一位设置为0 结果包含可能的进位和空字符'\0'

if ((n1 = (char *)malloc(res_len * sizeof(char) + 1)) == NULL)

exit(-1);

if ((n2 = (char *)malloc(res_len * sizeof(char) + 1)) == NULL)

exit(-1);

if ((res = (char *)malloc(res_len * sizeof(char) + 2)) == NULL)

exit(-1);

memset(n1, 0, res_len * sizeof(char) + 1);

memset(n2, 0, res_len * sizeof(char) + 1);

memset(res, 0, res_len * sizeof(char) + 2);

//将原加数按照逆序存入n1和n2 同时转换为数字

for (i = 0; i < num1_len; ++i)

{

n1[i] = num1[num1_len-i-1] - '0';

}

for (i = 0; i < num2_len; ++i)

{

n2[i] = num2[num2_len-i-1] - '0';

}

//按位进行加运算

for (i = 0; i < res_len + 1; ++i)

{

res[res_len-i] = ((n1[i] + n2[i] + c) % 10) + '0';//结果最高位是个位

c = (n1[i] + n2[i] + c) / 10;//进位

}

res[res_len+1] = '\0';//设置末尾的空字符

//释放临时内存

free(n1);

free(n2);

return res;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

#include

#include

#include

#include

#define INIT_LENGTH 20//数字位数的起始大小

char*inputBigNum(void);//接收标准输入的数字 存入内存后返回地址 返回的地址需要free

char*bigNumAdd(constchar*num1,constchar*num2);//计算num1+num2 结果是一个指针 用完后需要free

intmain(void)

{

char*num1;//数字1指针

char*num2;//数字2指针

char*res;//存放结果的指针

printf("Input the first num:\n");

num1=inputBigNum();

while(num1==NULL)//判断非法数字

{

printf("Invalid num, please input again:\n");

num1=inputBigNum();

}

printf("Input the second num:\n");

while((num2=inputBigNum())==NULL)//判断非法数字

{

printf("Invalid num, please input again:\n");

num2=inputBigNum();

}

res=bigNumAdd(num1,num2);//计算

printf("num1: %s\n",num1);

printf("num2: %s\n",num2);

printf("res: %s\n",res);

free(num1);

free(num2);

free(res);

return0;

}

/*

* 根据输入数字个数分配内存(采用翻倍增加空间的方式 有效利用率大于50%)

* 如果输入中有非数字 返回NULL

* 如果输入是合法数字 返回一个存放该数字字符串的指针

* 返回有效指针时,记得用完后释放内存

*/

char*inputBigNum(void)

{

char*p;

inti=0;

intcurrent_capacity=INIT_LENGTH;

charch;

intok=1;

if((p=(char*)malloc(INIT_LENGTH*sizeof(char)))==NULL)

exit(-1);

while((ch=getchar())!='\n')

{

p[i++]=ch;

if(ch'9')

{

ok=0;

}

//已经写入了i个数字

if(i+1==current_capacity)

{

if((p=(char*)realloc(p,current_capacity*2*sizeof(char)))==NULL)

exit(-1);

current_capacity*=2;

}

}

p[i]='\0';

if(ok==0)

{

free(p);

returnNULL;

}

else

{

returnp;

}

}

/*

* 计算num1 + num2 结果是字符串形式

* 返回存放结果的字符串地址,记得用完后free

*/

char*bigNumAdd(constchar*num1,constchar*num2)

{

inti;

intnum1_len;//num1的数字位数

intnum2_len;//num2的数字位数

intres_len;//计算结果的数字位数 包括最后的空字符'\0'

char*n1;//临时存放num1

char*n2;//临时存放num2

char*res;//存放结果

intc=0;//每一位上的进位 个位上的进位初始时是0

//计算长度

num1_len=strlen(num1);

num2_len=strlen(num2);

res_len=num1_len>num2_len?num1_len:num2_len;

//分配内存 两个加数最高位的更高一位设置为0 结果包含可能的进位和空字符'\0'

if((n1=(char*)malloc(res_len*sizeof(char)+1))==NULL)

exit(-1);

if((n2=(char*)malloc(res_len*sizeof(char)+1))==NULL)

exit(-1);

if((res=(char*)malloc(res_len*sizeof(char)+2))==NULL)

exit(-1);

memset(n1,0,res_len*sizeof(char)+1);

memset(n2,0,res_len*sizeof(char)+1);

memset(res,0,res_len*sizeof(char)+2);

//将原加数按照逆序存入n1和n2 同时转换为数字

for(i=0;i

{

n1[i]=num1[num1_len-i-1]-'0';

}

for(i=0;i

{

n2[i]=num2[num2_len-i-1]-'0';

}

//按位进行加运算

for(i=0;i

{

res[res_len-i]=((n1[i]+n2[i]+c)%10)+'0';//结果最高位是个位

c=(n1[i]+n2[i]+c)/10;//进位

}

res[res_len+1]='\0';//设置末尾的空字符

//释放临时内存

free(n1);

free(n2);

returnres;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值