![](/img/trans.png)
[英]Why can't you increment/decrement a variable twice in the same expression?
[英]Using of several increment/decrement in the same statement
我知道C中的计算顺序并不严格,因此表达式的值--a + ++a
是未定义的,因为它不知道哪个语句部分首先运行。
但是,如果我知道计算顺序在特定情况下无关紧要怎么办? 例如:
a[p1++] = b[p2++]
) a++ + ++a
- 无论首先计算+
哪一边,结果都是两个。 是否保证在运行另一个部件之前将完全计算一个部件? 即编译器无法记住a++
的结果, ++a
的结果然后首先应用a++
,得到一个而不是两个? 例如,高速缓存的初始值a
并将其传递作为参数传递给两个操作员独立。 我对C,C99,C11,C ++ 03和C ++ 11的答案很感兴趣,如果它们之间有任何区别的话。
标准说:
在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次。 此外,只能访问先前值以确定要存储的值。 / 26 /
除非语法/ 27 /或稍后指定(对于函数调用operator(),&&,||,?:和逗号运算符),子表达式的求值顺序和副作用的顺序地方都没有说明。
所以:
1.) a[p1++] = b[p2++]
:保证正确评估语句并给出预期结果。 这是因为每个变量只修改一次,结果不依赖于两个变量的实际增量完成的时间。
2.) a++ + ++a
:不能保证在第二次使用a
之前执行副作用(增量)。 因此,此表达式可以给出值a + (a+1)
或(a+1) + (a+1)
或a + (a+2)
具体取决于编译器何时执行原始变量的副作用增量。
6.5表达式
...
3语法指示运算符和操作数的分组。 85)除了后面指出的,子表达的副作用和价值计算是没有顺序的 。 86)
85)语法规定了运算符在表达式求值中的优先级,这与本子条款的主要子条款的顺序相同,首先是最高优先级。 因此,例如,允许作为二元+
运算符(6.5.6)的操作数的表达式是6.5.1到6.5.6中定义的表达式。 例外是强制转换表达式(6.5.4)作为一元运算符的操作数(6.5.3),以及下列任何运算符对之间包含的操作数:分组括号()
(6.5.1),下标括号[]
(6.5 .2.1),函数调用括号()
(6.5.2.2)和条件运算符? :
? :
(6.5.15)。 在每个主要子条款中,运算符具有相同的优先级。 在每个子条款中通过其中讨论的表达式的语法指示左或右相关性。
86)在程序执行期间不止一次评估的表达式中,不需要在不同的评估中一致地执行其子表达式的未序列和不确定顺序的评估。
强调补充说。
无法保证在评估其他表达式之前应用a++
或++a
的副作用 ,因此您可以根据操作顺序获得不同的结果。
下面是一些例子,假设a
从1开始的:
或任何其他组合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.