在下面的代码中我打印一个指针数组。我正在终止while循环,但它得到NULL
但这并没有终止。为什么没有获得NULL
?
#include <stdio.h>
int main()
{
int i = 0;
char *a[] = { "This is", "a story", "of a person" };
while (a[i] != NULL) {
printf("%s ", a[i]);
i++;
}
return 0;
}
这是我的GDB调试会话:
30 while (a[i] != NULL) {
(gdb) p a[0]
$1 = 0x8048510 "This is"
(gdb) p a[1]
$2 = 0x804851b "a story"
(gdb) p a[2]
$3 = 0x8048523 "of a person"
(gdb) p a[3]
$4 = 0x8048480 <__libc_csu_init> "UW1\377VS\350\305\376\377\377\201\303u\033"
a[3]
为什么不是NULL
。获得NULL
为什么我必须在数组末尾声明一个显式0,如下所示:
char *a[] = { "This is", "a story", "of a person", NULL };
为什么我们这样做?
答案 0 :(得分:2)
除了由零字节隐式终止的字符串文字外,所有内容都应该在C中显式化。因此代码具有明确的终止NULL
指针,如:
char *a[] = {"This is","a story","of a person", NULL};
顺便说一下,您可能需要const char*a[]
而不是char*a[]
(例如,因为您希望a
位于.rodata
只读数据段中,如果这对您有意义实现)。
答案 1 :(得分:1)
a
的大小为3,因此访问a[3]
会调用未定义的行为。任何东西都可以存储在那个单元格中,当然c不能保证它是NULL
。
答案 2 :(得分:1)
为什么它应该有NULL?
您可能会对"quoted strings"
零终止这一事实感到困惑。也就是说,您的每个字符串"This is"
,"a story"
等在结尾处都有一个ASCII NUL字符'\0'
,但不是字符串数组(指向字符的指针)你定义的元素。
此外,最好让数组包含const char *
,而不仅仅是char *
。
答案 3 :(得分:1)
a
的长度为3
,因为您为初始化提供了三个元素。访问a[3]
将是非法的。
您可以在初始化结束时添加空指针。或者,另一种可能的解决方案是明确地给它4
长度:
char *a[4] = {"This is","a story","of a person"};
这样,a[3]
被初始化为空指针。
答案 4 :(得分:1)
结束char *的空字符是&#39; \ 0&#39;,对于char * []
不是true 在您的情况下,[3]将包含来自RAM中实际内存地址的垃圾。如果您不确定数组的大小,则应该使用null显式结束数组。