13

Cで配列を再初期化するにはどうすればよいですか?

pointer: を介して定義する必要がありますかint *data[]、それとも単にコーディングできますint data[] = {};か?

たとえば、次のように定義しました。

int main(void) {
    int data[] = {44, 22, 1, 2, 3, 1000, 3};

では、配列を再初期化するにはどうすればよいdataですか?

4

4 に答える 4

15

初期化は、配列を作成するときに 1 回だけ行われます。

int foo[] = {0,1,2,3,4}; // creates a 5-element array of int and
                         // initializes it

配列が定義されたら、個々の要素に割り当てることができます:

foo[0] = 5;
foo[1] = 4;
foo[2] = 3;
foo[3] = 2;
foo[4] = 1;

ただし、配列自体に割り当てることはできません。IOW、あなたは次のようなものを書くことはできません

foo = {5,4,3,2,1};

ただし、ある配列の内容を別の配列にmemcpyコピーするために使用できます。

int foo[5];
int bar[5] = {1,2,3,4,5};
int i;

memcpy(foo, bar, sizeof bar); // Copies *contents* of bar to foo

for (i = 0; i < sizeof foo / sizeof *foo; i++)
  printf("foo[%d] = %d\n", i, foo[i]);

同様に、この方法で作成された配列はサイズ変更できません。そのサイズは宣言時に固定されます。C89 以前では、コンパイル時の定数 (整数式または整数式に展開されたマクロ) でサイズを指定するか、上記のような初期化子を使用して、コンパイル時に配列サイズを知る必要があります。そこから配列サイズが計算されます。

C99 では可変長配列が導入されました。これは、次のようなランタイム値を使用して宣言できます。

void foo(int x)
{
  int arr[x];
  ...
}

通常の配列と同様に、VLA は定義後にサイズ変更できないことに注意してください。

または、 を使用して配列を動的に割り当てることもできmallocますが、上記の方法で配列を初期化することはできません。

int *foo = malloc(sizeof *foo * N); // where N is the number of elements

個々の要素に割り当てることもできます:

foo[0] = 5;
foo[1] = 4;
foo[2] = 3;
...

memcpyまたは、上記のように使用できます。free完了したら、配列に覚えておく必要があることに注意してください。

free(foo);

この方法で作成された配列は、以下を使用してサイズ変更できreallocます。

int *tmp = realloc(foo, sizeof *foo * NEW_NUMBER_OF_ELEMENTS);
if (tmp)
  foo = tmp;

reallocbackの結果を に代入しないのはなぜfooですか? 操作が失敗すると、reallocNULL が返されます。これが発生し、結果を に代入するとfoo、既に割り当てたメモリを追跡できなくなり、メモリ リークが発生します。

C99 では、配列リテラル構文が導入されました。あなたは次のようなものを書くことができます

int *foo = (int[]){1,2,3,4,5};

foo次に、配列のようにインデックスを付けます。

printf("foo[%d] = %d\n", i, foo[i]);

の内容を変更できないことは確かですがfoo[i]、文字列リテラルの内容を変更しようとする試みが定義されていないのと同様です (ただし、その章と節は見つかりませんでした)。

于 2012-03-20T12:54:36.350 に答える
4

配列ではなく、型そのものを再初期化することはできません。
初期化は、変数の作成時に同じステートメントで変数に値を指定する 1 回限りのイベントです。

それぞれに新しい値を割り当てる必要がある場合は、配列を明示的にループして再度埋めることができます。または、すべての要素を特定の値に設定するか、特定の要素をそれにコピーするためにmemset()
またはmemcpy()
を 使用します。

于 2012-03-20T04:48:11.127 に答える
1

初期化 (もしあれば) は、変数の作成時に行う必要があります。コンパイル時に、コンパイラがこの値を変数に割り当てるためです。この行の後のその他の割り当ては、実行時にのみ実行されます。

あなたの場合、作成中に配列を初期化できます。次に何らかの値を割り当てるときは、「初期化」を意味しません。むしろ、実行時の割り当てのみです。

要素を動的に作成して保存する場合は、ポインターを使用してそれを行うことができます。

于 2012-03-20T04:53:20.547 に答える