问题:为什么输出的y是5,而不是6?
相关代码
#include <iostream>
int main() {
int someValue = 1, x = 1, y = 5;
std::cout << (someValue ? ++x, ++y : --x, --y) << std::endl;
return 0;
}
相关贴图(测试环境:Xcode 7.3.1 OSX EI Capitan)
个人思考
思考1:因为条件运算符?:是右结合,所以先执行--y,y变成4,再执行++y,y变成5。疑问:条件运算符的执行顺序是:先求解表达式1,若为非0(真)则求解表达式2,此时表达式2的值就作为整个条件表达式的值。那为什么还会出现这样的问题
思考2:这句语句中的第二第三个运算对象指向同一个对象x,y;而且两个都修改了对象的值,这种行为是未定义的。疑问:但是?:运算符不是已经确定了运算顺序码?为什么还会出现这样的问题?
前言
每次遇見問c++問題的,都是這樣的比較基礎的問題,這段話我每次都說:
反彙編是c++程式設計師必掌握的一項技能! ! !
反組譯是c++程式設計師必掌握的技能! ! !
反組譯是c++程式設計師必掌握的技能! ! !
否則,在調試程式的時候就跟瞎子沒什麼兩樣,只能靠猜。
分析
實際上根據經驗我認為遠沒有那麼複雜,更不是未定義行為,而是運算符作用域的問題。
這個表達式正確的執行順序如下:
一目了然,因為
:
運算子的優先權要高於,
。而:
之前的條件為真,只能順序執行,而之後的,
則超出的:
運算符作用域。所以,無論條件成立與否,--y一定會被執行。所以正確寫法要加
括号
.反組譯
因為
?:
運算子的優先權高於,
運算符,所以(someValue ? ++x, ++y : --x, --y)
這個表達式相當於((someValue ? (++x, ++y) : --x), --y)
所以條件運算++y之後會--y,所以y輸出5先修正一點,任何運算順序都是有定義的。多數未定義行為是針對求值順序而不是運算順序。
c 中有定義的求值順序有三:
A ? B : C
,A, B
,A && B
(當然也有||
)。你上面的程式碼可以被指責是可讀性不好的,但不能說是未定義的。結果相當明確,就是 5。