我知道C中的计算顺序并不严格,因此表达式--a + ++a
的值未定义,因为未知哪个语句部分首先运行。
但是,如果我知道计算顺序在特定情况下无关紧要怎么办?例如:
a[p1++] = b[p2++]
)a++ + ++a
中一样 - 无论+
的哪一侧先计算,结果都是两个。是否保证在运行另一个部件之前将完全计算一个部件?即编译器无法记住a++
的结果,++a
的结果,然后首先应用a++
,而不是两个?例如,缓存a
的初始值并将其作为参数单独传递给两个运算符。我对C,C99,C11,C ++ 03和C ++ 11的答案感兴趣,如果它们之间有任何差异。
答案 0 :(得分:3)
标准说:
在上一个和下一个序列点之间有一个对象 它的存储值最多只能通过评估一次修改 表达。此外,只能访问先前值 确定要存储的值。 / 26 /
除非语法/ 27 /或稍后指定 (对于函数调用运算符(),&&,||,?:和逗号 运算符),子表达式的评估顺序和顺序 发生哪些副作用都是未指明的。
所以:
1。)a[p1++] = b[p2++]
:保证正确评估语句并给出预期结果。这是因为每个变量只修改一次,结果不依赖于两个变量的实际增量完成的时间。
2。)a++ + ++a
:无法保证在第二次使用a
之前执行副作用(增量)。因此,此表达式可以赋予值a + (a+1)
或(a+1) + (a+1)
或a + (a+2)
,具体取决于编译器何时执行原始变量的副作用增量。
答案 1 :(得分:0)
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开始:
或任何其他组合。