模拟人类计算方式的C语言两数相加代码:长度相等时出错求助
模拟人类计算的大数相加代码(等长数字出错修复)
出于兴趣,我尝试编写一段模拟人类计算方式的C语言两数相加代码,但当两个数字长度相等时代码会出错。目前存在其他大数相加方法,比如反转数字、位运算或使用long类型,但这些都不是我想要的实现方式。
原代码
#include <stdio.h> #include <stdlib.h> int main() { int *ptr, *ptr2, *ptr3; int size, size2, size3, carry = 0; printf("Enter size of 1st element: "); scanf("%d", &size); ptr = (int *)calloc(size, sizeof(int)); if (ptr == NULL) printf("Memory not allocated.\n"); else { for (int j = 0; j < size; ++j) { scanf("%d", &ptr[j]); } } printf("\nEnter size of 2nd element: "); scanf("%d", &size2); ptr2 = (int *)calloc(size2, sizeof(int)); if (ptr2 == NULL) printf("Memory not allocated.\n"); else { for (int j = 0; j < size2; ++j) { scanf("%d", &ptr2[j]); } } printf("\n"); // Addition starts here if (size > size2) size3 = size + 1; else size3 = size2 + 1; ptr3 = (int *)calloc(size3, sizeof(int)); for (int j = 0; j < size3; ++j) { ptr3[j]=0; } if (size > size2) { //1st number higher digits for (int k = 1; k <= size2; ++k) { ptr3[k - 1] = (carry + ptr[size - k] + ptr2[size2 - k]); carry = ptr3[k - 1] / 10; ptr3[k - 1] = ptr3[k - 1] % 10; } for (int k = size2 + 1; k <= size; ++k) { if (k == size2) ptr3[k - 1] = ptr[size - k] + carry; else ptr3[k - 1] = ptr[size - k]; } } else if (size2 > size) { //2nd number higher digits for (int k = 1; k <= size; ++k) { ptr3[k - 1] = (carry + ptr2[size2 - k] + ptr[size - k]); carry = ptr3[k - 1] / 10; ptr3[k - 1] = ptr3[k - 1] % 10; } for (int k = size + 1; k <= size2; ++k) { if (k == size) ptr3[k - 1] = ptr2[size2 - k] + carry; else ptr3[k - 1] = ptr2[size2 - k]; } } else { //equal digits for (int k = size; k > -1; --k) { ptr3[k] = (carry + ptr2[k] + ptr[k]); printf("%d + %d = %d\n", ptr2[k], ptr[k], ptr3[k]); carry = ptr3[k] / 10; ptr3[k] = ptr3[k] % 10; } } // DISPLAY for (int j = 0; j < size; ++j) { printf("%d", ptr[j]); } printf("+"); for (int j = 0; j < size2; ++j) { printf("%d", ptr2[j]); } printf(" = "); for (int j = size3; j > -1; --j) { if (ptr3[j] >= 0) printf("%d", ptr3[j]); } return 0; }
错误分析
- 数组越界访问:等长数字处理时,循环
for (int k = size; k > -1; --k)会访问ptr[size]和ptr2[size],但数组下标范围仅为0到size-1,引发未定义行为。 - 进位处理遗漏:不等长数字的剩余高位逻辑中,
k == size2/k == size的判断永远不成立,导致进位未被正确叠加;等长处理结束后,剩余进位也未存入结果数组的最高位。 - 结果输出越界:输出结果时循环
for (int j = size3; j > -1; --j)会访问ptr3[size3],但ptr3的下标范围是0到size3-1,存在越界问题。
修复后的代码
#include <stdio.h> #include <stdlib.h> int main() { int *ptr, *ptr2, *ptr3; int size, size2, size3, carry = 0; printf("Enter size of 1st element: "); scanf("%d", &size); ptr = (int *)calloc(size, sizeof(int)); if (ptr == NULL) { printf("Memory not allocated.\n"); return 1; } for (int j = 0; j < size; ++j) { scanf("%d", &ptr[j]); } printf("\nEnter size of 2nd element: "); scanf("%d", &size2); ptr2 = (int *)calloc(size2, sizeof(int)); if (ptr2 == NULL) { printf("Memory not allocated.\n"); free(ptr); return 1; } for (int j = 0; j < size2; ++j) { scanf("%d", &ptr2[j]); } printf("\n"); // 初始化结果数组 size3 = (size > size2 ? size : size2) + 1; ptr3 = (int *)calloc(size3, sizeof(int)); if (ptr3 == NULL) { printf("Memory not allocated.\n"); free(ptr); free(ptr2); return 1; } if (size > size2) { // 第一个数位数更多 // 相加共同长度的部分 for (int k = 1; k <= size2; ++k) { int sum = carry + ptr[size - k] + ptr2[size2 - k]; ptr3[k - 1] = sum % 10; carry = sum / 10; } // 处理第一个数剩余的高位 for (int k = size2 + 1; k <= size; ++k) { int sum = carry + ptr[size - k]; ptr3[k - 1] = sum % 10; carry = sum / 10; } // 最后处理剩余进位 if (carry != 0) { ptr3[size] = carry; } } else if (size2 > size) { // 第二个数位数更多 // 相加共同长度的部分 for (int k = 1; k <= size; ++k) { int sum = carry + ptr2[size2 - k] + ptr[size - k]; ptr3[k - 1] = sum % 10; carry = sum / 10; } // 处理第二个数剩余的高位 for (int k = size + 1; k <= size2; ++k) { int sum = carry + ptr2[size2 - k]; ptr3[k - 1] = sum % 10; carry = sum / 10; } // 处理剩余进位 if (carry != 0) { ptr3[size2] = carry; } } else { // 两个数位数相等 // 从个位(数组最后一位)开始相加 for (int k = size - 1; k >= 0; --k) { int sum = carry + ptr[k] + ptr2[k]; ptr3[k] = sum % 10; carry = sum / 10; } // 处理最后的进位 if (carry != 0) { ptr3[size] = carry; } } // 输出结果 for (int j = 0; j < size; ++j) { printf("%d", ptr[j]); } printf("+"); for (int j = 0; j < size2; ++j) { printf("%d", ptr2[j]); } printf(" = "); // 跳过前导零(如果最高位是0且结果长度大于1) int start = size3 - 1; while (start > 0 && ptr3[start] == 0) { start--; } // 从最高位开始输出 for (int j = start; j >= 0; --j) { printf("%d", ptr3[j]); } printf("\n"); // 释放内存,避免泄漏 free(ptr); free(ptr2); free(ptr3); return 0; }
修复说明
- 修正了数组越界问题:等长处理时从
size-1开始循环,输出结果时从size3-1开始遍历。 - 完善进位逻辑:处理所有位后将剩余进位存入结果最高位,不等长剩余高位计算时每次叠加进位。
- 优化内存管理:增加内存释放步骤,分配失败时及时清理已分配内存并退出。
- 优化结果输出:自动跳过前导零,输出格式更符合常规数字显示习惯。
内容的提问来源于stack exchange,提问作者Sourav
相关产品推荐
相关产品推荐

