int main()
{
char *x = "HelloWorld";
char y[] = "HelloWorld";
x[0] = 'Z';
//y[0] = 'M';
return 0;
}
上記のプログラムでは、HelloWorld
は読み取り専用セクション(つまり、文字列テーブル)にあります。 x
はその読み取り専用セクションを指しているため、その値を変更しようとしても未定義の動作になります。
ただし、y
はスタックに割り当てられ、HelloWorld
はそのメモリにコピーされます。そのため、yの変更は正常に機能します。 文字列リテラル:ポインタと文字配列
これが私の質問です:
次のプログラムでは、両方のchar *arr
およびchar arr[]
は、コンテンツが変更された場合にセグメンテーション違反を引き起こします。
void function(char arr[])
//void function(char *arr)
{
arr[0] = 'X';
}
int main()
{
function("MyString");
return 0;
}
あなたの知識を共有してください。
関数パラメーターリスト内では、char arr[]
はchar *arr
と完全に同等であるため、定義のペアと宣言のペアは同等です。
void function(char arr[]) { ... }
void function(char *arr) { ... }
void function(char arr[]);
void function(char *arr);
問題は呼び出しコンテキストです。関数に文字列リテラルを提供しました。文字列リテラルは変更できません。関数が、与えられた文字列リテラルを変更しようとしました。プログラムが未定義の動作を呼び出し、クラッシュしました。すべて完全にコーシャ。
文字列リテラルをstatic const char literal[] = "string literal";
であるかのように扱い、変更を試みないでください。
function("MyString");
と類似しています
char *s = "MyString";
function(s);
"MyString"
はどちらの場合も文字列リテラルであり、どちらの場合も文字列は変更できません。
function("MyString");
文字列リテラルのアドレスをfunction
に引数として渡します。
char * arr;上記のステートメントは、arrが文字ポインターであり、1文字または文字列を指すことができることを意味します
&char arr [];上記のステートメントは、arrは文字列であり、できるだけ多くの文字または1文字を格納できるが、常に '\ 0'文字でカウントされるため、文字列になることを意味します(たとえば、char arr [] = "a"はchar arr [] = {'a'、 '\ 0'})
ただし、呼び出された関数のパラメーターとして使用する場合、渡される文字列は形式引数に文字ごとに格納され、違いはありません。