Mah*_*aha 5 c declaration comma-operator
来自高级OOP语言C#和Java,最近开始在C中摸不着头脑.我觉得C有点奇怪,就像有人觉得JS一样.所以想澄清如下:
下面给出了错误,这看起来很直观,因为即使在OOP语言中它看起来也是不正确的语法
int i=0,1,2;
/*
Error : expected identifier or ‘(’ before numeric constant
int i = 0, 1, 2;
^
*/
Run Code Online (Sandbox Code Playgroud)
但是下面的工作令人惊讶:
int i;
i = 0,1,2; //works
Run Code Online (Sandbox Code Playgroud)
为什么会这样?保持这种行为或仅仅是一些解析技术问题是否有意义?
i = 0,1,2;
Run Code Online (Sandbox Code Playgroud)
这是赋值,相当于:
(i = 0), 1, 2;
Run Code Online (Sandbox Code Playgroud)
逗号运算符(具有最低优先级)从左到右计算所有操作数,首先是赋值i = 0,然后是表达式1,2并将结果抛出.
第二个例子
int i=0,1,2;
Run Code Online (Sandbox Code Playgroud)
是初始化.将其与合法初始化进行比较int i = 0, j = 0;.
它适用于您使用:
int i=(0,1,2);
Run Code Online (Sandbox Code Playgroud)
这实际上是一个棘手的问题,因为它依赖于复杂的C语法的细节.理解它的最佳来源是草案标准,我们可以使用Annex A 语法语法摘要作为参考.
基本思路是:
int i=0,1,2;
Run Code Online (Sandbox Code Playgroud)
是一份声明并且:
i = 0,1,2;
Run Code Online (Sandbox Code Playgroud)
是一种表达.
在一个表达式中,我们可以使用逗号运算符来评估左侧(通常用于副作用),抛弃结果然后评估右侧等...
在声明中,逗号是语法分隔符而不是逗号运算符.在,中隔离声明符和自1和2是不是在这个声明的上下文说明符是不正确的语法:
int i=0,1,2;
^^^^
Run Code Online (Sandbox Code Playgroud)
C99标准的相关语法如下:
init-declarator-list:
init-declarator
init-declarator-list , init-declarator <--- here comma is just a seperator
init-declarator:
declarator
declarator = initializer
Run Code Online (Sandbox Code Playgroud)
因此,在这种情况下,,中隔离初始化声明符它可以是一个声明符或声明符=初始化既不1也不2是声明中使用,所以我们有不正确的语法.
这是一文不值,一个初始化可以是一个赋值表达式,但这种表达不为我们提供了一个光秃秃的路径逗号操作符,虽然我们可以用逗号操作结束()(通过基本表达式),但是这不会像分隔符.
对于表达式,来自部分的相关语法6.5.17是:
expression:
assignment-expression
expression , assignment-expression
Run Code Online (Sandbox Code Playgroud)
逗号运算符的描述如下:
逗号运算符的左操作数被计算为void表达式; 评估后有一个序列点.然后评估右操作数; 结果有它的类型和价值.[...]
注意逗号运算符具有以下表达式的最低优先级:
i = 0,1,2;
Run Code Online (Sandbox Code Playgroud)
相当于:
(i = 0),1,2;
Run Code Online (Sandbox Code Playgroud)
因此i将获得价值,0并且进一步评估的结果将被丢弃.