为什么第一行有效但其余行无效。我虽然第一个是第二个的速记。
const char *c = "abc"; // Why valid?
const char *b = { 'a' , 'b', 'c', '\0' }; // invalid
const int *a = { 1, 2, 3, 0 }; // invalid
答案 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 };
然后它变得有效,因为现在编译器确定你想在堆(临时)内存中有一个数组,并且在你离开代码部分后它将从内存中释放出来宣布。