c-为什么逗号的使用在表达式中有效,但在声明中失败



我来自高级OOP语言C#和Java,最近开始在C中挠头。我觉得C和JS一样有点奇怪。所以我想澄清一下:

下面给出了错误,这似乎很直观,因为它看起来像是不正确的语法,即使在OOP语言中也是如此

int i=0,1,2;  
/*
Error : expected identifier or ‘(’ before numeric constant
 int i = 0, 1, 2;
            ^
*/

然而,下面的工作原理令人惊讶:

int i;
i = 0,1,2;    //works

为什么会有这种行为?它们对保持这样的行为有什么意义吗?还是只是一些解析技术细节?

i = 0,1,2; 

这是任务,相当于:

(i = 0), 1, 2;

逗号运算符(优先级最低)从左到右计算所有操作数,首先计算赋值i = 0,然后计算表达式12,并丢弃结果。

的第二个例子

int i=0,1,2;  

是初始化。将其与合法初始化int i = 0, j = 0;进行比较。

如果你使用,它会起作用

int i=(0,1,2); 

这实际上是一个棘手的问题,因为它依赖于复杂的C语法的细节。理解它的最佳来源是标准草案,我们可以使用Annex A语言语法摘要作为参考。

基本思想是:

int i=0,1,2; 

是一个声明和:

i = 0,1,2; 

是一个表达式。

在表达式中,我们可以使用逗号运算符来评估左手边(通常用于副作用),丢弃结果,然后评估右手边等。

在声明中,逗号是语法分隔符,而不是逗号运算符。,分隔声明符,由于12在声明上下文中不是声明符,这是不正确的语法:

 int i=0,1,2;
        ^^^^

C99标准的相关语法如下:

init-declarator-list:
    init-declarator
    init-declarator-list , init-declarator   <--- here comma is just a seperator
init-declarator:
    declarator
    declarator = initializer

因此,在这种情况下,,init声明符分隔开,它们可以是声明符宣告符=初始值设定项12都不是申明符

初始值设定项可以是赋值表达式,这一点毫无价值,但该表达式并没有为我们提供一个通向空逗号运算符的路径,尽管我们最终可能会在()中使用逗号运算符(通过主表达式),但这看起来不像分隔符。

对于表达式,6.5.17节中的相关语法为:

expression:
    assignment-expression
    expression , assignment-expression

逗号运算符的描述如下:

逗号运算符的左操作数计算为空表示在其评估之后有一个序列点。然后计算右操作数;结果有其类型和值。[…]

注意逗号运算符的优先级最低,请使用以下表达式:

i = 0,1,2; 

相当于:

(i = 0),1,2; 

因此CCD_ 14将得到CCD_。

1.

  int i, j;
  i = 3,0,1,2;
  printf("%dn", i); => prints 3

2.

  i = 3,j =7;
  printf("%d, %dn", i, j); => prints 3 and 7

i = 3,0,1,2;分配3 to i,然后执行0, 1 and 2。检查我提到的第二个例子。

此外,尝试i=3;0;1;2;这不会报告任何错误。它将只执行(i=3), (0), (1) and (2)

相关内容

  • 没有找到相关文章

最新更新