1

誰かが理由を説明できますか

int main(int argc, const char * argv[]) {
  while (* argv) 
    puts(* argv++);
  return 0 ;
}

合法であり、

int main(int argc, const char * argv[]) {
  argv += argc - 1;
  while (* argv) 
    puts(* argv--);
  return 0 ;
}

そうじゃない?どちらの場合も、while ループ内の 'crement は argv の境界の外側を指します。虚数のより高いインデックスを指すことは合法であり、虚数のより低いインデックスを指すことはなぜ合法ですか?

よろしくお願いします。

4

4 に答える 4

1

C標準では、配列の末尾を過ぎたものへのポインターを作成できると述べているため、配列へのポインターと適切に比較されます(ただし、逆参照はできません)。

標準では、配列の先頭より前のアドレスへのポインターについては何も述べていません。そのようなポインターを作成しても、未定義の動作が発生します。

于 2013-04-15T19:18:48.737 に答える
0

標準argv[argc]は と等しいことを強制するためNULL、 argv がインクリメントされたときに逆参照することargcは合法です。

一方、 の前のアドレスについては何も定義されていないargvため、argv - 1何でもかまいません。

私の知る限り、このように動作することが保証されている文字列の配列は argv だけであることに注意してください。

標準から:

5.1.2.2.1 プログラムの起動

それらが宣言されている場合、メイン関数へのパラメーターは次のコスト制約に従う必要があります。

argv[argc] は null ポインターでなければなりません

于 2013-04-15T19:28:33.543 に答える
0

ループ セマンティクスとハーフ オープン インターバル。ポインターが指すオブジェクトの配列またはリストを反復処理する慣用的な方法は次のとおりです。

for (T *p = array; p < array + count; p++)

ここでpは、最終的には範囲外 (1 つずれる、配列の末尾を 1 つ超えた位置) になるため、未定義の動作を呼び出さないように this を要求することは (概念的にだけでなく) 便利です (標準は実際にこの要件を課しています)。

于 2013-04-15T19:18:46.700 に答える
0

argv++または++argvそれがconstポインタであるため。

のような単純な配列を取ってchar* arr[10]試しarr++てみると、エラーが発生します

于 2013-08-20T20:40:10.307 に答える