逗号(,)运算符在C

时间:2018-07-09 13:20:26

标签: c

我刚刚开始阅读C。

情况:

  

x =(y = 3,(z = ++ y + 2)+ 5)

它先评估 y = 3 ,然后评估(z = ++ y + 2)

我的问题:

它首先应该求值(z = ++ y + 2),因为逗号(,)的优先级远小于括号

我的思维方式:

  
      
  1. 由于优先级,我们选择了外部括号

  2.   
  3. 然后我们需要评估括号

  4.   
  5. 在此(括号)下,我再次开始应用优先级规则

  6.   
  7. 所以我先用内括号进行评估

  8.   

P.S。 :

这不是重复的

我已经浏览了这些链接,但仍然无法理解

Behavior of comma operator in C

C comma operator

What does the comma operator , do?

https://docs.microsoft.com/en-us/cpp/cpp/comma-operator

Uses of C comma operator

https://en.wikipedia.org/wiki/Comma_operator

3 个答案:

答案 0 :(得分:5)

您将运算符的优先级与求值顺序混淆了。

运算符优先级指示子表达式的分组方式。它不会指示何时评估每个操作数。

逗号运算符在其左操作数和右操作数之间具有序列点。对于y = 3, ( z = ++y + 2 ) + 5,这意味着y = 3必须在 ( z = ++y + 2 ) + 5被评估之前被完全评估。

还要在子表达式( z = ++y + 2 ) + 5中注意,不能保证括号内的所有内容都先于括号内的所有内容。您只知道在评估( z = ++y + 2 )之前先评估5( z = ++y + 2 ) + 5。例如,如果您有(z = ++y + 2) + y,它将调用undefined behavior,因为第二个y可以在++y的副作用之前或之后进行评估。

作为另一个示例,如果您有x = (func1() + 3) + func2(),由于未指定操作数的评估顺序,因此可以首先调用func1或首先调用func2。如果这两个函数都修改了相同的全局变量,那么您将无法可靠地知道该变量的值。

答案 1 :(得分:4)

优先级和评估顺序是不同的。在表达式(a*b) - (c+d)中,即使乘法的优先级高于加法,编译器仍可以在(c+d)之前对(a*b)进行求值。但是在表达式a,b和代码a;b中,要求编译器在计算a之前对b的计算进行排序。

答案 2 :(得分:1)

您在优先级评估顺序之间感到困惑。优先级是将不同类型的运算符及其操作数进行分组的优先级。

逗号(,)构成Sequence Point,因此保证操作数的特定评估顺序为从左到右

Order of evaluation

  

订购
  ......

     

如果在子表达式E1和E2之间存在一个序列点,那么将在计算E2的每个值和副作用之前对E1的值计算和副作用进行排序

     

规则
  .....
  2)在以下两个二进制运算符的第一个(左)操作数的求值之后和第二个(右)操作数的求值之前有一个序列点:&&(逻辑AND),|| (逻辑或)和,(逗号)。

在此表达式中:

x = ( y = 3, ( z = ++y + 2 ) + 5 )

首先评估y = 3,然后评估( z = ++y + 2 ) + 5