以下のコード スニペット
int jo=50;
if( jo =(rand()%100), jo!=50)
{
printf("!50");
}
- % の優先順位が最も高いため、 rand()%100 が最初に実行されます
- != は = よりも優先順位が高いため、jo != 50 は実行権を取得する必要があります。
- 、 i execute 代入が最初に発生し、次に != 、次に , が発生した場合でも、優先順位は最も低くなります。出力が !50 になるのはなぜですか??
以下のコード スニペット
int jo=50;
if( jo =(rand()%100), jo!=50)
{
printf("!50");
}
問題は「シーケンスポイント」です:
http://www.angelikalanger.com/Articles/VSJ/SequencePoints/SequencePoints.html
問題のある表現と安全な表現
割り当て x[i]=i++ + 1; をレンダリングするのは何ですか? 代入 i=2 に対して問題のあるもの。その結果が明確に定義され、予測可能であるという意味で無害ですか? 核心は、式 x[i]=i++ + 1; にあります。変数 i には 2 つのアクセスがあり、アクセスの 1 つ、つまり i++ は変更アクセスです。シーケンスポイント間の評価の順序は定義されていないため、 i が読み取られる前に変更されるのか、変更される前に読み取られるのかはわかりません。したがって、問題の根本は、アクセスが変更である場合、シーケンス ポイント間の変数への複数アクセスです。
別の例を次に示します。ステートメントが実行される前に i と j の値が 1 と 2 の場合、ここで何が起こるでしょうか?
f(i++, j++, i+j);
関数 f の 3 番目の引数として渡される値はどれですか? 繰り返しますが、わかりません。3、4、または 5 のいずれかになります。これは、関数の引数が評価される順序によって異なります。
ここでよくある誤解は、引数が左から右に評価されるというものです。それとも右から左?実際、言語定義によって義務付けられている順序はまったくありません。
優先順位は実行の順序を制御しません。優先順位はグループ化のみを制御します。つまり、優先順位は、各操作がいつ発生するかではなく、各操作のオペランドが何であるかを示します。
この例では%
、括弧のために の優先順位は無関係です。これらは、 のオペランド%
がrand()
およびであることを示しています100
。
andの優先順位,
よりも低い優先順位は、 のオペランドがandであり、 のオペランドがandであることを示しています。=
!=
=
jo
(rand()%100)
!=
jo
50
,
thenのオペランドはjo = (rand() % 100)
とjo != 50
です。
演算子の定義に,
よると、最初のオペランドが評価され、次にシーケンス ポイントがあり、次に 2 番目のオペランドが評価されます。したがって、このケースjo = (rand() % 100)
は完全に評価され、の結果がrand() % 100
into に格納されjo
ます。そしてjo != 50
評価される。式全体の値は の値ですjo != 50
。
まあ、シーケンスポイントが正しい答えです。しかし、教科書から翻訳しましょう-ese。
コンマ演算子には特別な性質があります: 左側にあるものが最初に評価されるようにします。だから、あなたが式に到達するとき
jo =(rand()%100), jo!=50
!=
バインドは ' , ' よりもきついため、完全に括弧で囲まれた式は次のようになります。
(jo =(rand()%100)),(jo!=50)
最初の部分が最初に評価されます。
これを覚えておくために、コンマ演算子を「and then」と発音または読むことができます。
j0=(rand()%100)
"その後"
jo!=50.
「優先」を「最初に行う」と考えるのは間違いです。
次のコード スニペットを検討してください。
f() + g() + h()
f() と g() の結果を合計する加算演算と、それと h() の結果を加算する加算演算のどちらが優先されますか?
「優先順位」を呼び出す必要がまったくないため、これはひっかけ問題です。ただし、C の関数呼び出しは「シーケンス ポイント」を導入するため、操作の順序はまだあります。これは、いわば「いつ何が起こるか」を C で判断できるようにする方法です。
特定のコードでは、この部分にコンマ演算子があります。これは、関数の引数のコンマ区切り記号とはまったく異なります。
jo = (rand() % 100), jo != 50
コンマ演算子は ( への関数呼び出しと同様に) シーケンス ポイントを導入するため、が実行されて値が生成され、その値が計算されて に割り当てられ、最後にと比較されるrand
ことがわかります。rand
% 100
jo
jo
50
if
(同様に、制御式の評価の後にシーケンス ポイントがあり、各ステートメント終了セミコロンにも 1 つずつあります。)