char arr1 [0];
arr1[50] = 'A';
char arr2 [0] = {1, 1, 1, 1, 1}; //gives compiler warning
为什么上面可以正常编译?
为什么只有第二个给我一个警告?
第一个编译正常,因为编译器通常不会意识到a[50] = 0
试图在数组分配的内存之外分配一个值。运行时的行为是未定义的:它可能会崩溃、终止程序、格式化你的硬盘,或者根本不做任何事情。
第二个给出警告,因为右侧的数组初始值设定项与左侧的数组声明不匹配。这就像写作一样int x = "a string"
。
这两个声明都应该给你一个编译时错误,因为声明一个长度数组0
是一种“违反约束”的错误,如果它符合 C 标准,任何编译器都必须捕获这种错误。
char arr2 [0] = {1, 1, 1, 1, 1};
有一个额外的约束违规,即初始化器比数组中的元素多。您的编译器似乎只捕获了那个。
与此相反
arr1[50] = 'A';
只是标准未定义的运行时行为,编译器可以随心所欲地做任何事情。一个好的编译器也可以很容易地检测到那个。
总之,您或许应该考虑让自己成为一个更好、更新的编译器。
“char arr2 [0] = {1, 1, 1, 1, 1};” 会给您一个错误,因为您将 arr2 声明为一个零元素数组并用 5 个元素对其进行初始化。编译器很可能会抱怨/警告您数组初始值设定项中有多余的元素。您可以执行“char arr2[] = {1, 1, 1, 1, 1};” 并且 C 会隐式计算存储或者您可以显式指定元素的数量:“char arr2[5] = {1, 1, 1, 1, 1};”
此外,“arr1[50] = 'A';” 当您将 arr1 定义为大小为零的数组时,这是一个坏主意:“char arr1 [0];”。只需声明它,以便它可以有足够的元素来包含您在索引 50 处添加的值。