C语言存储二进制位的两数组求和结果错误问题排查
C语言模拟二进制加法代码错误分析及修复
核心问题列表
- 数组越界:
num2定义长度为8,但输入循环遍历9次(i从0到8),访问num2[8]属于越界操作,会导致内存数据异常。 - 输入长度丢失:两个数组的输入循环共用变量
i,第一个数组的输入长度被第二个数组的输入长度覆盖,求和时无法正确匹配两个数组的有效位长度。 - 加法逻辑错误:
- 进位处理不全:当
num1[i2] + num2[i2] + carry = 3(即两位都是1且有进位)时,仅设置当前位为1,未保留新的进位,导致进位丢失。 - 未处理和为2的场景:else分支直接将求和结果赋值给当前位、清空进位,若
carry + num1[i2] + num2[i2] = 2时,会直接存储2到结果位,不符合二进制规则,且未生成新的进位。
- 进位处理不全:当
- 剩余进位未处理:求和循环结束后,如果还有未处理的进位,没有存入结果数组,导致最高位丢失。
- 数组未初始化:
result数组未做初始化,未赋值的位置是内存随机值,输出会出现异常数据。 - 加法顺序不符合手工计算规则:二进制加法需要从最低位开始计算,原代码未对齐最低位,长度不一致时计算完全错误。
修复方案
- 修正数组定义:将
num2的长度改为9,和num1匹配,避免输入越界。 - 分别存储两个数组的输入长度:新增
len1、len2变量分别保存两个数组输入结束后的有效长度。 - 重写加法逻辑:按二进制加法规则,逐位计算
sum = 位1 + 位2 + 进位,当前位值为sum % 2,新的进位为sum / 2,自动覆盖所有场景无需多分支判断。 - 对齐最低位计算:从两个数组的最后一个有效元素(最低位)开始求和,超出有效长度的位按0处理,取两个数组的最大长度作为求和循环次数。
- 处理最终进位:求和结束后如果进位为1,将其存入结果数组的最高位。
- 初始化所有数组:定义数组时初始化为全0,避免随机值干扰。
- 调整输出顺序:按用户预期的高位在前格式输出结果,符合常规阅读习惯。
修复后完整代码
#include <stdio.h> int main(void) { int num1[9] = {0}, num2[9] = {0}, result[12] = {0}; int carry = 0, i, len1, len2, max_len; // 输入num1 for (i = 0; i < 9; i++) { printf("Type 0 or 1 to save in position %d of num1\n", i + 1); scanf("%d", &num1[i]); if (num1[i] > 1 || num1[i] < 0) { num1[i] = 0; printf("Exiting loop...\n"); break; } } len1 = i; // 保存num1有效长度 // 输入num2 for (i = 0; i < 9; i++) { printf("Type 0 or 1 to save in position %d of num2\n", i + 1); scanf("%d", &num2[i]); if (num2[i] > 1 || num2[i] < 0) { num2[i] = 0; printf("Exiting loop...\n"); break; } } len2 = i; // 保存num2有效长度 max_len = len1 > len2 ? len1 : len2; // 从最低位(数组最后一个有效元素)开始求和 for (i = 0; i < max_len; i++) { int a = (i < len1) ? num1[len1 - 1 - i] : 0; int b = (i < len2) ? num2[len2 - 1 - i] : 0; int sum = a + b + carry; result[i] = sum % 2; carry = sum / 2; } // 处理剩余进位 if (carry) { result[max_len] = 1; max_len++; } // 从最高位到最低位输出结果,和预期高位在前格式一致 printf("计算结果:"); for (i = max_len - 1; i >= 0; i--) { printf("%d", result[i]); if (i != 0) printf(","); } printf("\n"); return 0; }
内容的提问来源于stack exchange,提问作者Matheus_Felipe_c
相关产品推荐
相关产品推荐

