C语言校验和错误验证程序触发无限循环,寻求问题原因及解决方法
你的C语言校验和程序无限循环问题分析与修复
嘿,咱们来一步步拆解你的程序问题,先搞定无限循环,再处理那些会导致奇怪行为的数组越界问题:
一、无限循环的直接元凶:goto s时错误重置了索引i
看你代码里的s标签段:
s: for (k = 0; k < 2; k++) { for (j = 7; j >= 0; j--) { de[k][i] = dec[k][j]; i++; } i = 0; // 这里就是罪魁祸首! }
你第一次执行加法逻辑后,会执行i = i + 2,此时i变成2(初始是0),因为2 < 5(n=5),会跳回s标签。但一进入s,代码立刻把i重置为0了——这就导致i永远没法增长到超过n,循环永远停不下来!
二、隐藏的数组越界问题(会导致未定义行为)
除了无限循环,你的代码还有两个严重的数组越界问题,不仅会破坏数据,还可能间接影响程序逻辑:
de数组定义为int de[2][8],只有2行,但后面你尝试访问de[i][j]当i=2、3的时候,已经超出了数组的合法下标范围(数组下标从0开始,合法行是0和1)。- 加法循环
for (j = 7; j >= 0; j--)结束后,j的值是-1,这时你执行de[i][j] = add[j]和de[i + 1][j] = u[j],用-1当下标完全非法,会触发未定义行为。
三、具体修复方案
1. 先解决无限循环
把s标签里的i = 0;删掉,并且重新设计索引的递增逻辑,确保每次跳回s时,索引是当前需要处理的位置,不会被重置。比如可以用一个单独的变量(比如current_idx)来跟踪当前处理的行索引,避免和其他逻辑的i混淆。
2. 修复数组越界
- 把
de数组的大小调整为int de[5][8](因为n=5,最多需要5行数据),确保能容纳所有计算结果。 - 加法循环结束后,不要直接用
j的值(此时j=-1),重新用循环遍历0-7的下标来赋值add数组到de中。
3. 简化加法逻辑(可选但推荐)
你写了一堆if-else来处理加法进位,可以用更简洁的方式替代,减少代码冗余和出错概率:
int sum = de[current_idx][j] + de[current_idx+1][j] + carry; add[j] = sum % 2; carry = sum / 2;
调整后的核心代码片段
// 调整de数组大小为5行,适配n=5的需求 int a[2], i, dec[10][8], de[5][8], j, k, add[8], carry = 0, n = 5; int u[] = {0, 0, 0, 0, 0, 0, 0, 1}; char b[] = {'H', 'e', 'l', 'l', 'o'}; int main() { // 初始化dec数组 for (k = 0; k < 2; k++) { for (j = 0; j < 8; j++) { dec[k][j] = 0; } } // 转换字符为ASCII值 for (k = 0; k < 2; k++) { a[k] = b[k]; } // ASCII转二进制 for (k = 0; k < 2; k++) { i = 0; while (a[k] > 0) { dec[k][i] = a[k] % 2; a[k] = a[k] / 2; i++; } } int current_idx = 0; s: // 把dec的数据赋值到de的当前行范围 for (k = 0; k < 2; k++) { for (j = 7; j >= 0; j--) { de[current_idx + k][j] = dec[k][j]; } } // 打印当前de的内容 for (k = current_idx; k < current_idx + 2; k++) { for (j = 0; j < 8; j++) { printf("%d", de[k][j]); } printf("\n"); } // 计算两行的校验和 carry = 0; for (j = 7; j >= 0; j--) { int sum = de[current_idx][j] + de[current_idx+1][j] + carry; add[j] = sum % 2; carry = sum / 2; } current_idx += 2; if (current_idx < n) { // 将计算得到的add数组赋值给de的下一行 for (j = 0; j < 8; j++) { de[current_idx][j] = add[j]; } // 如果有进位,需要添加进位行 if (carry == 1) { for (j = 0; j < 8; j++) { de[current_idx+1][j] = u[j]; } current_idx += 1; // 因为多了一行进位数据,索引要加1 } goto s; } // 打印最终的校验和 for (j = 0; j < 8; j++) { printf("%d", add[j]); } printf("\n"); return 0; }
这样调整后,current_idx会逐步递增,不会被重置,程序就能正常退出循环了,同时也解决了数组越界的问题。
内容的提问来源于stack exchange,提问作者Parth Bissa
相关产品推荐
相关产品推荐

