我偶然发现行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;
}
感谢您的任何澄清。
P.S。我的编译器是gcc-4.3.4。
答案 0 :(得分:64)
这是允许的,因为标准是这样说的: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 }
答案 1 :(得分:22)
大括号是可选的,表达式只相当于char数组。
你也可以这样写:
int a = {100}; //ok
实际上,C++11
概括了这个语法,统一地初始化非数组和数组。所以在C++11
中,您可以拥有以下内容:
int a{}; //a is initialized to zero, and it is NOT an array
int b[]{1,2,3,4}; //b is an array of size 4 containing elements 1,2,3,4
int c[10]{}; //all 10 elements are initialized to zero
int *d{}; //pointer initialized to nullptr
std::vector<int> v{1,2,3,4,5}; //vector is initialized uniformly as well.
答案 2 :(得分:3)
(int
,char
等)中的任何变量都只是一个长度为1的数组。
char s = {0};
也可以。
答案 3 :(得分:2)
我可能错了,但我认为这不是一个字符数组数组,但是一个块包含一个字符数组。 int a = {1};
也可以正常运作。
答案 4 :(得分:1)
[...]事实上,如果我将其更改为 char * s [] = {“Hello World”};编译器也接受它,如 预期
编译器加入它,因为实际上,你正在创建一个未定义大小元素的数组2D,其中只存储了一个元素"Hello World"
字符串。像这样:
char* s[] = {"Hello world", "foo", "baa" ...};
在这种情况下,您无法省略bracets
。
答案 5 :(得分:1)
这也是C ++标准允许的,Citation:
窄字符类型([basic.fundamental]),char16_t数组,char32_t数组或wchar_t数组的数组可分别由窄字符串文字,char16_t字符串文字,char32_t字符串文字或宽字符串文字初始化, 或由大括号([lex.string])中包含的适当类型的字符串文字。 [剪断]