我已经声明了一个包含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]);
}
答案 0 :(得分:5)
正如您自己所说,您不会将数组元素初始化超过第三个,因此它们会自动初始化为空指针。尝试打印这些空指针是未定义的行为,因此任何都可能发生(包括第一个示例中的段错误,或者出现,就像在第二个示例中一样)。< / p>
在这两种情况下,您的代码都是错误的,尝试解释为什么会发生随机事件(再次,段错误或似乎工作)是毫无意义的。
答案 1 :(得分:4)
实际上,它可能来自您的编译器。如果您使用GCC,this page会说明printf("%s\n", s)
已优化为puts(s)
。该页面显示了2004年的错误报告,但我可以在Windows下使用GCC-4.7.2重现该错误。虽然printf
具有防止空指针的保护,但puts
似乎没有,因此取决于换行符的行为也不同。
然而,正如syam已经说过的那样,将空指针作为字符串给出并不是标准的,并且可能导致任何事情发生。这只是GCC友好,打印(null)
而不是简单地崩溃。
答案 2 :(得分:3)
两种情况都不正确,他们试图打印空指针的内容,这没有任何意义。您正在调用任何可能发生的未定义行为。
C标准保证行char *a[10] = {"hi", "hello", "how"};
以下列方式初始化:
a[0] -> "hi"
a[1] -> "hello"
a[2] -> "how"
a[3] -> NULL
...
a[9] -> NULL