あなたのコメントからエヴァン・リーに行きます(「文字列も一種の配列であり、ポインターで初期化されます。したがって、配列もこの方法で初期化する必要があります。」)。インストラクターが実際にあなたにこれを言った場合、彼は物事について混乱しているので、私は新しいインストラクターを見つけることを真剣に考えます.
文字列リテラルは配列式です。リテラル「Hello」は、char
( const char
C++ では) の 6 要素配列です。文字列リテラルは、プログラムの存続期間にわたってメモリが割り当てられるような方法で格納されます。このメモリは、プラットフォームに応じて、読み取り専用である場合とそうでない場合があります。文字列リテラルの内容を変更しようとしたときの動作はundefinedです。つまり、segfault が発生したり、文字列が変更されたり、その他のことが起こる可能性があります。
sizeof
配列式がまたは 単項演算子のオペランドとして以外のコンテキストに現れる場合、&
または宣言で別の配列を初期化するために使用される文字列リテラルである場合、式の型は "N -要素T
" へのポインタ "の配列でT
あり、式の値は配列の最初の要素のアドレスです。
そのため、次のように書くことができます
char *foo = "This is a test";
文字列リテラル"This is a test"
は、タイプ "15 要素の配列 " の配列式char
です。sizeof
or演算子のオペランドではなく、 の&
別の配列を初期化するために使用されていないためchar
、式の型は「へのポインタchar
」になり、最初の文字のアドレスが に割り当てられfoo
ます。比較すると、
char foo[] = "This is a test";
;の配列foo
として宣言します。サイズは初期化文字列 (15 文字) のサイズから計算され、文字列リテラルの内容が にコピーされます。 char
foo
文字列は配列式です。中括弧で囲まれた値のリストは ではありません。
int *foo = {1, 2, 3};
の 3 要素配列を作成せずint
、最初の要素のアドレスを に割り当てfoo
ます。代わりに、これを正しく読んでいる場合、これは制約違反である必要があります。
6.7.9 初期化の
制約
2 初期化子は、初期化されるエンティティに含まれていないオブジェクトに値を提供しようと試みてはなりません。
C99 では、複合リテラルと呼ばれるものを次のように使用できます。
int *foo = (int []) {1, 2, 3};
キャスト式(int [])
が必要です。これにより、 の新しい 3 要素配列が作成int
され、最初の要素のアドレスが に割り当てられfoo
ます。文字列リテラルとは異なり、このような複合リテラルは、囲んでいるブロック1の間だけ存在します。IOW、次のようなことをした場合
int *foo = NULL;
if (condition())
{
foo = (int []){1, 2, 3};
// do stuff
}
// do more stuff
が指す無名配列オブジェクトは、ブロックfoo
内にのみ存在します。ブロックが終了すると、配列は存在しなくなり、の値は無効になりif
ます。 if
foo
1. 複合リテラルがファイル スコープ (関数の外部) で定義されている場合static
、期間があり、プログラムの存続期間中存在します。