为何添加打印语句会改变C++函数的返回值?
问题根源:未初始化数组元素导致的未定义行为
你的代码核心问题是访问了数组中未初始化的元素,总和混入了栈内存的垃圾值;而添加cout后返回正确只是巧合,属于C++里的「未定义行为」——栈上的随机值刚好被覆盖成0了,不是真正解决了问题。
一步步拆解错误:
以输入125为例:
- 第一个循环计算数组大小:
i从1开始乘10,直到i >= x,最终i=1000,inc=4(循环执行3次,初始inc=1,每次加1)。你创建了大小为4的数组digs,但125只有3位数字。 - 第二个循环填充数组:
循环执行3次,给digs[0](1)、digs[1](2)、digs[2](5)赋值,digs[3]完全未被初始化,是栈上的垃圾值。 - 第三个循环求和:
你用size=4作为循环上限,把digs[3]的垃圾值也加进了总和。32766就是这个垃圾值(比如栈上残留的0x7FFE),加上前面的8,结果就是32766。
为什么加cout后会「正常」?
添加cout << "hello world";会改变函数调用时的栈布局,刚好把digs[3]的位置覆盖成了0,总和就变成了8。但这是完全随机的——换个编译器、操作系统,或者输入其他数字,结果依然会错,这就是C++里的未定义行为,绝对不能依赖这种巧合。
修正方案
方案1:修复原代码的数组遍历逻辑
记录实际填充的元素个数,替代错误的size:
int sumOfDigits(int x) { int i = 1; int inc = 1; while(i < x){ i *= 10; inc += 1; } int digs[inc]; int count = 0; // 记录实际填充的元素数 int z = x; i /= 10; while(z > 0) { digs[count] = (z/i); z -= i * digs[count]; i /= 10; count += 1; } int sum = 0; for (int j = 0; j < count; j += 1) { // 用count代替size sum += digs[j]; } return sum; }
方案2:换更简单的实现(推荐)
根本不需要数组,直接用取模和除法求各位和,逻辑清晰且无错误:
int sumOfDigits(int x) { int sum = 0; while (x > 0) { sum += x % 10; // 取最后一位数字 x /= 10; // 去掉最后一位 } return sum; }
内容的提问来源于stack exchange,提问作者vulcan_ocelot
相关产品推荐
相关产品推荐

