在 C 中,为什么包含逗号(,)运算符的表达式(语句)的工作方式不同

In C, why expression(Statement) containing comma(,) operator work differently

我有一个简单的 C 代码,但对包含逗号 (,) 运算符的表达式很困惑。

int main(){
    int i=0,j=11,c;
    c=i=j,++i;
    printf("c=%d i=%d\n",c,i);
    c=(i=j,++i);
    printf("c=%d i=%d\n",c,i);
    return 0;
}

以上代码打印:

c=11 i=12
c=12 i=12

我的问题是:

  1. 逗号 (,) 作为运算符的实际工作是什么?
  2. ++的优先级高于,=,为什么要对逗号左边的表达式进行求值?
  3. 如果一个表达式包含不同优先级的运算符,顺序是什么,是否取决于逗号(,)?
  4. 它的行为是否像分号 (;) 的替代品?

好吧,让我们分开吧。第一种情况c和i取j的值=> c=i=j=11;然后你递增 i => i=12;所以代码相当于这个

c = j;
i = j;
++i;

对于第二种情况,i 取值 j => i=j=11 然后递增 i => i=12 然后 c 取值 i => c = 12;

所以代码等同于:

i = j;
++i;
c = i;

运算符逗号是执行多条语句,return只是最后一条语句的结果。

所以对于 c=i=j,++i;c=i=j 被执行,然后 ++i 然后 ++i 的结果被 return 编辑(但未被使用)。

而对于c=(i=j,++i);,根据运算符优先级,执行i=j,紧接着++i执行,然后对[的结果c做作=18=],这是最后一条语句的结果,即++i

所以,逗号的行为与分号并不完全相同。您可以像 c=i=j,++i; 中那样将其用作替代品。

就我个人而言,我不鼓励使用此运算符,它会生成可读性和可维护性较差的代码

逗号运算符将评估丢弃所有操作,最多但不包括最终操作。这允许在只有最后一个操作感兴趣的一行上一起调用任意数量的无关紧要的操作。

这样想,如果你有许多循环变量要在循环中的任何一个位置递增,你可以将所有 additions/subtraction 等分开。线,但为什么呢?它们的执行位置(在合理范围内)对代码的操作 没有影响 。然后可以在一行中调用它们,而不会对代码产生不利影响。

赋值运算符的优先级高于逗号运算符。 因此表达式

c = i = j, ++i;

相当于

( c = i = j ), ++i;

根据 C 标准(6.5.17 逗号运算符)

2 The left operand of a comma operator is evaluated as a void expression; there is a sequence point between its evaluation and that of the right operand. Then the right operand is evaluated; the result has its type and value.114)

在上面的表达式中,逗号运算符的结果被丢弃,但它有增加 i.

的副作用

在这个表达式中

c = ( i = j, ++i );

由于使用括号,您更改了上述表达式的计算顺序。现在相当于

c = ( ( i = j ), ++i );

和变量 c 根据上面列出的 C 标准中的引用获取表达式 ++i 的值。

What is the actual work of comma(,) as an operator?

逗号运算符主要是一个多余的功能。 See this 了解其工作原理。

++ has more precedence than , and =, why evaluation is done for the expression on left of comma? What will be the order if an expression contains operators with different priority, will it depend on comma(,)?

计算左操作数的副作用。逗号运算符的结果是评估的右操作数的结果。请注意,逗号运算符在 C 中的所有运算符中具有最低的优先级。

Is it behaving like a substitute of semicolon(;)?

有点,是的。分号和逗号运算符都包含一个序列点。不同之处在于逗号运算符不是语句的结尾,因此可以将其与其他运算符挤在同一行中,并且它也是 returns 结果。

虽然你真的没有理由想要这样做。逗号运算符的主要用途是混淆代码,应该避免使用。您需要了解其工作原理的唯一原因是您可能会遇到包含它的垃圾代码。

例如,你的废话代码应该改写成更具可读性和安全性的代码:

int main(){
    int i=0;
    int j=11;
    int c;

    i=j;
    c=j;
    i++;
    printf("c=%d i=%d\n",c,i);

    i=j;
    i++;
    c=i;
    printf("c=%d i=%d\n",c,i);

    return 0;
}