回答:
それは魔法ではありません。
Cでのこのコードの動作は、C仕様のセクション6.7.8.21(C仕様のオンラインドラフト)で説明されています。指定された値を持たない要素の場合、コンパイラーはポインターをNULLに、算術型をゼロに初期化します(これを再帰的に集計に適用します)。
C ++でのこのコードの動作は、C ++仕様のセクション8.5.1.7(C ++仕様のオンラインドラフト)で説明されています。コンパイラは、指定された値を持たない要素を集約初期化します。
また、C ++(Cではない)では、空の初期化リストを使用できるため、コンパイラーが配列のすべての要素を集約初期化することに注意してください。
char array[100] = {};
これを行うとコンパイラーがどのようなコードを生成する可能性があるかについては、この質問を見てください:配列0からの奇妙なアセンブリ-初期化
実装はコンパイラ開発者次第です。
あなたの質問が「そのような宣言で何が起こるか」である場合-コンパイラーは最初の配列要素を指定された値(0)に設定し、その他はすべて省略された配列要素のデフォルト値であるためゼロに設定されます。
コンパイラがGCCの場合は、次の構文も使用できます。
int array[256] = {[0 ... 255] = 0};
http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Initsを参照してください。これはコンパイラ固有の機能であることに注意して ください。
この初期化をどこに置くかによります。
配列が静的である場合
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};
...
}
その後、技術的には最初のケースと同じです。