1

左辺値の評価が右辺値の評価に先行し、割り当ても値を返す場合、次のうちどれが最初に評価されますか?

int i = 2;
int x[] = {1, 2, 3};
int y[] = {4, 5, 6};
int z[] = {7, 8, 9};

x[--i] = y[++i] = z[i++]; // Out of bound exception or not?

: 左辺値の評価が最初に来る一般的な C ライクな言語。私の教科書から

C などの一部の言語では、代入は、副作用を生成するだけでなく、その評価によって計算された r 値も返す演算子と見なされます。したがって、Cで書くと:

x = 2;

このようなコマンドの評価は、値 2 を x に代入するだけでなく、値 2 を返します。したがって、C では次のように書くこともできます。

y = x = 2;

次のように解釈する必要があります。

(y = (x = 2));
4

3 に答える 3

6

i連続するシーケンス ポイント間で変数の値を複数回変更して読み取っているため、この場合の動作は未定義であると確信しています。

また、C では[]、型の後ろではなく、変数名の後に配置することで配列を宣言します。

int x[] = {1, 2, 3};

編集:

[ほとんどの場合]無関係であるため、例から配列を削除します。次のコードを考えてみましょう。

int main(void)
{
    int i = 2;
    int x = --i + ++i + i++;
    return x;
}

iこのコードは、配列を使用せずに元のコードで変数に対して実行される操作を示しています。iこのステートメントでは、変数が複数回変更されていることがより明確にわかります。連続するシーケンス ポイント間で変更された変数の状態に依存する場合、動作は未定義です。コンパイラが異なれば (実際、GCC は 6 を返し、Clang は 5 を返します)、異なる結果が得られます。また、同じコンパイラでも、異なる最適化オプションを使用して異なる結果が得られたり、明らかな理由がまったくない場合があります。

i連続するシーケンス ポイント間で何度か変更されたために、このステートメントの動作が定義されていない場合は、元のコードについても同じことが言えます。代入演算子は、新しいシーケンス ポイントを導入しません。

于 2011-02-01T21:46:12.183 に答える
2

全般的

C では、2 つのシーケンス ポイント間の操作の順序は依存すべきではありません。標準からの正確な文言は覚えていませんが、このためです

i = i++;

未定義の動作です。標準では、 を構成するもののリストが定義されていsequence pointsます。メモリから、これは次のとおりです。

  1. ステートメントの後のセミコロン
  2. コンマ演算子
  3. 関数呼び出し前のすべての関数引数の評価
  4. && と || オペランド

ウィキペディアのページを調べると、リストがより完全になり、より詳細に説明されています。シーケンス ポイントは、C では非常に重要な概念です。その意味をまだ知らない場合は、すぐに学習してください。

明確な

xyおよびz変数の評価と代入の順序がどれほど明確に定義されていても、

x[--i] = y[++i] = z[i++];

i--このステートメントは、 、 、i++およびのため、未定義の動作に他なりませんi++。一方で

x[i] = y[i] = z[i];

は明確に定義されていますが、これに対する評価の順序がどのようなステータスかはわかりません。これが重要な場合は、「... の前に ... が割り当てられている/初期化されていることが重要である」というコメントとともに、これを 2 つのステートメントに分割することをお勧めします。

于 2011-02-01T21:44:47.243 に答える
-3

と同じだと思います

x[3] = y[4] = z[2];
i = 3;
于 2011-02-01T21:50:38.567 に答える