web-dev-qa-db-ja.com

Cでのchar配列宣言と初期化

私はなぜこれがCで許可されていないのか興味がありました:

char myarray[4];

myarray = "abc";

そしてこれは許可されています:

char myarray[4] = "abc";

最初のケースではstrcpyを使用する必要があることを知っています。

char myarray[4];

strcpy(myarray, "abc");

しかし、宣言とその後の初期化が許可されず、宣言と同時初期化が許可されるのはなぜですか? Cプログラムのメモリマッピングに関連していますか?

ありがとう!

21
Alexey Pimenov

これは、最初のコードスニペットが初期化ではなく、assignmentを実行していないためです:

char myarray[4] = "abc";  // Initialization.

myarray = "abc";          // Assignment.

また、配列はCでは直接割り当てられません。

名前myarrayは、実際には最初の要素(&myarray[0])、これは lvalue ではないため、割り当てのターゲットにできません。

37

はい、これは一種の言語の矛盾です。

myarray = "abc";の「=」は割り当てです(配列は基本的に定数ポインターであるため機能しません)が、char myarray[4] = "abc";では配列の初期化です。 「後期初期化」の方法はありません。

このルールを覚えておいてください。

4
Vlad

これは、同じ構文が異なる意味を持つ(別の場所で)別のCの例です。これらの2つのケースでは構文が異なるべきであると主張できるかもしれませんが、それはそうです。これは、「許可されていない」ということではなく、2番目のことは何か異なることを意味するということです(「ポインターの割り当て」を意味します)。

1
davep
myarray = "abc";

...は、「abc」上のポインターをmyarrayポインターに割り当てることです。

これは、myarrayバッファを「abc」で埋めていません。

Strcpy()を使用せずにmyarrayバッファを手動で埋めたい場合は、次を使用できます。

myarray[0] = 'a', myarray[1] = 'b', myarray[2] = 'c', myarray[3] = 0;

または

char *ptr = myarray;
*ptr++ = 'a', *ptr++ = 'b', *ptr++ = 'c', *ptr = 0;

あなたの質問は、ポインターとバッファー(配列)の違いについてです。 Cが各種類にどのように対処するかを理解していただければ幸いです。

1
pierre

これらは本当に異なる2つのケースだと思います。最初のケースでは、メモリはコンパイル時に割り当てられ、初期化されます。第二に-ランタイムで。

0
Nofate