web-dev-qa-db-ja.com

グローバル変数で決定されるサイズの配列を作成できないのはなぜですか?

配列aがグローバル変数sizeによって初期化されないのはなぜですか?

#include<stdio.h>

int size = 5;

int main()
{
    int a[size] = {1, 2, 3, 4, 5};
    printf("%d", a[0]);

    return 0;
}

コンパイルエラーは次のように表示されます

可変サイズのオブジェクトが初期化されていない可能性があります

私によると、配列はsizeによって初期化されるはずです。

そして、私がグローバル変数を使用することを主張した場合(可能な場合)、答えはどうなりますか?

20
Ashish Yadav

C99では、6.7.8/3:

初期化するエンティティのタイプは、サイズが不明な配列か、可変長配列タイプではないオブジェクトタイプでなければなりません。

6.6/2:

定数式は、実行時ではなく変換中に評価できます

6.6/6:

整数定数式は整数型を持ち、整数定数、列挙定数、文字定数、結果が整数定数であるsizeof式、およびキャストの直接のオペランドである浮動定数であるオペランドのみを持つものとします。

6.7.5.2/4:

サイズが整数定数式で、要素の型が既知の定数サイズである場合、配列型は可変長配列型ではありません。それ以外の場合、配列型は可変長配列型です。

aは整数定数式ではないため、sizeは可変長配列型です。したがって、初期化リストを含めることはできません。

C90にはVLAがないため、そのためコードは不正です。

C++にはVLAもありませんが、sizeconst intにすることができます。これは、C++ではICEでconst int変数を使用できるためです。 Cではできません。

おそらくあなたはaが可変長になることを意図していなかったので、必要なのは:

#define size 5

実際にaを可変長にするつもりなら、次のようにすることができるでしょう。

int a[size];
int initlen = size;
if (initlen > 5) initlen = 5;
memcpy(a, (int[]){1,2,3,4,5}, initlen*sizeof(int));

または多分:

int a[size];
for (int i = 0; i < size && i < 5; ++i) {
    a[i] = i+1;
}

ただし、サイズが!= 5の場合、ここで「発生するはず」が何であるかを言うのは困難です。可変長配列に固定サイズの初期値を指定することは、実際には意味がありません。

22
Steve Jessop

イニシャライザを指定する場合は、配列のサイズをコンパイラに通知する必要はありません。コンパイラーは、初期化に使用している要素の数に基づいてサイズを計算します。

_int a[] = {1,2,3,4,5};
_

次に、バイト単位の配列の合計サイズsizeof(a)を取得し、それを1つの要素のサイズsizeof(a[0])で除算することにより、コンパイラーにサイズを通知させることもできます。

_int size = sizeof(a) / sizeof(a[0]);
_
9
indiv

コンパイラーは、main()が制御を取得するまでに、sizeの値がまだ5であるとは想定できません。古いスタイルのCプロジェクトで真の定数が必要な場合は、以下を使用します。

#define size 5
6
Seva Alekseyev

コンパイラがC99に準拠していないようです...どのコンパイラを使用していますか?それがgccの場合は、スイッチ '-std = c99'を渡す必要があります。..C99以前のコンパイラを使用している場合、そのステートメントは無効です。その場合は、次のようにします。

 int main(){
 int a [5] = {1,2,3,4,5}; 
 printf( "%d"、a [0]); 
 0を返します。 
} 

C99より前の標準コンパイラでは、変数の代わりに定数を使用します。

編集:C99標準 here ...および here について詳しく知ることができます。 ...

3
t0mm13b

sizeは変数であり、Cでは宣言できません(edit:C99では宣言できますが、初期化しないだけです。あなたがやっているように)そのような可変サイズの配列。サイズが変数である配列を作成する場合は、 malloc を使用するか、サイズを定数にします。

3
IVlad

コンパイラは、配列を宣言する際に配列のサイズを知る必要があります。配列のサイズは宣言後も変化しないためです。配列のサイズを変数に入れると、プログラムの実行時にその変数の値が変化することを想像できます。この場合、コンパイラはこの配列に追加のメモリを割り当てるように強制されます。この場合、配列はスタックに割り当てられた静的データ構造であるため、これは不可能です。これがお役に立てば幸いです。

2
Abderrahmen
#include<stdio.h> 

/* int size=5; */
#define size 5 /* use this instead*/
/*OR*/
int a[size]={1,2,3,4,5};  /* this*/

int main() 
{ 
    int a[size]={1,2,3,4,5}; 
    printf("%d",a[0]); 
    return 0; 
} 

int sizeは、size変数であり、Cが変数size配列を許可しないことを意味します。

私はVS2008を使用していますが、

const int size=5;  

許可する

int a[size]={1,2,3,4,5}; 
0
Pratik Deoghare