この答えは良いですが、完全ではありません。
char * test = "abcdefghijklmnopqrstuvwxyz";
文字列リテラルchar[N]
は、静的記憶域期間 (プログラムの実行全体にわたって存在することを意味する) を持つ型の無名配列オブジェクトを参照します。ここN
で、 は文字列の長さに終端の'\0'
. このオブジェクトは ではありませんconst
が、変更しようとすると未定義の動作が発生します。(実装は、必要に応じて文字列リテラルを書き込み可能にすることができますが、最新のコンパイラのほとんどはそうではありません。)
上記の宣言は、タイプ の無名オブジェクトを作成char[27]
し、そのオブジェクトの最初の要素のアドレスを使用して を初期化しますtest
。したがって、代入のようなtest[5] = 'x'
配列を変更しようとすると、動作が未定義になります。通常、プログラムがクラッシュします。(リテラルは配列型の式であり、ほとんどのコンテキストで配列の最初の要素へのポインターに暗黙的に変換されるため、初期化ではアドレスが使用されます。)
C++ では、文字列リテラルは実際にconst
は であり、上記の宣言は無効になることに注意してください。C または C++ では、consttest
へのポインターとして宣言するのが最善です。 char
const char *test = "abcdefghijklmnopqrstuvwxyz";
そのため、 を介して配列を変更しようとすると、コンパイラから警告が表示されますtest
。
(C 文字列リテラルはconst
歴史的な理由によるものではありません。1989 年の ANSI C 標準より前には、const
キーワードは存在しませんでした。あなたのような宣言で使用することを要求すると、より安全なコードが作成されますが、既存のコードを変更する必要がありました。 ANSI 委員会が回避しようとしたこと.文字列リテラルはそうでconst
なくても. .)-Wwrite-strings
const
参照する文字列を変更できるようにしたい場合はtest
、次のように定義できます。
char test[] = "abcdefghijklmnopqrstuvwxyz";
コンパイラはイニシャライザを調べて、test
必要なサイズを決定します。この場合、test
タイプは になりますchar[27]
。文字列リテラルは引き続き匿名のほとんど読み取り専用の配列オブジェクトを参照しますが、その値は にコピーされtest
ます。(配列オブジェクトを初期化するために使用される初期化子の文字列リテラルは、配列がポインターに「減衰」しないコンテキストの 1 つです。その他は、それが単項&
またはのオペランドである場合sizeof
です。)無名配列の場合、コンパイラはそれを最適化して削除する場合があります。
この場合、それ自体は、指定した 26 文字とターミネータtest
を含む配列です。'\0'
その配列の有効期間は、test
宣言されている場所によって異なりますが、これは問題になる場合とそうでない場合があります。たとえば、次のようにします。
char *func(void) {
char test[] = "abcdefghijklmnopqrstuvwxyz";
return test; /* BAD IDEA */
}
呼び出し元は、もはや存在しないものへのポインターを受け取ります。が定義されているスコープ外の配列を参照する必要がある場合はtest
、 として定義するか、static
を使用して割り当てることができますmalloc
。
char *test = malloc(27);
if (test == NULL) {
/* error handling */
}
strcpy(test, "abcdefghijklmnopqrstuvwxyz";
そのため、配列は を呼び出すまで存在し続けますfree()
。非標準strdup()
関数がこれを行います (これは POSIX で定義されていますが、ISO C では定義されていません)。
test
宣言方法に応じて、ポインターまたは配列のいずれかになる可能性があることに注意してください。文字列関数に渡す場合test
、または を取る関数に渡す場合char*
、それは問題ではありませんが、 がポインターか配列sizeof test
かによって動作が大きく異なります。test
comp.lang.c FAQは優れています。セクション 8 では文字と文字列について説明し、質問 8.5 は質問 1.32 を示しています。これはあなたの特定の質問に対応しています。セクション 6 では、配列とポインターの間の混乱しがちな関係について説明します。