は、上記の宣言は、タイプchar[27]
のように匿名のオブジェクトを作成し、test
を初期化するために、そのオブジェクトの最初の要素のアドレスを使用しています。したがって、test[5] = 'x'
のような割り当ては配列の変更を試み、未定義の動作をします。通常、プログラムがクラッシュします。 (リテラルは配列型の式であり、ほとんどのコンテキストでは配列の最初の要素へのポインタに暗黙的に変換されるため、初期化ではアドレスが使用されます。)
C++では、文字列リテラルは実際にはconst
であり、上記の宣言は無効であることに注意してください。あなたはtest
経由で配列を変更しようとするので、コンパイラは警告を表示します
const char *test = "abcdefghijklmnopqrstuvwxyz";
:CまたはC++のいずれかで、それはのconstchar
へのポインタとしてtest
を宣言するのが最善です。
(歴史的な理由から、Cの文字列リテラルはconst
ではありません)1989 ANSI C規格の前には、const
キーワードは存在しませんでした。あなたのような宣言で使用することを要求すると、既存のコードを修正する必要がありますが、ANSI委員会が避けようとしたことです。のように、文字列リテラルはconst
でなければなりません。gccを使用している場合、-Wwrite-strings
オプションは、リテラルはconst
- gccが非適合になります)
の文字列を変更したい場合はコンパイラはtest
をする必要がありますどのように大きな決定するために初期化子を見
char test[] = "abcdefghijklmnopqrstuvwxyz";
:は、あなたがこのようにそれを定義することができ、を指します。この場合、test
はchar[27]
となります。文字列リテラルは、依然として匿名の主に読み取り専用の配列オブジェクトを参照しますが、その値はで、test
にがコピーされています。 (配列オブジェクトを初期化するために使用される初期化子の文字列リテラルは、配列がポインタに対して "崩壊"しないコンテキストの1つであり、他のものは単項のオペランドの場合です&
またはsizeof
)匿名配列への参照では、コンパイラはそれを最適化するかもしれません。
この場合、test
自体は、指定した26文字と、'\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では、配列とポインタの間のしばしば混乱する関係について説明します。
私はそれを言いたくはありませんが、これは実際にCのFAQのどこかにあるはずです...スタックオーバーフローで何十何千もの他の時間が既に要求されています。 – ephemient
これまでに聞いたことがあれば申し訳ありませんが、答えが見つかりませんでした。私は実際に関数のリファレンスとすべてを最初に読んだのですが、私が間違っていたことは実際には分かりませんでした。このようなC FAQに私を指摘できますか? – fresskoma
@ x3ro:誰も4年間でC FAQについてあなたに答えましたか? [comp.lang.c FAQ](http://www.c-faq.com/)は優れています。セクション8は文字と文字列をカバーし、質問8.5は質問1.32を指し、特定の質問に対処します。 –