C语言中运算符的优先级和相关性

roo*_*kea 1 c operator-precedence associativity

请查看以下代码段:

int a = 10, b;  
b = (a) + (++a);                       //2  
printf("b = %d\n", b);  
Run Code Online (Sandbox Code Playgroud)

输出:

b = 22  
Run Code Online (Sandbox Code Playgroud)

在声明2中,有4个不同的运算符.其中()优先级最高.由于()操作员的关联性是从左到右为什么b = 22而不是21

$ gcc --version  
gcc (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3
Run Code Online (Sandbox Code Playgroud)

Kei*_*son 8

b = (a) + (++a);
Run Code Online (Sandbox Code Playgroud)

这有未定义的行为.

引用C99标准(实际上是N1256草案),6.5p2:

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算来修改一次.此外,先前的值应该只读以确定要存储的值.

该表达式既读取值a又更新它,读取操作(LHS +)不用于确定写操作(RHS +)存储的值.

2011 ISO C标准(引自N1570草案)以不同的方式说明,但含义基本相同:

如果相对于对同一标量对象的不同副作用或使用相同标量对象的值进行值计算,对标量对象的副作用未被排序,则行为未定义.如果表达式的子表达式有多个允许的排序,则如果在任何排序中发生这种未测序的副作用,则行为是不确定的.

(a)是使用值的值计算a; (a++)是副作用a.由于操作数的计算顺序+没有指定,这两个操作是未测序相对于彼此.

因此,不仅仅是评估的顺序是未定义的 - 行为是未定义的,并且不限于+在两个可能的顺序中的任何一个中评估运算符的操作数的可能性.

不,括号不会改变这一点.

comp.lang.c FAQ的第3节很好地解释了这一点.