“为什么?”;char*ptr={';R';,';E';,';D';,';\0';}&引用;“时发出过多警告”;char*ptr=";“红色”&引用;行吗?

“为什么?”;char*ptr={';R';,';E';,';D';,';\0';}&引用;“时发出过多警告”;char*ptr=";“红色”&引用;行吗?,c,arrays,pointers,array-initialization,C,Arrays,Pointers,Array Initialization,考虑以下代码: #include<stdio.h> int main() { char *ptr={'R','E','D','\0'}; //char *ptr="RED"; } 但是如果我注释掉第一条语句并激活第二条语句(在我的代码中注释掉),if可以正常工作 为什么会这样?为什么在第一种情况下,指向同一数组的指针没有分配给ptr,就像在第二种情况下一样?造成这种情况的严格技术原因是什么?在6.7.9(11)[N1570草案中,与C99的6.7.8(11)中相同],

考虑以下代码:

#include<stdio.h>

int main()
{
   char *ptr={'R','E','D','\0'};
   //char *ptr="RED";
}
但是如果我注释掉第一条语句并激活第二条语句(在我的代码中注释掉),if可以正常工作

为什么会这样?为什么在第一种情况下,指向同一数组的指针没有分配给
ptr
,就像在第二种情况下一样?造成这种情况的严格技术原因是什么?

在6.7.9(11)[N1570草案中,与C99的6.7.8(11)中相同],规定

标量的初始值设定项应为单个表达式,可以选择用大括号括起来。对象的初始值为表达式的初始值(转换后);应用与简单赋值相同的类型约束和转换,将标量的类型作为其声明类型的非限定版本

通过在中提供多个表达式

char *ptr={'R','E','D','\0'};
您违反了“应”的要求,并调用了未定义的行为(4(2)):

如果违反了出现在约束或运行时约束之外的“应”或“不应”要求,则行为未定义

顺便说一句,这种特殊的未定义行为通常会在编译器忽略除第一个表达式以外的所有表达式时保持不变——除了生成

warning: excess elements in scalar initializer|
并将代码视为

char *ptr = {'R'};
然后,这就不足为奇地导致了

warning: initialization makes pointer from integer without a cast|
因为
'R'
是一个整数而不是指针

另一方面,

char *ptr = "RED";
非常好,因为数组(1)
“RED”
在初始化过程中被转换为指向其初始元素的指针,就像用于赋值一样

(1) 字符串文字是数组,而不是指针,如第6.4.5(6)节所述:

在翻译阶段7中,将值为零的字节或代码附加到由字符串文字产生的每个多字节字符序列中然后使用多字节字符序列初始化静态存储持续时间和长度刚好足以包含序列的数组。对于字符串文字,数组元素的类型为char,并使用多字节字符序列的各个字节进行初始化。对于UTF−8个字符串文字,数组元素的类型为char,并使用UTF编码的多字节字符序列的字符进行初始化−八,


(宽字符串文字是
wchar\u t[N]
char16\u t[N]
char32\u t[N]
类型的数组,这取决于它们的前缀是
L
u
还是
u

,但H2CO3表示字符串文字
“RED”
char[4]/code>,而不是
char*/code>,但是paxdiablo说它属于
char*
类型。谁是对的?如果我是对的,你的答案在最后一行中说字符串文字确实属于
char[4]
类型,但它在分配给
ptr
之前被转换为指针
char*
。对吗?是的,
红色“
的类型是
char[4]
,正如H2CO3所说,这个数组进行数组到指针的转换。天哪!!是什么让paxdiablo删除了他的答案Fischer先生?我很高兴我发布了这个看似微不足道的问题,而不是耸耸肩。我从中学到了很多新东西。
char *ptr = "RED";