为什么指针char数组最后不会自动获得NULL?

时间:2014-11-14 11:12:21

标签: c

在下面的代码中我打印一个指针数组。我正在终止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 };

为什么我们这样做?

5 个答案:

答案 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显式结束数组。