向数组插入元素时空字符异常:为何未报错却输出olleh
为什么这段代码覆盖空字符后仍能输出"olleh"?
代码执行逻辑拆解
数组初始化细节
char s1[5] = {'\0'}:数组大小为5,初始化列表仅指定第一个元素为'\0',C语言会自动将剩余4个元素初始化为'\0',所以初始状态下s1是[ '\0', '\0', '\0', '\0', '\0' ]。char s2[] = "hello":字符串实际长度为5(strlen(s2)返回5),数组总大小为6(包含末尾默认添加的'\0'),内容为[ 'h','e','l','l','o','\0' ]。
递归函数执行流程
初始调用f(s1, s2, 0, 4)(strlen(s2)-1=4),递归步骤如下:- i=0, j=4:
s1[0] = 'o'→ 调用f(1,3) - i=1, j=3:
s1[1] = 'l'→ 调用f(2,2) - i=2, j=2:
s1[2] = 'l'→ 调用f(3,1) - i=3, j=1:
s1[3] = 'e'→ 调用f(4,0) - i=4, j=0:
s1[4] = 'h'→ 调用f(5,-1)
当i=5、j=-1时,不满足i>=0 && j>=0的条件,递归终止。此时s1的内容是[ 'o','l','l','e','h' ],没有字符串终止符'\0'。
- i=0, j=4:
关于“覆盖空字符未触发错误”的解释
- 覆盖数组中的
'\0'本身是合法操作,C语言允许修改数组元素的值,不会直接触发错误。 - 你预期的“错误”本质是字符串未以
'\0'结尾时,使用printf("%s")输出的未定义行为。这次能正确输出"olleh"只是巧合——在你的运行环境中,s1数组后面的内存恰好存在一个'\0',让printf停止输出。换一个环境,可能会输出乱码甚至导致程序崩溃。
合法修正建议
要让代码行为可预测,应将s1的大小设为6,在递归结束后手动添加终止符:
int main() { char s1[6] = {'\0'}, s2[] = "hello"; f(s1, s2, 0, (int)strlen(s2) - 1); s1[5] = '\0'; // 确保字符串终止 printf(" %s\n", s1); return 0; }
内容的提问来源于stack exchange,提问作者Tommaso Ansaloni
相关产品推荐
相关产品推荐

