web-dev-qa-db-ja.com

array [100] = {0}はどのようにして配列全体を0に設定しますか?

コンパイラはどのようにしてchar array[100] = {0};の値を埋めますか?その背後にある魔法は何ですか?

内部でコンパイラがどのように初期化されるかを知りたかった。

140
mahesh

それは魔法ではありません。

Cでのこのコードの動作は、C仕様のセクション6.7.8.21で説明されています( C仕様のオンラインドラフト ):指定された値を持たない要素の場合、コンパイラはNULLおよび算術型はゼロ(およびこれを集計に再帰的に適用)。

C++でのこのコードの動作は、C++仕様のセクション8.5.1.7で説明されています( C++仕様のオンラインドラフト ):コンパイラは、指定された値を持たない要素を集約初期化します。

また、C++(ただしCではない)では、空の初期化リストを使用できるため、コンパイラーは配列のすべての要素を集約初期化することに注意してください。

char array[100] = {};

これを行うとコンパイラがどのようなコードを生成するかについては、次の質問をご覧ください。 配列0-初期化からの奇妙なアセンブリ

161
bk1e

実装はコンパイラ開発者次第です。

あなたの質問が「そのような宣言で何が起こるか」である場合-コンパイラは最初の配列要素を指定した値(0)に設定し、それ以外はすべて省略された配列要素のデフォルト値であるためゼロに設定されます。

34
qrdl

コンパイラがGCCの場合、次の構文も使用できます。

int array[256] = {[0 ... 255] = 0};

http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Inits をご覧ください。これはコンパイラ固有の機能。

27
lakshmanaraj

この初期化をどこに置くかによります。

配列が次のように静的な場合

char array[100] = {0};

int main(void)
{
...
}

次に、プログラムのデータセグメントに100 0バイトを予約するのはコンパイラです。この場合、初期化子を省略できます。

配列が自動の場合、別の話です。

int foo(void)
{
char array[100] = {0};
...
}

この場合、関数fooを呼び出すたびに、非表示のmemsetがあります。

上記のコードは次と同等です

int foo(void)
{ 
char array[100];

memset(array, 0, sizeof(array));
....
}

また、イニシャライザを省略すると、配列にランダムデータ(スタックのデータ)が含まれます。

ローカル配列が次のように静的に宣言されている場合

int foo(void)
{ 
static char array[100] = {0};
...
}

技術的には最初のケースと同じです。

17
gallier2