如果错误的话,我定义了一个没有'\ 0'作为最后一个字符的char数组,那么会发生什么?我问这个是因为我注意到如果我尝试迭代数组而(cnt!='\ 0'),其中cnt是一个int变量,用作数组的索引,同时打印cnt值来监视迭代停止在最后一个字符+ 2处发生了什么.额外的字符当然是随机的但我无法理解为什么它必须在2之后停止.编译器是否会自动插入'\ 0'字符?相关文档的链接不胜感激.
为了说清楚,我给出了一个例子.让我们说数组"str"包含单词doh(没有'\ 0').在每个循环中打印cnt变量会给我这个doh +或doh ^等等.
编辑(未定义的行为)
访问数组边界之外的数组元素是未定义的行为.
使用除C字符串之外的任何内容调用字符串函数是未定义的行为.
不要这样做!
AC字符串是由封端的字节序列,并且包括一个'\0'(NUL终止子).所有字节必须属于同一个对象.
无论如何,你看到的是巧合!
但它可能会发生这样的事情
,------------------ garbage
| ,---------------- str[cnt] (when cnt == 4, no bounds-checking)
memory ----> [...|d|o|h|*|0|0|0|4|...]
| | \_____/ -------- cnt (big-endian, properly 4-byte aligned)
\___/ ------------------ str
如果您定义一个没有终止符的 char 数组\0(称为“空终止符”),那么您的字符串将不会有该终止符。你会这样做:
char strings[] = {'h', 'e', 'l', 'l', 'o'};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,编译器永远不会自动插入空终止符。您的代码在“+2”之后停止的事实是一个巧合;它可以很容易地停止在 +50 或其他任何地方,具体取决于字符串后面的内存中是否恰好有 \0 字符。
如果将字符串定义为:
char strings[] = "hello";
Run Code Online (Sandbox Code Playgroud)
那么这确实会以空终止。当您在 C 中使用引号时,即使您在文本编辑器中看不到它,字符串末尾也会有一个空终止符。
有一些与 C 字符串相关的函数会自动附加空终止符。这不是编译器所做的事情,而是函数规范本身的一部分。例如,strncat()将一个字符串连接到另一个字符串,会在末尾添加空终止符。
但是,如果您使用的字符串之一尚不具有该终止符,则该函数将不知道该字符串在哪里结束,并且您最终会得到垃圾值(或分段错误)。
在 C 语言中,术语“字符串”是指以零结尾的字符数组。因此,迂腐地说,不存在“没有 '\0' 字符的字符串”这样的东西。如果它不是以零结尾,则它不是字符串。
现在,只要您了解它不是字符串,仅包含不带任何零的字符数组就没有问题。如果您尝试像使用字符串一样使用此类字符数组,则程序的行为是未定义的。任何事情都可能发生。由于某些神奇的原因,它可能看起来“有效”。或者它可能会一直崩溃。这样的程序实际上会做什么并不重要,因为如果行为未定义,则程序就没用。