用花括号初始化一维和二维数组

3
以下代码会出现“无效的初始化器”错误:
     int a[]=(1,2,3);

但是以下代码虽然将','视为逗号运算符而不是分隔符,但可以成功编译:
    int a[][2]={(1,2),(3,4)};

那么为什么()对于一维数组无效而对于二维数组有效呢?

2个回答

9
在第一个示例中:
int a[]=(1,2,3);

初始化程序是一个类型为int的表达式(相当奇怪)。它包含两个逗号运算符,并产生值3。该对象是一个数组。初始化无效,因为存在类型不匹配。

第二个:

int a[][2]={(1,2),(3,4)};

等同于:

int a[][2] = { 2, 4 };

这段话在IT技术方面,需要翻译的内容为:“由于初始化器中允许省略嵌套花括号,因此该语句是有效的;元素用于初始化对象的连续元素。第一个和第三个逗号是逗号运算符;第二个是分隔符。”

如果初始化器仅仅是目标类型的表达式(无论它是标量、结构体还是联合体),则最外层的花括号是可选的。例如,您可以这样写:

int x = 42;
int y = { 42 };

外层大括号在为数组、结构体或联合体对象指定元素值的初始化器中是必需的。

例如:

struct foo {
    int x;
    int y;
};

 struct foo arr[2] = { 1, 2, 3, 4 };

“is valid”是有效的,但更清晰的写法是:

 struct foo arr[2] = { { 1, 2 }, { 3, 4 } };

除了第一个示例无效外,两个示例的样式都很差。第一个示例可能本意是:
int a[] = { 1, 2, 3 };

第二种方式是:
int a[][2] = { 2, 4 };

或者

int a[][2] = {{1, 2}, {3, 4}};

根据意图而定。

我同意你的答案,但是我认为“最外层花括号用于数组结构初始化”的说法并不正确,因为你也可以将它们用于标量,比如int、char,但是它只会返回第一个元素。 - Saurabh Mehta
@SaurabhMehta:我说最外层大括号是必需的,用于数组、结构体和联合体的初始化(除非,现在我想到了,初始化程序是结构体或联合体类型的对象)。对于标量初始化程序,大括号是可选的 - Keith Thompson
@SaurabhMehta:抱歉,我之前的评论应该写成“表达式”,而不是“对象”。我已经更新了我的答案。 - Keith Thompson

2

在第一个示例中,您忘记使用花括号。花括号表示数组内容的初始化,然后您可以通过这些花括号内的声明来处理数组内容。基本上,在第一个示例中,您没有对数组进行初始化。圆括号表示评估顺序,而不是函数参数。


1
不,(1, 2, 3) 是一个类型为 int 值为 3 的表达式。初始化程序无效是因为类型不匹配。请看我的答案。(也许本意是使用大括号而不是圆括号,但我认为问题是关于为什么这个特定的代码不被接受。) - Keith Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接