无意中,我发现第char s[] = {"Hello World"};行是正确编译的,似乎与第char s[] = "Hello World";行的处理方式相同.第一个({"Hello World"})不是一个数组,它包含一个char数组元素,所以s的声明应该是char *s[]?事实上,如果我把它改成char *s[] = {"Hello World"};,编译器也会像预期的那样接受它.

为了寻找答案,我找到的唯一提到这一点的地方是this one,但没有引用标准.

所以我的问题是,为什么要编译第char s[] = {"Hello World"};行,而左侧是array of char类型,右侧是array of array of char类型?

以下是工作计划:

#include<stdio.h>
int main() {
    char s[] = {"Hello World"};
    printf("%s", s); // Same output if line above is char s[] = "Hello World";
    return 0;
}

谢谢你的澄清.

另外,我的编译器是gcc-4.3.4.

推荐答案

这是允许的,因为标准是这样规定的:C99第6.7.8节,§14:

字符类型的数组可以由字符串文字(可选)初始化

这意味着两者都

char s[] = { "Hello World" };

char s[] = "Hello World";

只不过是句法上的糖,

char s[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0 };

在相关的说明中(同一节,§11),C还允许在标量初始值设定项周围使用花括号,比如

int foo = { 42 };

顺便说一句,它非常符合复合文字的语法

(int){ 42 }

C++相关问答推荐

生成C代码时自动复制/生成' tmwtypes.h '依赖项

如何使用Python C API实现多线程程序?

在C中使用JMP_buf数组进行线程化(在xv6中测试)

为什么在函数内部分配内存空间时需要添加符号?

我在这里正确地解释了C操作顺序吗?

为什么我会收到释放后堆使用错误?

将返回的char*设置为S在函数中定义的字符串文字可能会产生什么问题?

在C++中父进程和子进程中的TAILQ队列同步问题

Go和C中的数据 struct 对齐差异

链表删除 node 错误

判断系统命令返回值的正确方法

*S=0;正在优化中.可能是GCC 13号虫?或者是一些不明确的行为?

为什么二进制文件的大小不会随着静态数据的大小而增加?

哪个首选包含第三个库S头文件?#INCLUDE;文件名或#INCLUDE<;文件名&>?

为什么GCC不能在 struct 初始值设定项中以sizeof作为条件的三进制中处理复合文字的编译时求值?

分配给静态变量和动态变量的位置之间有区别吗?

如果类型是新的,offsetof是否与typeof一起工作?

为什么这个代码的最后一次迭代不能正常工作?

C: NULL>;NULL总是false?

为什么argc和argv即使在主函数之外也能工作?