0
#include <stdio.h>

int main(void) {
    for (int i = 0; i < 5; i++) {
        int arr[5] = {0};
        // arr gets zeroed at runtime, and on every loop iteration!
        printf("%d %d %d %d %d\n", arr[0], arr[1], arr[2], arr[3], arr[4]);
        // overwrite arr with non-zero crap!
        arr[0] = 3;
        arr[1] = 5;
        arr[2] = 2;
        arr[3] = 4;
        arr[4] = 1;
    }
    return 0;
}

どうやらこれはうまくいきます:

> gcc -Wall -Wextra -pedantic -std=c99 -o test test.c;./test
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

しかし:

  • ボンネットの下で何が起こっているのですか?
  • これは、任意のサイズの配列で機能することが保証されていますか?
  • ループの反復ごとに配列をゼロにする最も洗練された方法を見つけましたか?
4

6 に答える 6

6

反復ごとに新しい配列を作成しているため、再初期化はありません。

于 2012-05-14T12:46:15.273 に答える
3

これは以前に回答されています:

内部で何が起こっているのですか?

コンパイラはmemsetと同等のコードを生成します(詳細については、配列0からの奇妙なアセンブリ-初期化を参照してください)。

これは、任意のサイズのアレイで機能することが保証されていますか?

はい、使用可能なスタックサイズの制限までです。

ループのすべての反復で配列をゼロにする最も洗練された方法を見つけましたか?

そうだと思います。:)

于 2012-05-14T12:51:20.460 に答える
3

私によれば、ループを反復処理しているときはいつでも、ループ内で宣言している変数はすべてそのループに対してローカルです。したがって、ループの終わりにそれらは破壊され、ループが再び開始されると、それらは再び作成されます。したがって、1。上記の回答。2.はい、これは任意のサイズのアレイで機能するはずです。3.いいえ...

于 2012-05-14T12:46:42.567 に答える
3

変数arrは、ループの反復ごとに作成および初期化されます。これは、それがあなたが書いたものだからです。あなたの例では、コードは配列をゼロに設定するのと似たようなことmemset()をしますが、おそらくより効率的でインラインです。ゼロ以外の初期化子を作成することもできます。

はい、「任意の」サイズの配列で機能します。配列が大きい場合、ループは遅くなります。

それは効果を達成するための非常にエレガントな方法です。コンパイラは可能な限り高速にそれを行います。より高速な関数呼び出しを記述できるのであれば、プログラマーの作成者は間抜けです。

于 2012-05-14T12:48:07.623 に答える
0

はい、C標準は、ループの反復ごとに配列要素がゼロになることを保証します。最初の反復でそれらをゼロにするだけの場合は、配列を静的にします。

static int arr[5] = {0}; 

初期化子がない場合はすべての要素に0が割り当てられているかのように静的データを初期化する必要があるため= { 0 }、この場合は省略できます(または、ポインターの場合はNULL、構造体の場合は浮動小数点値の場合は0.0)。

また、配列の次元で指定されているよりも少ない初期化子を使用すると、残りの要素にゼロが割り当てられることにも注意してください。それで

int arr[5] = {42, 0xdead};

と同等です

int arr[5] = {42, 0xdead, 0, 0, 0};

単一の0を使用することは、このルールの特殊なケースにすぎません。

于 2012-05-14T12:46:37.510 に答える
-2

コードの論理エラーを無視しないでください(各反復で再初期化)配列のすべての要素を割り当てたいときはいつでもmemcpyまたはmemsetを使用することをお勧めします。これは試行錯誤された方法であり、幸いなことにほとんどすべてのコンパイラの実装。

Memsetの例

MemCpyの例

したがって、Memsetを使用すると、コードは次のようになります。

int a[5]; 
memset(a,0,<number of bytes to be set to> sizeof(int)*5); 

ドキュメントを読んで、なぜ高速なのかを確認してください。お楽しみいただけます...

編集 申し訳ありませんが、すべての反対投票者/コメント投稿者に感謝します...私は答えを修正しました...

于 2012-05-14T12:52:57.697 に答える