3

次の 2 行のコードを検討してください。

const char *ptr = "Hello";
char arr[] = "Hello";

ポインター定義の場合、"Hello"文字列リテラルは本質的に不変ですが、ptr変数自体は変更され、別のアドレスを保持できます。

配列定義の場合、"Hello"文字列リテラルは配列の場所にコピーされますが、別の場所を指すarr ことはできません。ただし、配列が保持する文字列は可変であるため、変更できます。

次に、次の 2 行のコードについて考えてみましょう。

const char * const ptr = "Hello";
const char arr[] = "Hello";

ここでは、両方の文字列が修飾子の結果として不変になっていますが、もっと興味深いのは、定数ポインターとして定義されているため、別のアドレスを指すことはできないということです。const charptr

これらの 2 行のコードは同じ動作になりますか? 最終結果が同じである場合、実装に理論的な違いはありますか?配列?

4

5 に答える 5

1

配列定義の場合、"Hello"文字列リテラルは配列の場所にコピーされますが、arr は別の場所を指すことはできません

文字列は配列にコピーされず、文字列リテラル (暗黙的にポインターに変換できる) のように読み取り専用の場所に作成および格納されることはありませんが、

char arr[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

標準が言うように:

文字型の配列は、文字列リテラルまたは UTF-8 文字列リテラルで初期化することができ、オプションで中括弧で囲みます。

また、配列は「ポイント」しません。配列はポインターではありません。

これらの 2 行のコードは同じ動作になりますか?

いいえ、同じ理由でまったく異なるタイプがあります。

ポインターメソッドは、ポインター自体に加えて文字列を保持するために匿名配列にメモリを割り当てますが、配列メソッドは配列にのみメモリを割り当てますか?

はい、同じ文字列リテラルが使用されている場合、「匿名」で作成された配列を別の場所で再度使用できます(ただし、一般的に、コンパイラが実際に何をするかはわかりません)。

これらの配列の要素が適切な値を持っている場合、これらの配列が異なるかどうかは指定されていません。

繰り返しますが、2 行目は配列を初期化するためのシンタックス シュガーです。

于 2013-04-29T21:46:50.447 に答える