这并没有根本上的原因 - 它只是该语言最初定义的方式。
数组初始化的基本语法为
type array[] = {value, value, value};
指针初始化的基本语法为:
type *pointer = value
但是,我们也有字符串字面量。实际上,编译器对字符串字面量进行的操作在本质上是两个几乎完全不同的方面。
如果你这样说:
char array[] = "string";
编译器会将其处理得几乎与你实际编写的代码一样。
char array[] = { 's', 't', 'r', 'i', 'n', 'g', '\0' };
但是如果您说
char *p = "string";
编译器会做一些完全不同的事情。它会在背后默默地为您创建一个数组,其中包含该字符串,差不多就像您编写了:
char __hidden_unnamed_array[] = "string"
char *p = __hidden_unnamed_array
然而,回答你的问题的关键是编译器只会对字符串字面值做这种特殊处理。至少在C语言最初的定义中,没有办法使用{value, value, value}
语法创建一个隐藏、无名称的数组,并对其进行其他操作。 {value, value, value}
语法仅被定义为作为显式声明数组的直接初始化器。
正如@pmg在评论中提到的,新版本的C语言有一种新的语法——"复合字面量",它基本上让你可以使用{value, value, value}
语法创建一个隐藏的、无名称的数组并对其进行其他操作。 因此,你实际上可以编写:
char *word2 = (char[]){'a', 'b', 'c', '\0'};
这个非常好用。在其他情况下也可以使用,例如,您可以说类似于:
printf("%s\n", (char[]){'d', 'e', 'f', '\0'});
回到你问的一个副问题:当你写下
char *word2 = {'a', 'b', 'c', '\0'};
编译器对自己说,“等一下,
word2
是一个东西,但初始化程序有四个。所以我会丢弃三个,并警告程序员我正在这样做。”接着它做了相当于...
char *word2 = {'a'};
如果您稍后尝试类似以下的操作
printf("%s", word2);
当printf
尝试访问地址0x00000061时,您遇到了崩溃的情况。
char *word2 = (char[4]){'a', 'b', 'c', '\0'};
- pmg