问题:为什么输出的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 プログラマーが習得しなければならないスキルです。 ! !
そうしないと、プログラムをデバッグするときに、推測に頼ることしかできず、盲人のようになってしまいます。
分析
実際、経験に基づいて、これははるかに複雑ではなく、未定義の動作ではなく、演算子のスコープの問題であると思います。
リーリーこの式の正しい実行順序は次のとおりです:
演算子は
リーリー:
よりも優先順位が高いため、,
は一目瞭然です。:
の前の条件は true であり、順次にのみ実行できますが、後続の,
は:
演算子の範囲を超えています。したがって、条件が true かどうかに関係なく、--y は必ず実行されます。したがって、正しい書き方は
括号
を追加することです。分解
リーリー?:
演算子は,
演算子よりも優先度が高いため、式(someValue ? x, y : --x, --y)
は((someValue ? ( x, y) : --x), --y)
と同等であるため、条件演算 y の後に --y が続くため、y は 5 を出力します。まず、修正、任意の操作順序を定義します。未定義の動作のほとんどは、 操作 順序ではなく、 評価 順序に対するものです。
c には、
A ? B : C
、A, B
、A && B
の 3 つの評価順序が定義されています (もちろん、||
もあります)。上記のコードは判読不能であると非難される可能性がありますが、未定義であるとは言えません。結果は明らかで、5 です。