循环赋值后数组x[0]莫名为0的C语言技术问题
问题分析:循环内数组元素正常,循环后x[0]变为0的原因
问题描述
通过for循环从long类型变量n的末尾开始逐位截取数字,交替存入两个数组x[]和y[]。循环内部打印x数组元素时结果符合预期,但循环结束后打印发现仅x[0]变为0,其余元素均正常。
问题代码
int x[8]; int y[8]; long n = 4003600000000014; int d = 0; printf("x before: "); for (long j = n; j > 0; j /= 10) { y[d] = n % 10; n /= 10; x[d] = n % 10; // debug to print x printf("%d, ", x[d]); n /= 10; d++; } //debug print printf("\n"); printf("x after: "); for(int fu = 0; fu < 8; fu++) { printf("%d, ", x[fu]); } printf("\n");
原因解析
核心问题是数组越界访问导致的未定义行为:
- 循环条件使用了初始n的副本
j,每次循环j /= 10,因此循环会执行16次(对应n的16位数字)。 - 但数组
x和y的长度仅为8(下标范围0-7),每次循环d自增1,当d >=8时,赋值x[d]和y[d]会超出数组的合法范围,破坏栈上的其他内存数据。 - 循环内部打印时,
x[d]是刚赋值的临时值,尚未被后续越界操作覆盖,因此显示正常;循环结束后,前期赋值的x[0]已被越界写入操作覆盖,最终变为0。
修复方案
修正后的代码
#include <stdio.h> int main() { int x[8]; int y[8]; long n = 4003600000000014; int d = 0; printf("x during: "); // 直接以n是否有效为循环条件,同时限制数组下标不越界 while (n > 0 && d < 8) { y[d] = n % 10; n /= 10; // 处理n为奇数位的情况,避免取无效的0值 if (n == 0) { x[d] = 0; break; } x[d] = n % 10; printf("%d, ", x[d]); n /= 10; d++; } printf("\n"); printf("x after: "); // 仅打印已赋值的元素,避免输出未初始化的垃圾值 for(int fu = 0; fu < d; fu++) { printf("%d, ", x[fu]); } printf("\n"); return 0; }
关键修复点
- 调整循环条件:直接判断
n > 0,同时增加d < 8限制,彻底避免数组越界。 - 增加奇数位判断:当n处理到最后一位时,避免给
x[d]赋值无效的0值。 - 优化数组打印:仅遍历已赋值的元素(到下标
d),避免输出未初始化的随机值。
内容的提问来源于stack exchange,提问作者NacerShucks
相关产品推荐
相关产品推荐

