一些字符数组不以 '\0' 结尾

Some char arrays don't end with '\0'

我在 C 中有一个简单的代码来查看三个相同的 char 数组是否都以 '[=11=]':

结尾
int main(){
    char a[4] = "1234";
    char b[4] = "1234";
    char c[4] = "1234";


    if(a[4] == '[=10=]')
            printf("a end with '\0'\n");
    if(b[4] == '[=10=]')
            printf("b end with '\0'\n");
    if(c[4] == '[=10=]')
            printf("c end with '\0'\n");

    return 0;
}

但是输出显示只有数组b以终止符'[=11=]'结束。这是为什么?我认为所有字符数组都必须以 '[=11=]'.

结尾

输出:

b end with '[=14=]'

主要问题是,对于定义为 char a[4] = ....(大小为 4 个元素)的数组,使用 if (a[4] ....) 已经差一并导致 undefined behavior

您要检查 a[3],因为它是最后一个 有效 元素。

就是说,在您的情况下,您没有空终止符的空间!!

强调引用自 C11,§6.7.9,

An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

因此,您需要

  • 使用为空终止符留出空间的数组大小
  • 或者,使用未知大小的数组,例如 char a[ ] = "1234";,其中,数组大小由提供的初始值设定项(包括空终止符)的长度自动确定。

这是未定义的行为,因为您试图越界访问数组。

不要指定用 字符串字面量 初始化的字符串的边界,因为编译器会自动为整个字符串字面量分配足够的 space,包括终止空字符.

C 标准(c11 - 6.7.9:第 14 段)说:

An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

所以,在数组初始化时没有指定字符数组的边界。

char a[] = "1234";

数组末尾还需要一个地方来存放[=10=]。声明长度为 5 的数组。

如果数组有 n 个元素,您可以访问数组的第 n 个元素。这里数组的大小是 4 字节,当你做类似 if(a[4] == '[=17= ]').

在不指定数组大小的情况下执行上面的代码,那么3条if语句都会被执行,这里因为我们已经指定了数组大小,我们知道string数组对于NULL会多占用1个char终止,但在这里我们没有给数组以这种方式表现的机会,因此编译器表现随机。