2016-08-23 5 views
0

二つのタイプ:C++の文字列リテラルの種類と宣言

char* str1 = "string 1"; 

char str2[] = "string 2"; 

私のコンパイラは私がconstのchar型からエラー 間違って変換して最初の宣言を使用することはできません。 [8]をchar *に変換する。大丈夫に見える、このような バージョン:コンパイラによって渡さ

const char* str1 = "string 1"; 

私の理解を明確にしてください。 私は、両方のバージョンを宣言すると、 main()、 最初のもの(const char *) - 唯一のポインタはスタックに割り当てられ、データセグメントのあるアドレスで初期化されます。 2番目のバージョン(char []) - シンボルの配列全体がスタックに置かれます。

文字列リテラルには常にconst char []型があります。 はconst char * depricatedを使用していますか? C互換のみのために?

ここで、各バージョンには文字列が格納されますか?

+3

CとC++は異なる言語です!同じ行動を期待する理由は何ですか?これはCに関するものではありません。 – Olaf

+3

これは面白いです、 '' string 1 ''は' const char [8] 'ではなく' const char [9] 'です。 – aschepler

+1

@aschepler面白くない - 普通。 9文字を構成する末尾の0文字があります。 – Aconcagua

答えて

2
char* str1 = "string 1"; 

これはC++ 98のように廃止され、そしてリテラル文字列を変更できないようにC++ 11のよう悪い形成されています。変更すると、未定義の動作になります。

はこれを回避するには、標準では、それは 彼/彼女はそれを修正してはならないことを実現するプログラマせず、後に修正される可能性がありますように、変更可能 charポインタに代入禁止しています。

char str2[] = "string 2"; 

各文字がスタックに格納されているのに対し、はい、これは、文字の配列を割り当てられました。

const char* str1 = "string 1"; 

これは推奨されていない、それはcharポインタにリテラル文字列を割り当てるために推奨される方法(唯一の方法)です。ここではstr1constの文字を指しています。つまり、変更することはできません。したがって、コンパイラはcharが改変されないことを強制するので、どこかで使用することは安全です。

ここでは、str1がスタックに格納され、読み取り専用メモリに格納されている場合とされていない場合があります(これは実装定義です)。

+0

"' char * str1 = "string 1"; 'C++ 11では非推奨です。 'いいえ、これはC++ 98では非推奨で、C++ 11では_ill-formed_です。 – cpplearner

+0

@cpplearner info: – Rakete1111

2

char str2[] = "string 2";

"string 2"読み出し専用メモリに格納された文字列リテラルconst char[9]あります。

char str2[]は、読み書き可能メモリにchar配列(初期化サイズから控除したサイズ)を割り当てます。

=は、文字列リテラルを使用して、文字配列を初期化します("string 2"コンテンツのmemcpy)。

私は原則を意味します。最適化で生成された実際のマシンコードは、文字列リテラルのmemcpyよりも些細な意味でstr2の内容を設定するという点で異なる場合があります。

- ここでは実際の文字列リテラルメモリアドレスを取得しようとしていますが、その1つはconstなので、char *に割り当てる/キャストしないでください。

const char* str1const char *const char[]からキャスト、OK働く有効である必要があります(コンパイル時に元の配列のサイズへのアクセス権を持っていない限り、彼らは、ほとんど同じものです、そして、ポインタの変種はサイズレスダムダウンバージョンです)。

+0

ありがとうございますので、バージョンconst char *はデータセグメントの文字列リテラルへの実際のポインタです。 2番目のバージョン - char []は、文字列リテラルから、ちょうど右手の値から文字をコピーすることによって初期化された配列です。それが正しいか? – amigo421

関連する問題