ここで何が起こっているのかを理解するには、次の 2 つの言語規則が重要です。
- 配列は代入できません。
- 配列は、その最初の要素へのポインターに変換できます。
文字列リテラルのようなものを理解することも重要"Sunstroke"
です。これは定数文字の静的配列であり、文字列のすべての文字を最後にターミネータで保持するのに十分な大きさです。したがって、この場合、これはconst char[10]
配列であり、9 つの文字の後にゼロ値のターミネータが続きます。staticであるため、配列はプログラムの存続期間中、メモリ内のどこかに格納されます。
char a[] = "Sunstroke";
これにより、ローカル配列が作成され、文字列リテラルから文字をコピーして初期化されます。
char *b = "Coldwave";
これにより、ポインターが作成され、リテラル自体を指すように初期化されます。これは危険であることに注意してください: リテラルは ですconst
が、ポインターはそうではないため、リテラルを変更しようとするコードを記述して、未定義の動作を与えることができます。この変換は推奨されていない (確かに C++ では、C についてはわかりません) ため、コンパイラは警告を表示する必要があります。できる限りすべてのコンパイラ警告を有効にしましたね。
a = "Coldwave";
これは配列の再割り当てを試みますが、配列は割り当て可能でないため失敗します。そうでない理由は特にありません。それがまさに言語が進化した方法です。
b = "Sunstroke";
これにより、ポインターが別のリテラルを指すように再割り当てされます。const
それは問題ありません(上記の欠如を除いて)。
文字列を操作する必要がある場合は、次のようにします。
- C では、必要に応じて十分な大きさの配列を慎重に作成し、ライブラリ関数
<string.h>
(または独自の手作りコード) を使用してそれらの配列内の文字を操作する必要があります。
- C++ では、
std::string
クラスを使用してメモリ管理、割り当てなどを処理します。