char str[]とchar*strの違い
print ?
char* get_str(void) {
char str[] = {"abcd"}; return str;
}
char str[] = {"abcd"};配列であるにもかかわらず、ローカル変数であり、そのアドレスが解放された空間のアドレスであることを返すローカル文字配列を定義します.この関数は内部のローカル文字配列strのアドレスを返し、関数呼び出しが完了するとこの配列が破棄されるので、返されるポインタは破棄されたメモリを指します.この書き方は間違っています.
[cpp] view plain copy print ?
char* get_str(void) {
char *str = {"abcd"}; return str;
}
char* str = {"abcd"};文字列定数を定義しstrにアドレスを割り当てることを示します.この関数は文字列定数のアドレスを返しますが、このような文字列はすべてグローバルであり、コンパイル時にメモリが割り当てられており、プログラムが終了したときにのみ破棄されるので、そのアドレスを返すのは問題ありませんが、文字列定数の値を変更することはできません.
このstrはスタックの中にありますが、後ろの文字列は定数領域にあり、関数が戻るときは、まず定数領域のアドレスを返し、それから役割ドメインが終了し、strがスタックの中にある空間を解放します.
[cpp] view plain copy print ?
const char str[] = "abcd";//abcスタックに格納 const char *str = "abcd";//abcは、静的記憶領域 に記憶する.
正確に言えば、上の2つの「abc」「すべて静的ストレージ領域、すなわち定数領域に格納されています.定数領域は読み取り可能で書き込み不可です.したがって、定数領域を書き込みしようとする操作は違法です.もちろん、これは必ずしも書き込み不可ではありません.pe関連セクションの属性を変更するなど、定数領域のメモリ属性を変更するチャネルを使用して定数領域を読み書きすることができます.もちろん、これは現在無視できます..では、str[] = "abc";書いてもいいですか.答えはstr[]=「abc」です.定数領域のabcをスタックメモリにコピーする追加のコピープロセスがあるので、書くことができます.
要約:「」または「」に含まれるすべての文字、文字列は定数であり、スタックに格納されるべきです.char*str=“xxxx”であり、strはこの定数アドレスを指す.char str[]=「xxxx」で、strはスタック上で空間を申請し、定数コンテンツをコピーするので、ローカル変数です.
まず、配列とポインタは異なるデータ型であり、本質的な違いがある:char str[]=「abcd」; //sizeof(str) == 5 * sizeof(char) char * str = "abcd";//sizeof(str)==4(x 86)or 8(x 64)配列は自動的にポインタに変換でき、ポインタは配列に変換できません.
次に、文字列は文字ポインタに等しくなく、文字配列に等価です.前の項目に従って、文字列は自動的に文字ポインタに変換されます.
そして、「abcd」は「文字列定数」と呼ばれ、どのタイプの定数も右値(名前のない一時変数)であり、「abcd」を左値(名前のある変数)にしてこそ、「abcd」という文字列を修正することができる.char str[] = "abcd";//等号両端は同じデータ型で、右値は左値char*str=「abcd」となります.//等号の両端は異なるデータ型で、右端は自動的にchar*に変換され、strの名前が得られたが、「abcd」というchar配列には名前がない.
char*strはグローバル静的記憶領域に格納されているので、ローカル変数であるにもかかわらず関数が戻った後も正しい値を得ることができます!char str[]はスタックに格納されており、local variable、関数が戻った後、OSは空間を回収し、もう存在しないので、正しい結果は得られません!
char str[]="name";とchar str[5];str=「name」の違いはどこにあるのか、メモリ割り当ての観点から言えば、配列名が定数アドレス(ポインタ)であることを知っています.1つ目はなぜ正しいのか、2つ目はなぜ間違っているのか.
2つ目はまず配列を定義し、配列名strが配列に割り当てられた空間のヘッダアドレスであることを知るには、str=「name」は等号の両側タイプが一致しないエラーであるべきである.通常の定数には、変数が定数を指していない限り、メモリアドレスはありません.配列名がアドレス定数である場合、定数はもちろん再割り当ては許されません.「name」は文字列定数です.彼は定数ストレージ領域に格納されています.1つのポインタでしか変更できません.char*p;p="name"; 一般的にchar str[]=「name」;配列はスタック上の空間がコンパイラによって割り当てられ,コンテンツはユーザによって変更される.
char* get_str(void)
char str[] = {"abcd"};
}
char* get_str(void)
{
char str[] = {"abcd"};
return str;
}
char str[] = {"abcd"};配列であるにもかかわらず、ローカル変数であり、そのアドレスが解放された空間のアドレスであることを返すローカル文字配列を定義します.この関数は内部のローカル文字配列strのアドレスを返し、関数呼び出しが完了するとこの配列が破棄されるので、返されるポインタは破棄されたメモリを指します.この書き方は間違っています.
[cpp] view plain copy print ?
char* get_str(void)
char *str = {"abcd"};
}
char* get_str(void)
{
char *str = {"abcd"};
return str;
}
char* str = {"abcd"};文字列定数を定義しstrにアドレスを割り当てることを示します.この関数は文字列定数のアドレスを返しますが、このような文字列はすべてグローバルであり、コンパイル時にメモリが割り当てられており、プログラムが終了したときにのみ破棄されるので、そのアドレスを返すのは問題ありませんが、文字列定数の値を変更することはできません.
このstrはスタックの中にありますが、後ろの文字列は定数領域にあり、関数が戻るときは、まず定数領域のアドレスを返し、それから役割ドメインが終了し、strがスタックの中にある空間を解放します.
[cpp] view plain copy print ?
const char str[] = "abcd";//abcスタックに格納
const char str[] = "abcd"; //abc
const char *str = "abcd"; //abc
正確に言えば、上の2つの「abc」「すべて静的ストレージ領域、すなわち定数領域に格納されています.定数領域は読み取り可能で書き込み不可です.したがって、定数領域を書き込みしようとする操作は違法です.もちろん、これは必ずしも書き込み不可ではありません.pe関連セクションの属性を変更するなど、定数領域のメモリ属性を変更するチャネルを使用して定数領域を読み書きすることができます.もちろん、これは現在無視できます..では、str[] = "abc";書いてもいいですか.答えはstr[]=「abc」です.定数領域のabcをスタックメモリにコピーする追加のコピープロセスがあるので、書くことができます.
要約:「」または「」に含まれるすべての文字、文字列は定数であり、スタックに格納されるべきです.char*str=“xxxx”であり、strはこの定数アドレスを指す.char str[]=「xxxx」で、strはスタック上で空間を申請し、定数コンテンツをコピーするので、ローカル変数です.
まず、配列とポインタは異なるデータ型であり、本質的な違いがある:char str[]=「abcd」; //sizeof(str) == 5 * sizeof(char) char * str = "abcd";//sizeof(str)==4(x 86)or 8(x 64)配列は自動的にポインタに変換でき、ポインタは配列に変換できません.
次に、文字列は文字ポインタに等しくなく、文字配列に等価です.前の項目に従って、文字列は自動的に文字ポインタに変換されます.
そして、「abcd」は「文字列定数」と呼ばれ、どのタイプの定数も右値(名前のない一時変数)であり、「abcd」を左値(名前のある変数)にしてこそ、「abcd」という文字列を修正することができる.char str[] = "abcd";//等号両端は同じデータ型で、右値は左値char*str=「abcd」となります.//等号の両端は異なるデータ型で、右端は自動的にchar*に変換され、strの名前が得られたが、「abcd」というchar配列には名前がない.
char*strはグローバル静的記憶領域に格納されているので、ローカル変数であるにもかかわらず関数が戻った後も正しい値を得ることができます!char str[]はスタックに格納されており、local variable、関数が戻った後、OSは空間を回収し、もう存在しないので、正しい結果は得られません!
char str[]="name";とchar str[5];str=「name」の違いはどこにあるのか、メモリ割り当ての観点から言えば、配列名が定数アドレス(ポインタ)であることを知っています.1つ目はなぜ正しいのか、2つ目はなぜ間違っているのか.
2つ目はまず配列を定義し、配列名strが配列に割り当てられた空間のヘッダアドレスであることを知るには、str=「name」は等号の両側タイプが一致しないエラーであるべきである.通常の定数には、変数が定数を指していない限り、メモリアドレスはありません.配列名がアドレス定数である場合、定数はもちろん再割り当ては許されません.「name」は文字列定数です.彼は定数ストレージ領域に格納されています.1つのポインタでしか変更できません.char*p;p="name"; 一般的にchar str[]=「name」;配列はスタック上の空間がコンパイラによって割り当てられ,コンテンツはユーザによって変更される.