使用指针初始化const数组

时间:2014-03-21 13:53:43

标签: c gcc c99

为什么第一行有效但其余行无效。我虽然第一个是第二个的速记。

const char *c = "abc"; // Why valid?

const char *b = { 'a' , 'b', 'c', '\0' }; // invalid

const int *a = { 1, 2, 3, 0 }; // invalid

4 个答案:

答案 0 :(得分:3)

这里的真正区别在于"abc"char[]类型的字符串文字,而{'a', 'b', 'c', 0}则不是。struct s{ char c; int i, j; float f; } x = {'a', 'b', 'c', 0}; 。您可以轻松地使用它来初始化完全不同的类型,例如:

const char *b = { 'a' , 'b', 'c', '\0' };

因此,当您编写{'a'} -> 'a'时,编译器会选择隐式转换const char *b = { '\0' };并尝试使用该命令初始化您的指针。根据编译器和实际值,这可能会也可能不会失败,例如,许多编译器会将b解释为将const char *b = (const char[]){'a', 'b', 'c', 0}; const int *a = (const int[]){'a', 'b', 'c', 0}; struct s *x = &(struct s){'a', 'b', 'c', 0}; 初始化为NULL指针,而不是像预期的那样将空字符串初始化。

如果要初始化指向使用列表初始化创建的数组(或任何其他类型)的地址的指针,则应明确强制转换:

data::__ID
data::firstName
data::lastName

答案 1 :(得分:1)

在第一种情况下,你有一个字符串文字,它是char数组,在这种情况下它将被转换为指向char的指针。

在接下来的两种情况下,您尝试使用列表初始化来初始化指针,该指针将尝试将列表的第一个元素转换为生成警告的指针,因为char或int都不是指针,同样的方式这会:

const char *b = 'a' ;

如果列表中有有效的指针,它对第一个元素可以正常工作,但由于你有比变量更多的初始值,因此格式不正确。

答案 2 :(得分:0)

数组和指针不是一回事。

const char *c = "abc";

使用字符串常量的地址初始化指针。 Sting常量包含在其他地方(不在堆栈上,通常是特殊的全局常量区域)。

const char c[] = "abc";

使用给定字符初始化字符数组(包含给定字符串的内容)。这个会在堆栈上。

答案 3 :(得分:0)

第一行是有效的,因为C标准允许创建常量字符串,因为它们的长度可以在编译时确定。

同样不适用于指针:编译器无法决定是否应该为堆中的数组分配内存(例如,就像普通的 int [] )或者常规记忆,如 malloc()

如果将数组初始化为:

   int a[] = { 1, 2, 3, 0 };

然后它变得有效,因为现在编译器确定你想在堆(临时)内存中有一个数组,并且在你离开代码部分后它将从内存中释放出来宣布。