我刚刚开始阅读C。
情况:
x =(y = 3,(z = ++ y + 2)+ 5)
它先评估 y = 3 ,然后评估(z = ++ y + 2)
我的问题:
它首先应该求值(z = ++ y + 2),因为逗号(,)的优先级远小于括号
我的思维方式:
由于优先级,我们选择了外部括号
然后我们需要评估括号
在此(括号)下,我再次开始应用优先级规则
所以我先用内括号进行评估
P.S。 :
这不是重复的
我已经浏览了这些链接,但仍然无法理解
Behavior of comma operator in C
What does the comma operator , do?
答案 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,因此保证操作数的特定评估顺序为从左到右。
订购
......如果在子表达式E1和E2之间存在一个序列点,那么将在计算E2的每个值和副作用之前对E1的值计算和副作用进行排序
规则
.....
2)在以下两个二进制运算符的第一个(左)操作数的求值之后和第二个(右)操作数的求值之前有一个序列点:&&(逻辑AND),|| (逻辑或)和,(逗号)。
在此表达式中:
x = ( y = 3, ( z = ++y + 2 ) + 5 )
首先评估y = 3
,然后评估( z = ++y + 2 ) + 5
。