2

以下のコード スニペット

int jo=50;
if( jo =(rand()%100), jo!=50)
{
    printf("!50");
}   
  1. % の優先順位が最も高いため、 rand()%100 が最初に実行されます
  2. != は = よりも優先順位が高いため、jo != 50 は実行権を取得する必要があります。
  3. 、 i execute 代入が最初に発生し、次に != 、次に , が発生した場合でも、優先順位は最も低くなります。出力が !50 になるのはなぜですか??
4

4 に答える 4

4

問題は「シーケンスポイント」です:

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 のいずれかになります。これは、関数の引数が評価される順序によって異なります。
ここでよくある誤解は、引数が左から右に評価されるというものです。それとも右から左?実際、言語定義によって義務付けられている順序はまったくありません。

于 2012-05-26T05:29:16.530 に答える
3

優先順位は実行の順序を制御しません。優先順位はグループ化のみを制御します。つまり、優先順位は、各操作がいつ発生するかではなく各操作のオペランドが何であるかを示します。

この例では%、括弧のために の優先順位は無関係です。これらは、 のオペランド%rand()およびであることを示しています100

andの優先順位,よりも低い優先順位は、 のオペランドがandであり、 のオペランドがandであることを示しています。=!==jo(rand()%100)!=jo50

,thenのオペランドはjo = (rand() % 100)jo != 50です。

演算子の定義に,よると、最初のオペランドが評価され、次にシーケンス ポイントがあり、次に 2 番目のオペランドが評価されます。したがって、このケースjo = (rand() % 100)は完全に評価され、の結果がrand() % 100into に格納されjoます。そしてjo != 50評価される。式全体の値は の値ですjo != 50

于 2012-05-26T05:36:54.677 に答える
3

まあ、シーケンスポイントが正しい答えです。しかし、教科書から翻訳しましょう-ese。

コンマ演算子には特別な性質があります: 左側にあるものが最初に評価されるようにします。だから、あなたが式に到達するとき

 jo =(rand()%100), jo!=50

!= バインドは ' , ' よりもきついため、完全に括弧で囲まれた式は次のようになります

 (jo =(rand()%100)),(jo!=50)

最初の部分が最初に評価されます。

これを覚えておくために、コンマ演算子を「and then」と発音または読むことができます。

 j0=(rand()%100)

"その後"

 jo!=50.
于 2012-05-26T05:37:15.263 に答える
2

「優先」を「最初に行う」と考えるのは間違いです。

次のコード スニペットを検討してください。

f() + g() + h()

f() と g() の結果を合計する加算演算と、それと h() の結果を加算する加算演算のどちらが優先されますか?

「優先順位」を呼び出す必要がまったくないため、これはひっかけ問題です。ただし、C の関数呼び出しは「シーケンス ポイント」を導入するため、操作の順序はまだあります。これは、いわば「いつ何が起こるか」を C で判断できるようにする方法です。

特定のコードでは、この部分にコンマ演算子があります。これは、関数の引数のコンマ区切り記号とはまったく異なります。

jo = (rand() % 100), jo != 50

コンマ演算子は ( への関数呼び出しと同様に) シーケンス ポイントを導入するため、が実行されて値が生成され、その値が計算されて に割り当てられ、最後にと比較されるrandことがわかります。rand% 100jojo50

if(同様に、制御式の評価の後にシーケンス ポイントがあり、各ステートメント終了セミコロンにも 1 つずつあります。)

于 2012-05-26T05:35:58.843 に答える