14

これらの2行のコードは同じ結果を達成しますか?関数にこれらの行がある場合、どちらの場合も文字列はスタックに格納されますか?コードの最初の行でnullターミネータを宣言する必要がないことを除けば、一方を他方の上に使用する必要がある強い理由はありますか?

char  s[] = "string";
char* s   = "string\0";
4

3 に答える 3

29

いいえ、これら2つの行は同じ結果を達成しません。

char s[] = "string"その結果、7バイトの変更可能な配列が作成され、最初はコンテンツで埋められます's' 't' 'r' 'i' 'n' 'g' '\0'(実行時にすべて文字列リテラルからコピーされます)。

char *s = "string"結果として、文字列リテラルの「文字列」を含む読み取り専用メモリへのポインタが生成されます。

文字列の内容を変更したい場合は、最初の方法が唯一の方法です。文字列への読み取り専用アクセスのみが必要な場合は、文字列をコピーする必要がないため、2番目のアクセスはわずかに高速になります。


どちらの場合も、文字列リテラルでnullターミネータを指定する必要はありません。コンパイラは、終了 "に遭遇したときに、それを処理します。

于 2010-10-29T11:41:57.390 に答える
4

これら2つの違い:

char a[] = "string";
char* b = "string";

つまり、aは実際にはスタック上の静的配列であり、bは定数へのポインターです。aのコンテンツは変更できますが、bは変更できません。

于 2010-10-29T11:42:37.433 に答える
3

他の回答に加えて*s、プログラムフローの後半で変数を変更できない理由を説明しようと思います。

概念的には、プログラムがメモリにロードされると、3つの領域(セグメント)があります。

  • コードセグメント:プログラムのテキストはここに保存されます(読み取り専用領域です)
  • データセグメント:事前定義された値を持ち、変更可能なグローバル変数または静的変数が含まれます
  • スタックセグメント:ここでは、呼び出されたときに関数がロードされます。関数からのリターンアドレスとローカル変数を含むすべての関数呼び出しに対してスタックにプッシュされる値のセット(スタックフレーム)。

あなたの場合、s[]変数は関数内のローカル変数(配列)でありmain()、値で初期化されます"string"。したがって、スタックに格納され、変更できます。

変数は、コードセグメントにある定数である*sのアドレスを指すポインタ です。"string\0"読み取り専用領域であるため、その内容を変更することはできません。

于 2017-06-26T22:21:59.863 に答える