【发布时间】:2020-09-20 14:03:51
【问题描述】:
通常,这个问题可能会以积极的方式表达,成为重复问题俱乐部中的下一个成员 - 希望这个不是。我写了一个简单的程序来反转 C 中的字符串。这里是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char arr[4] = "TEST";
char rev[2];
int j = 0;
for(int i = 0; i < 4; i++) {
j = 4 - i - 1;
rev[j] = arr[i];
}
printf("%s\n",rev);
}
当我将 char arr 和 char rev 定义为 4 时,一切正常。当我离开arr 尺寸时,我得到了意想不到的重复输出,如“TSTTST”。当我将 rev 定义为 2 个字符的数组时,我没有收到段错误,但在循环中我试图访问它的第三个和第四个元素。据我相对有限的理解告诉我,访问长度为 2 的数组中的第三个元素应该是段错误,对吧?那为什么不呢?
编辑:
有趣的是,当我像这样离开循环时
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char arr[4] = "TEST";
char rev[2] = "00";
printf("%s\n",rev);
}
它打印“00TEST”。这里发生了什么?某种溢出?我什至重新启动了终端,重新编译并再次运行。
编辑 2:
我已经知道这确实是重复的。但是,大多数建议的重复项都提到了 C++,而事实并非如此。我认为对于新的 C 程序员来说,这是一个学习和理解未定义行为的好问题。一方面,我不知道越界访问数组不总是会导致 SEGFAULT。 另外,我了解到我必须自己终止字符串文字,我错误地认为这是自动完成的。这部分是错误的:它是自动添加的 - C99 标准 (TC3) 在 6.4 中说.5 在翻译阶段 7 添加终止空值的字符串文字。根据this answer 和此问题的答案,char 数组也是空值终止的,但这只有在数组具有正确长度时才是安全的(字符串长度 + 1 为空终止符)。
【问题讨论】:
-
%s将打印到\0。你缺少的 -
关于您的编辑:
printf格式说明符%s需要一个以 null 结尾的字符串。您的“字符串”不是以空值结尾的,因此您还有另一种未定义行为的变体。
标签: c