#include<stdio.h>
int main()
{
int i=2;
printf("%d %d \n",++i,++i);
}
上記のコードは出力を提供します4 4
。出力を説明する方法を手伝ってくれる人はいますか?
どちらの答えも同じ間違いを犯しています。その明確なUBであり、不特定の動作だけではありません。
あなたが経験したのはUndefined behaviorです。シーケンスポイントについてお読みください。コンマは、演算子ではなく関数呼び出しの区切り記号です。
シーケンス ポイントは、ほこりが落ち着いた時点で、これまでに見られたすべての副作用が完全であることが保証されています。C 標準にリストされているシーケンス ポイントは次のとおりです。
完全な式の評価の終了時 (完全な式は、式ステートメント、またはより大きな式内の部分式ではないその他の式です)。||、&&、?:、およびコンマ演算子で。および関数呼び出し時 (すべての引数の評価後、実際の呼び出しの直前)。
規格は次のように述べています
前のシーケンス ポイントと次のシーケンス ポイントの間で、オブジェクトの格納値は、式の評価によって最大 1 回変更されます。さらに、保存する値を決定するためにのみ、前の値にアクセスする必要があります。
最初に評価されるもの this "%d %d \n"
、 this++i
または this ++i
(2番目のもの) - それについて考えてください。これは指定されていない動作です。
void f(int x)
{
printf("%d ",x);
}
int main()
{
int i=0;
f(i++) ;
}
ウィキから:
関数呼び出しで関数が入力される前。引数が評価される順序は指定されていませんが、このシーケンス ポイントは、関数に入る前にすべての副作用が完了していることを意味します。式 f(i++) + g(j++) + h(k++) では、i の元の値のパラメーターで f が呼び出されますが、i は f の本体に入る前にインクリメントされます。同様に、j と k はそれぞれ g と h に入る前に更新されます。ただし、f()、g()、h() が実行される順序や、i、j、k がインクリメントされる順序は指定されていません。f の本体の変数 j と k は、既にインクリメントされている場合とされていない場合があります。関数呼び出し f(a,b,c) はコンマ演算子の使用ではなく、a、b、および c の評価順序は指定されていないことに注意してください。