Arrays 初始化指针时,为什么必须将数组强制转换为[]类型?

Arrays 初始化指针时,为什么必须将数组强制转换为[]类型?,arrays,c,pointers,Arrays,C,Pointers,初始化指针时不强制转换字符串: char *string = "Hello World!"; 但是,如果我尝试显式定义数组(无论它是什么类型),编译器会向我发出类型不兼容的警告: char *string = {'H', 'e', 'l', 'l', 'o', '\0'}; 对char[]进行强制转换是可行的,但我想知道为什么我们必须进行强制转换?编译器没有看到初始化值{'H','e','l','l','o','\0'}已经是一个数组了吗?如果我们以同样的方式初始化一个数

初始化指针时不强制转换字符串:

char *string = "Hello World!";
但是,如果我尝试显式定义数组(无论它是什么类型),编译器会向我发出类型不兼容的警告:

char *string = {'H', 'e', 'l', 'l', 'o', '\0'};

对char[]进行强制转换是可行的,但我想知道为什么我们必须进行强制转换?编译器没有看到初始化值
{'H','e','l','l','o','\0'}
已经是一个数组了吗?如果我们以同样的方式初始化一个数组,比如
string[]
,我们就不必强制转换。我假设编译器在这里看到初始化值是什么,为什么在初始化指针时看不到它?

字符串是指针,而不是数组,因此它需要一个作为指针的初始化器

第一个代码段是OK的,因为字符串文字具有数组类型,并且该数组衰减为指向其第一个元素的指针

第二个是不正常的,因为您正在为指针分配一组字符。因为
string
不是数组或结构,所以只使用初始值设定项列表的第一个成员。因此,您有一个字符常量,其类型为
int
,您正试图将其分配给指针

你说如果你投的话效果会很好。如果你是这个意思:

char *string = (char []){'H', 'e', 'l', 'l', 'o', '\0'};

然后,实际上右边是一个具有数组类型的复合文本,就像第一个示例一样,数组衰减为指向其第一个成员的指针。

初始化指针时,必须提供一个值,即对象的地址或空指针

{'H','e','l','l','o','0'}
不是任何东西的地址。这是初始化列表的语法,它只能用于初始化类型为数组或结构类型的变量

你实际上还没有展示你所说的演员阵容,但我想是的

char *string = (char[]){'H', 'e', 'l', 'l', 'o', '\0'};
虽然它使用类似的语法,但它实际上并不是强制转换

在括号中以数组或结构类型开头的初始值设定项列表称为。它创建指定类型的匿名对象,其值就是该对象

与数组一起使用时,值衰减为指向数组第一个元素的指针,就像在r值上下文中使用数组的任何其他用法一样。这允许您将其用作指针变量的初始值设定项

因此,它实际上相当于:

char temp[] = {'H', 'e', 'l', 'l', 'o', '\0'};
char *string = temp;
除了没有与数组关联的名称
temp


当使用字符串文字初始化时,不需要这种语法,因为字符串文字已经在静态内存中构造了数组,并计算为指向第一个元素的指针。

像{'a'}或{'a',1}甚至{}这样的复合文字意味着为将来的语言扩展打开

也许复合文字{'a',1',b',17}在某个时候将是未来可能的纯C hashmap初始化的有效右值

C的语法并没有故意假定太多

C可能会增长

另外,我们与C++的兼容性很小,我们不希望完全被C编译器所破坏,因为假设编译器会使C代码仍然难以通过C++编译器正确地运行。

C++和C++之间需要相互重视。


即使是C本身未来的潜在增长,也有必要不要将文字解释为它们在C中可能合理的含义,而是说初始化值
{'H','e','l','l','o','\0'}
是一组字符,没有数组就足够了@Kaiyaha一个问题的答案应该不仅对你有帮助,而且对任何其他可能有相同问题的人都有帮助。我知道,我只是觉得你没有完全理解我的问题。无论如何,一切都很好,谢谢你的回答,这解释了一切。好吧,现在我不明白为什么
string[]
会将
{'H','e','l','o','\0'}解释为一个数组而不强制转换。你能简单解释一下吗?@Kaiyaha复合文字是“就地”定义结构或数组的一种方式。它看起来像一个演员阵容,但有些不同。评论不是为了扩大讨论;这段对话已经结束。