You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言循环中字符数组元素值异常变更原因咨询

字符形式整数相加时数组越界导致的问题解析

问题背景

我在完成C语言作业时需要实现字符形式的整数相加(比如"123"和"321"相加得到"444"),思路是通过计算字符与'0'的ASCII差值转成数值后运算。但写代码时用char total[] = { 0 };定义数组,循环里发现total[1]的值从'4'莫名变成\x01,改成char total[4] = { 0 };后问题就解决了,想知道原写法失效的原因。

相关代码

#include <stdio.h>

int main (int argc, char *argv[]) {
        char *num1 = "123";
        char *num2 = "321";
        const char Z = 48; //value of zero 
        char from_z = 0;
        char total[] = { 0 };
        int i = 0;
        
        //main for loop
        for (i = 0; num1[i] != '\0' || num2[i] != '\0'; i++) {
                from_z = num2[i] - Z; //distance from '0'
                total[i] = num1[i] + from_z;

                //print out contents of current index and previous
                //to compare
                printf("i total[%d]: %c\n", i, total[i]);
                printf("i - 1: total[%d]: %c\n", i-1, total[i-1]);
        } 
        printf("i: %d\n", i);
        total[i] = '\0';
        
        return 0;
}

运行输出

i total[0]: 4
i - 1: total[-1]:
i total[1]: 4
i - 1: total[0]: 4
i total[2]: 4
i - 1: total[1]:
i: 3

问题根源:数组越界与未定义行为

  • 当你用char total[] = { 0 };定义数组时,编译器会根据初始化列表的元素数量确定数组大小——这里只初始化了一个元素,所以total是长度为1的char数组,仅能合法访问total[0]。
  • 你的循环会执行3次(i从0到2),循环结束后还会执行total[3] = '\0',这意味着你连续访问了total[1]、total[2]、total[3],这些都是数组边界外的内存区域。
  • C语言不会自动检查数组越界,访问超出数组范围的内存属于未定义行为:这部分内存可能是其他变量的存储空间,也可能是栈上的其他数据,写入操作会破坏这些未知内容,导致之前写入的total[1]被意外覆盖(比如被循环变量i的更新、printf的栈操作等改写),就出现了你看到的total[1]值莫名变化的情况。
  • 改成char total[4] = { 0 };后,数组长度足够容纳3位结果字符加上末尾的终止符'\0',所有访问都在合法范围内,未定义行为消失,问题自然解决。

补充说明

代码里还有个潜在问题:当循环到i=3时,num1[i]和num2[i]都是字符串终止符'\0',此时num2[i] - Z会计算成'\0' - 48(即-48),虽然这里循环结束后直接给total[3]赋值'\0'覆盖了,但如果是更长的字符串或者逻辑变化,可能会引发其他问题,建议在循环里判断字符是否为'\0',如果是就按0处理。

内容的提问来源于stack exchange,提问作者AsianDora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 13:38:30