-1

我已经声明了一个包含 10 个指向字符的指针的数组。在 10 个中,我只初始化了 3 个。当我使用%s以下命令打印数组时\n,它给出的输出如下:

hi
hello
how 
segmentation fault

但如果我不使用\n,那么它会给出如下输出:

hihellohow(null)...(7 times).

有人可以解释一下吗?


代码 1

#include <stdio.h>

void main()
{
    char *a[10] = {"hi", "hello", "how"};
    int i = 0, j = 0;

    a[0] = "hey";
    for (i = 0;i < 10; i++)
        printf("%s\n", a[i]);
}

代码 2

#include <stdio.h>

void main()
{
    char *a[10] = {"hi", "hello", "how"};
    int i = 0, j = 0;

    a[0] = "hey";
    for (i = 0;i < 10; i++)
        printf("%s", a[i]);
}
4

3 回答 3

5

正如您自己所说,您不会将数组元素初始化为第三个元素,因此它们会自动初始化为空指针。尝试打印这些空指针是未定义的行为,因此任何事情都可能发生(包括第一个示例中的段错误,或者看起来像第二个示例中那样工作)。

在这两种情况下,您的代码都是错误的,尝试解释为什么会发生随机事件(同样,段错误或看起来有效)是毫无意义的。

于 2013-10-18T12:33:47.440 回答
4

实际上,它可能来自您的编译器。如果您使用 GCC,此页面说明printf("%s\n", s)已优化为puts(s). 该页面显示了 2004 年的错误报告,但我可以在 Windows 下使用 GCC-4.7.2 重现该错误。虽然printf有防范空指针,puts但似乎没有,因此不同的行为取决于换行符。

但是,正如 syam 所说,将空指针作为字符串提供是不标准的,并且可能导致任何事情发生。这里只是 GCC 是友好的,打印(null)而不是简单的崩溃。

于 2013-10-18T12:36:56.563 回答
3

这两种情况都不正确,它们试图打印空指针的内容,这没有任何意义。您正在调用任何可能发生的未定义行为。

C 标准保证该行char *a[10] = {"hi", "hello", "how"};以下列方式初始化:

a[0] -> "hi"
a[1] -> "hello"
a[2] -> "how"
a[3] -> NULL
...
a[9] -> NULL
于 2013-10-18T12:37:24.177 回答