-1

このコードがコンパイルされない理由

#include <stdio.h>
int x=5;
int a[x];
int main()
{
     a[0]=5;
     printf("%d\n",a[0]);
     return 0;
}

gcc filename.c -Wall -ansi -pedantic でコンパイルすると、エラーが発生します

エラー: ファイル スコープで可変的に変更された 'a'

ただし、このコードはコンパイルされますが、警告は表示されますが、正しい出力が得られます。

#include <stdio.h>
int main()
{
     int x=5;
     int a[x];
     a[0]=5;
     printf("%d\n",a[0]);
     return 0;
}

警告: ISO C90 は可変長配列 'a' を禁止しています [-Wvla]

ただし、 g++ filename.c -Wall -ansi -pedantic を使用してこれをコンパイルしようとすると、警告は生成されず、正しい出力も得られます

#include <stdio.h>
const int x=5;
int a[x];
int main()
{
    a[0]=5;
    printf("%d\n",a[0]);
    return 0;
}

gcc バージョン 4.7.0 を使用しています

何が起こっているのか詳しく説明してください。

4

4 に答える 4

4

C では、自動ストレージ期間を持つ配列オブジェクトのみが可変長配列になることができます。ファイル スコープで宣言されたオブジェクトは、自動保存期間を持つことはできません。

2 番目のコード例では、c89/c90 には可変長配列がなく、この機能を使用するには c99 コンパイラを使用する必要があります。使用している場合はgcc、オプションで c99 を選択できます-std=c99。または、c: c11 の最新バージョンを使用することもできます。

C++ には可変長配列がありません。

于 2012-12-24T19:12:50.597 に答える
4

C では (C++ とは異なり) const 宣言は定数式を生成しません。つまり、C では、VLA 以外の配列宣言で const int オブジェクトを配列サイズとして使用することはできません。

そう、

const int max_foos = 10;
int foos[max_foos];

C++ では有効ですが、C では無効です。同等の C コードは次のようになります。

#define MAX_FOOS 10
int foos[MAX_FOOS];

注意:
c の const は定数を意味しません。「読み取り専用」という意味です。

可変長配列は、C99 でのみ C 標準の一部になったことに注意してください。それ以前は、標準では許可されていませんでしたが、ほとんどのコンパイラでは拡張機能として許可されていました。


最初のコード スニペットは、配列の添え字が定数である必要があるため、コンパイルされません。また、可変長配列はグローバル スコープでは宣言できません。

可変長配列は c99 より前の標準の一部ではなかったため、2 番目のコード スニペットはコンパイルされません。

C とは異なり、C++ では const 宣言が定数式を生成するため、3 番目のスニペットはコンパイルされます。

于 2012-12-24T19:13:39.567 に答える
2

可変長配列は C99 以降でのみサポートされており、グローバルにすることはできません。

C11、配列宣言子、6.7.6.2:

識別子が可変的に変更された型を持つと宣言されている場合、それは通常の識別子 (6.2.3 で定義) であり、リンケージを持たず、ブロック スコープまたは関数プロトタイプ スコープのいずれかを持ちます。識別子が静的またはスレッド ストレージ期間を持つオブジェクトとして宣言されている場合、可変長配列型を持たないものとします。

于 2012-12-24T19:06:30.887 に答える
1

はいそして ?

C と C++ の世代が異なれば、配列のサイズ設定に使用できるルールも異なります。最初のケースでは、従来の ANSI (C89/90) にコンパイルしています。

C++ では、C99 と同様に (定数) を配列サイズとして使用できます。「元の」C++ ANSI 標準は 1990 年より新しいため、C99 標準に多くのものが追加されていることに注意してください。

于 2012-12-24T19:04:01.310 に答える