2016-12-29 7 views
3

私は(12)のことを見てきました:Cでは、char *とchar s []の違いは他の型にも当てはまりますか?

char s[] = { 'a', 'b', 'c', '\0' }; 
char t[] = { 'a', 'b', 'c' }; 

そして次:

char s[] = "abc"; 
char t[3] = "abc"; 

はを効果的に同じです

char *word = "abc"; 
word[0] = 'd'; 

場所word読み出し専用メモリでは、不正なメモリ操作word[0] = 'd'がエラーになります。

charの場合のみですか?

int array[] = {1, 2, 3}; 
int *p = array; 
p[0] = 0; // No error here 
array[1] = 1; // or here 
+2

はいこれらの動作は文字配列と文字列リテラルに固有です。詳細については、C標準をお読みください。 – kaylum

+2

なぜあなたの質問に投票しているのか分かりません。 – UrbiJr

+1

あなたの最初のチャンクでは、 't [3] =" abc "は' char t [3] = "abc"でなければなりません。あなたの2番目のチャンクでも同様です。 –

答えて

7

それだけ文字列リテラルに適用されます。私はこのような何かをするとき、私はエラーを取得することはできません。

文字列リテラルは暗黙的に、char[N]型の配列オブジェクトを作成します。この配列オブジェクトには、リテラルに文字が含まれ、その後に終端文字「\0'」が含まれます。このオブジェクトは静的な記憶期間を持ち、読み取り専用です。 (これは歴史的な理由のために、constではないが、それを修正しようとすると、未定義の動作をしている。)

あなたが書くとき:あなたはポインタオブジェクトとしてptrを作成している

char *ptr = "abc"; 

をし、を指すように初期化します読み取り専用静的配列​​を含む(あなたはconstとしてそれを定義することによって、それを修正しようとする試みを防ぐことができます。)

をあなたが書くとき:タイプchar[4]のあなたは、配列オブジェクトとしてarrを作成している

char arr[] = "abc"; 

、およびコピー内容を静的な読み取り専用配列をそのオブジェクトに挿入します。 arrは読み取り専用ではありません。

int array[] = {1, 2, 3}; 

は、配列オブジェクトを作成し、図のように初期化します。文字列リテラルのように動作する「整数配列リテラル」はありません。 (そこほとんどある - 「複合リテラル」を参照してください - しかし、それらは、文字列リテラルと同じ読み取り専用の意味を持っていません。)このこと

注:

char t[3] = "abc"; 

は特別ですcase:配列が文字列リテラルで初期化され、終了する余地がない場合'\0'、null以外の文字のみが配列にコピーされます。その結果、tには文字列が含まれず、終了していない文字列のみが含まれます。これは特にあなたの質問には関係ありません。

+0

ありがとう!これはちょっと話題ですが、あなたはこう書いています: "[' char * ptr = "abc" ']を' const'と定義して修正しようとする試みを防ぐことができます。 'char * ptr =" abc "'( 'const'なし)を変更しようとすると、すでに失敗しています。編集:私はおそらく、私とは別のコンピュータに 'const'接頭辞(?)のないプログラムの可能性を見落としているでしょう。 – awalllllll

+1

'char * s =" abc "と書くと; s [0] = 'A'; 'おそらくランタイムクラッシュが発生するでしょう。 (実際には動作は未定義ですが、実装によってはそれをキャッチできない場合があります)。代わりに 'const char * s =" abc "; s [0] = 'A'; 'エラーはコンパイラによって捕捉されます。エラーを早期にキャッチすることは(ほとんど)いつもより良いことです。 –

+0

美しい、ありがとう。 – awalllllll

1

他の配列型の文字列リテラルには正確な類似点はありません。しかし、あなたはそれが読み取り専用メモリに配置され、試みは後に(それを修正するために行われた場合、プログラムをクラッシュする可能性がありますチャンスがありリテラル

const int *p = (const int []) { 1, 2, 3 }; 

const修飾化合物を使用して、やや近くに来ることができますそれはまさにそのようなものです。文字列リテラルとのもう1つの類似点は、const修飾された複合リテラルが記憶域を共有する可能性があることです。

複合リテラルと文字列リテラルの明白な違いは、文字列リテラルは常に静的記憶期間を持ち、ブロックレベル複合リテラルは自動記憶期間を持つという点です。

+1

非常に良い答えです。 – chux

関連する問題