#include <stdio.h>
#include <string.h>
void f(char s1[], const char s2[], int i, int j) {
if (i >= 0 && j >= 0) {
s1[i] = s2[j];
f(s1, s2, i + 1, j - 1);
}
}
int main() {
char s1[5] = {'\0'}, s2[] = "hello";
f(s1, s2, 0, (int)strlen(s2) - 1);
printf(" %s \n", s1);
return 0;
}
你好, 这段代码的打印结果是 olleh,但我预计代码会给出错误,因为在 for 循环期间空字符被覆盖,为什么会发生这种情况?
…我预计代码会出错…
这种期望是不正确的。当
printf
被传递时,对于 %s
转换,一个不包含空字符的数组,则该行为不是由 C 标准定义的。
没有任何内容表明计算机会出错。 C 标准中没有关于行为的规范。
通常会发生的情况是,
printf
将继续检查数组末尾之外的内存并打印找到的内容,直到找到零字节为止。 s1
数组后面可能有一个零字节,因此 printf
立即停止。然而,其他行为也是可能的。 printf
可能打印了您没有看到的其他字符,因为它们没有可见的效果,例如空格或制表符或某些控制字符。在其他情况下,数组之外可能还有其他字符,并且 printf
可能会打印这些字符。或者,在优化过程中,编译器可能会以产生其他效果的方式转换您的程序。
如果您尝试使用
%s
打印,并且传递的不是以 null 结尾的字符串,它将调用未定义的行为。
但是在您的情况下,
char s1[5] = {'\0'}
用零填充所有数组,因此如果strlen(s2) < sizeof(s1)
(s
和s2
函数范围中的main
)此代码将正常工作。
如果
sizeof(s2) >= sizeof(s1)
它将调用未定义的行为:
strlen(s2) > sizeof(s1)
strlen(s2) >= sizeof(s1)
这段代码的打印结果是 olleh,但我希望代码给出一个 错误,因为在 for 循环期间空字符被覆盖,为什么 会发生这种事吗?
覆盖第一个字符并不重要,因为如果按照初始化方式初始化数组,则数组将被清零。问题是您没有空间容纳空终止字符。它调用 UB。 UB 不必以任何特定方式表达自己。该代码可能工作正常、出现段错误、转移您所有的钱或其他东西。