これらの2行のコードは同じ結果を達成しますか?関数にこれらの行がある場合、どちらの場合も文字列はスタックに格納されますか?コードの最初の行でnullターミネータを宣言する必要がないことを除けば、一方を他方の上に使用する必要がある強い理由はありますか?
char s[] = "string";
char* s = "string\0";
いいえ、これら2つの行は同じ結果を達成しません。
char s[] = "string"
その結果、7バイトの変更可能な配列が作成され、最初はコンテンツで埋められます's' 't' 'r' 'i' 'n' 'g' '\0'
(実行時にすべて文字列リテラルからコピーされます)。
char *s = "string"
結果として、文字列リテラルの「文字列」を含む読み取り専用メモリへのポインタが生成されます。
文字列の内容を変更したい場合は、最初の方法が唯一の方法です。文字列への読み取り専用アクセスのみが必要な場合は、文字列をコピーする必要がないため、2番目のアクセスはわずかに高速になります。
どちらの場合も、文字列リテラルでnullターミネータを指定する必要はありません。コンパイラは、終了 "に遭遇したときに、それを処理します。
これら2つの違い:
char a[] = "string";
char* b = "string";
つまり、aは実際にはスタック上の静的配列であり、bは定数へのポインターです。aのコンテンツは変更できますが、bは変更できません。
他の回答に加えて*s
、プログラムフローの後半で変数を変更できない理由を説明しようと思います。
概念的には、プログラムがメモリにロードされると、3つの領域(セグメント)があります。
あなたの場合、s[]
変数は関数内のローカル変数(配列)でありmain()
、値で初期化されます"string"
。したがって、スタックに格納され、変更できます。
変数は、コードセグメントにある定数である*s
のアドレスを指すポインタ です。"string\0"
読み取り専用領域であるため、その内容を変更することはできません。