c
版本6.3接受以下有效gcc
代码:
char white[] = { 'a', 'b', 'c' };
char blue[] = "abc";
char *red = "abc";
然而以下失败:
char *green = { 'a', 'b', 'c' }; // gcc error
我确信这是一个非常合理的理由,但我想知道它是什么。这个问题是由于必须初始化一个字节数组(所以unsigned char
而不是char
)的情况所致,写{ '\x43', '\xde', '\xa0' }
而不是"\x43\xde\xa0"
这样的东西很诱人。一旦你忘记编写my_array[]
而不是*my_array
,你就会被编译器抓住。
答案 0 :(得分:7)
以下内容会产生错误
char *green = { 'a', 'b', 'c' };
因为green
的初始值设定项不是您认为的字符数组。它没有类型,它只是一个括号封闭的初始化列表。它在之前的样本中初始化的内容(即white
)决定了它的解释方式。可以使用相同的initialzier初始化任何能够容纳3个字符的聚合。
但是green
是一个指针,而不是一个聚合,所以你不能使用大括号括起来的初始化列表作为它的初始值。 1
现在,以下两个工作但语义非常不同:
char blue[] = "abc";
char *red = "abc";
blue
是一个数组。它将保留与文字"abc"
相同的内容。 red
是指向文字"abc"
的指向的指针。
您可以使用compound literal expression:
char *green = (char[]){ 'a', 'b', 'c' };
它告诉编译器创建一个未命名的对象(其生命周期取决于声明的范围),即字符数组类型,并用这三个字符初始化。然后为指针分配该对象的地址。
答案 1 :(得分:5)
这三个声明
char white[] = { 'a', 'b', 'c' };
char blue[] = "abc";
char *red = "abc";
是不同的。
第一个声明一个字符数组,其中包含与初始值设定项数对应的三个字符。
第二个声明了一个包含四个字符的字符数组,因为它是由一个包含四个字符(包括终止零)的字符串文字初始化的。所以这个字符数组包含一个字符串。
第三个定义了一个字符串文字,它是一个字符数组,并声明了一个类型为char *
的指针,该指针由对应于字符串文字的字符数组的第一个字符的地址初始化。
您可以将此声明想象为
char unnamed = { 'a', 'b', 'c', '\0' };
char *red = unnamed;
此声明
char *green = { 'a', 'b', 'c' };
无效,因为左对象是标量,并且可能无法由包含多个初始值设定项的列表初始化。
考虑到您可以使用复合文字初始化指针。例如
char *green = ( char[] ){ 'a', 'b', 'c' };