两个大数相加

来源:互联网 发布:淘宝客怎么开通 编辑:程序博客网 时间:2024/05/21 10:14

       我们以前计算两个整数的和,需要定义两个整型变量来存储两个操作数。

       但是,若这两个数大到任何整型类型都存放不下时,我们该怎么来计算它们的和呢?这就是我们今天所讨论的话题!


解决思路:

      (1)、存储问题:我们可以使用字符串来存储操作数,这样不管操作数有多长都能放得下。

      (2)、计算问题:自定加法时,我们要考虑每一位的相加,还有相加时是否有进位值产生。若产生进位,则要在下一位相加时加上进位值。

      (3)、存储结果:两个数相加的结果的位数肯定小于等于两个数的较长的数的位数+1,因为要考虑的最高位进位。即:

                   结果的位数 = (操作数1位数  > 操作数2位数 ?  操作数1位数 : 操作数2位数) + 1;

      (4)、输出问题:这是最简单的问题,因为申请的结果位数可能大于真正的结果的位数。所以第一个字符可能为空字符'\0', 所以输出是应把它跳过。


好,思路理清了。开始写代码:

        写代码时遇到一个问题:释放所申请的结果的内存时出现释放错误


HEAP CORRUPTION DETECTED:after Normal block(#***) at 0x****.CRT detected that application wrote memory after end of heap buffer.


        可能很多人都遇见过这种错误,原因是:以对内在操作的过程中,所写的地址超出了所分配内在的边界。

但是我感觉并没有超界,但是没办法。用最笨的办法:

         将内存申请的大一些。所以我的结果位数比原来的大了一个字节,你们在代码中是可以看到的。然后程序就可以正常运行了!

源代码 :

#include<stdio.h>#include<string.h>#include<malloc.h>/***功能: 从键盘获取加法操作数的输入**参数说明: 无参数**返回值: 输入的操作数存储位置的指针*/char *GetOperInput(){char Oper[1000];  //定义一个足够大的空间char *pOper = NULL;  //指向真正存储操作数的指针int len;   //操作数的长度gets(Oper);len = strlen(Oper);pOper = malloc(len + 1);strncpy(pOper, Oper, len);  //将Oper的len个字节内容拷贝到pOper中pOper[len] = '\0';return pOper;}/***功能: 将两个字符串形式的整数相加,得到结果**参数说明: **@pAddResult: 存储加法结果;  **@pOperOne: 存储加法第一个操作数 @pOperTwo: 存储加法第二个操作数 (两个操作数不可更改)**返回值: 无*/void GetResult(char **pAddResult, int resultLength, const char *const pOperOne, const char *const pOperTwo){int carryValue = 0;  //进位值(两个数相加的进位值不是 0 就是 1 )int AddValue = 0;    //每一位相加后的值int lenOne = strlen(pOperOne);int lenTwo = strlen(pOperTwo);//lenOne、resultLength 和lenTwo要作为下标值lenOne--;lenTwo--;resultLength--;//循环相加每一位while (lenOne >= 0 && lenTwo >= 0){AddValue = (pOperOne[lenOne] - '0') + (pOperTwo[lenTwo] - '0') + carryValue;if (AddValue >= 10){carryValue = 1;AddValue -= 10;}else{carryValue = 0;}(*pAddResult)[resultLength] = AddValue + '0';lenOne--;lenTwo--;resultLength--;}//如果哪一个操作数剩下未相加的位,直接加到结果中while (lenOne >= 0){(*pAddResult)[resultLength] = pOperOne[lenOne] + carryValue;if (carryValue){carryValue = 0;}lenOne--;resultLength--;}while (lenTwo >= 0){(*pAddResult)[resultLength] = pOperOne[lenTwo] + carryValue;if (carryValue){carryValue = 0;}lenTwo--;resultLength--;}//如果有最高位进位的话if (carryValue){(*pAddResult)[resultLength] = '0' + carryValue;}}int main(void){//加法操作的两个操作数char *pOperOne = NULL;        char *pOperTwo = NULL;//加法的结果char *pAddResult = NULL;int resultLength = 0, lenOne = 0, lenTwo = 0;//获取两个操作数的输入puts("请输入第一个加数:");pOperOne = GetOperInput();puts("请输入第二个加数:");pOperTwo = GetOperInput();//申请到足够的结果空间resultLength = strlen(pOperOne) > strlen(pOperTwo) ? strlen(pOperOne) : strlen(pOperTwo);resultLength += 2;  //考虑到可能有进位pAddResult = malloc(resultLength);  memset(pAddResult, 0, resultLength);  //清空//计算结果(第二个参数传长度-1,是为了结果字符串以\0结尾)GetResult(&pAddResult, resultLength - 1, pOperOne, pOperTwo);//输出结果printf("%s + %s = ", pOperOne, pOperTwo);char *pResult = pAddResult;int i = 0;//如果没有进位的话,前面几位是空字符while(pAddResult[i] == '\0'){pResult++;i++;}puts(pResult);//收尾工作free(pOperOne);pOperOne = NULL;free(pOperTwo);pOperTwo = NULL;free(pAddResult);pAddResult = NULL;return 0;}


运行截图 :