所以我注意到在C语言中,我可以在变量的赋值语句的左侧放置方括号,并且可以正确编译:
int a;
(a) = 3;
但是,如果我在定义本身上加上方括号,这是行不通的:
(int a) = 3;
所以我的问题是,在第一个代码段中,C语法是否实际上通过忽略括号来解决(a)
意味着a
的事实,还是编译器实际上将其评估为意味着{{ 1}}。因为如果语法忽略了它,那么第二个代码片段为什么也行不通?
答案 0 :(得分:3)
关于OP的第一个示例代码:
int a;
(a) = 3;
这是一条声明(1 st 行),后跟赋值表达式(2 nd 行)。
第二个示例代码:
(int a) = 3; /* COMPILER ERROR */
是非法的,但为进一步解释,我将其更改为:
int a = 3;
这是一个定义–带有初始化的声明。
带有初始化的赋值和声明有所不同,尽管它们看起来非常相似(可能是故意的)。 (我有一种感觉,OP对此并不了解,因此我做了详细说明。)
可以找到完整的C语法ANSI C Yacc grammar。 (这确实很老,但我相信我想解释的足够了。)
规则适用于 (a) = 3;
:
适用于3
:primary_expression : CONSTANT
适用于a
:primary_expression : IDENTIFIER
适用于(a)
:primary_expression : '(' expression ')'
适用于=
:assignment_operator : '='
适用于(a) = 3
:assignment_expression : unary_expression assignment_operator assignment_expression
(其中右侧的assignment_expression
通过多个步骤解析为primary_expression
)。
规则适用于 int a = 3;
适用于int
:type_specifier : INT
代表a
:direct_declarator:IDENTIFIER`
:(这变得很复杂)
int a = 3;
declaration : declaration_specifiers init_declarator_list ';'
declaration_specifiers : type_specifier
init_declarator_list : init_declarator
init_declarator : declarator '=' initializer
将其放在一起,得出以下结果将是有效的:
initializer : assignment_expression
但是语法中根本没有东西可以解决
int b, a = (b) = 5;
/* ^ ^
* | +--- assignment operator
* +--------- initializer
*/
也许是,值得一提的是,有一个类似的问题