6

次元のないグローバル配列を定義するときの概念は何ですか。これは出力を 16 として示しています。

    #include <stdio.h>
    #include <stdlib.h>
    int arr[];

    int main(int argc, char *argv[])
    {
        arr[1] = 16;

      printf("%d\n",arr[1]);
      system("PAUSE");  
      return 0;
    }

sizeof(arr) でも機能しません。なんで?

4

2 に答える 2

12

int arr[];暫定的な定義です。

条項 6.9.2、パラグラフ 2 は次のように述べています。

ファイル スコープを持ち、イニシャライザを使用せず、ストレージ クラス指定子を使用しないか、またはストレージ クラス指定子 static を使用するオブジェクトの識別子の宣言は、暫定的な定義を構成します。翻訳単位に識別子の暫定的な定義が 1 つ以上含まれており、翻訳単位にその識別子の外部定義が含まれていない場合、動作は、翻訳単位にその識別子のファイル スコープ宣言が含まれているかのように、複合型は次のようになります。に等しいイニシャライザを使用して、翻訳単位の末尾を指定し0ます。

そして、その条項のパラグラフ 5 の例 2 は、次のことを明確にしています。

を含む翻訳単位の末尾にある場合

   int i[];

配列iにはまだ不完全な型があり、暗黙的なイニシャライザによって要素が 1 つになり、プログラムの起動時にゼロに設定されます。

したがって、翻訳単位の最後で、配列のarr型はになりますint[1]。終了する前に、その型は不完全であるため、sizeof機能しませんmain。 では、配列型がまだ不完全であるためです。

要素が 1 つしかないため、アクセスするarr[1]と未定義の動作が呼び出されます。arr

于 2013-06-21T19:28:13.730 に答える
1

GCC は、arr要素が 1 つだけであることを前提としています。セグメンテーション違反なしで他の要素にアクセスできるという事実arr[0]は、単なる偶然です。たとえば、私のマシンでは にアクセスできarr[1]、問題なくアクセスできますがarr[10]、segfaultarr[100]が発生します。arr[1000]一般に、配列の範囲外の場所にアクセスすると、未定義の動作が発生します。

于 2013-06-21T19:28:41.160 に答える