C char数组v C char *初始化

时间:2017-03-20 14:33:21

标签: c string initialization declaration

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,你就会被编译器抓住。

2 个答案:

答案 0 :(得分:7)

以下内容会产生错误

char *green = { 'a', 'b', 'c' };

因为green的初始值设定项不是您认为的字符数组。它没有类型,它只是一个括号封闭的初始化列表。它在之前的样本中初始化的内容(即white)决定了它的解释方式。可以使用相同的initialzier初始化任何能够容纳3个字符的聚合。

但是green是一个指针,而不是一个聚合,所以你不能使用大括号括起来的初始化列表作为它的初始值。 1

现在,以下两个工作但语义非常不同:

char blue[]  = "abc";
char *red    = "abc";

blue是一个数组。它将保留与文字"abc"相同的内容。 red是指向文字"abc"指向的指针。

  1. 您可以使用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' };   
相关问题