main()
{
int k = 5;
if(++k <5 && k++/5 || ++k<=8); // how to compiler compile this statement
print f("%d",k);
}
// ここでは答えは 7 ですが、なぜですか?
main()
{
int k = 5;
if(++k <5 && k++/5 || ++k<=8); // how to compiler compile this statement
print f("%d",k);
}
// ここでは答えは 7 ですが、なぜですか?
++k < 5
は false (6 < 5 = false) と評価されるため、&&
演算子の RHS は評価されません (結果が既に false であることがわかっているため)。++k <= 8
次に評価される (7 <= 8 = true) ため、完全な式の結果は true になり、k
2 回インクリメントされ、最終的な値は 7 になります。
&&
と||
は短絡ブール演算子であることに注意してください。式の結果が左側の引数によって決定できる場合、右側の引数は評価されません。
また、ほとんどの演算子とは異なり、短絡演算子は式内でシーケンス ポイントを定義するため、上記の例k
で同じ式を複数回変更することが正当化されることにも注意してください (一般に、これはシーケンス ポイントを介在させないと許可されず、未定義の結果になります)。動作)。
このような多くの質問とは異なり、あなたのコードには実際に動作が定義されているように見えます。
&&
および||
インポーズ シーケンス ポイントの両方。より具体的には、最初に左オペランドを評価します。次に、シーケンス ポイント1があります。次に (結果を決定するために必要な場合にのみ)、右側のオペランドを評価します。
&&
andの相対的な優先順位により||
、式:if(++k <5 && k++/5 || ++k<=8)
は: と同等であることにも言及する価値があるでしょうif((++k <5 && k++/5) || ++k<=8)
。
それでは、一度に 1 段階ずつ説明しましょう。
int k = 5;
if(++k <5 &&
で、まずはこれくらい評価。これは をインクリメントk
するので、その値は 6 になります。次に、それが 5 より小さいかどうかを比較します。これは明らかに false を生成します。
k++/5
前の結果が だったのでfalse
、このオペランドは評価されませんfalse && <anything>
(常に結果として生成false
されるため)。
|| ++k<=8);
したがって、実行がここに到達すると、false || <something>
. の結果は でfalse | x
あるx
ため、正しい結果を得るには正しいオペランドを評価する必要があります。++k
したがって、再び評価されるため、 k
7 にインクリメントされます。次に、結果を 8 と比較し、(明らかに) 7 が 8 以下であることを検出します。したがって、に続く null ステートメントif
が実行されます (ただし、 null ステートメントの場合、何もしません)。
したがって、if
ステートメントの後、k
は 2 回インクリメントされているので、7
です。
最初に、宣言で k
割り当てられ、次に if 条件で割り当てられます。5
++k < 5 && k++ / 5 || ++k <= 8
// ^
// evaluates
6 までインクリメントk
し、オペランドの LHS は&&
false と評価されます。
6 < 5 && k++ / 5 || ++k <= 8
// ^ ^^^^^^^
// 0 not evaluates
次に 、 && 演算子の短絡動作k++ / 5
のため、評価されません。
&& 演算子の短絡動作は:
0 && any_expression == 0
であるためany_expression
、評価する必要はありません。
したがって、上記のステップ 2 の条件式は次のようになります。
0 || ++k <= 8
// ^^^^^^^^
// evaluates
k
7 までインクリメントすると、次のようになります。
0 || 7 <= 8
;
afterがあるためif
、 condition が True または False と評価されるかどうかに関係なく、printf()
で呼び出されk = 7
ます。