No.16430![]() |
K&Rを読んでいて(ポインタと配列) 投稿者---lala(2004/08/30 20:49:36) |
||
Cの勉強をしていて、幾つか関係の本を読んだ後に、今K&Rを読んでいます。 ポインタの所で疑問が出たので質問します。 char amessage[]="now is the time" char *pmessage ="now is the time" の違いについて説明してあったのですが(p127)、ここで後者のpmessageについて『文字列の内容を変更しようとすると不定になる』とあるのですが、これは前者のように一定のメモリを指してるのではなく"now is the time"というのが一つの塊となっているという事ですか?ここが少し分かりません。ご指導お願いします |
No.16431![]() |
Re:K&Rを読んでいて(ポインタと配列) 投稿者---Sciggepy(2004/08/30 21:11:35) |
||
処理系依存ということではないでしょうか。 私の処理系で試したところ、 #include <stdio.h> int main(void) { char *s="abcdef"; s[0]='g'; printf("%s",s); return 0; } 結果: Boland C/C++ Compiler 5.5.1 gbcdef gcc 3.2.3(MinGW) Segmentation fault(異常終了)となりました。 BCCでは、"abcdef"は静的領域に置かれ、書き込み可能になっていますが、gccではコード領域に置かれるようです。 |
No.16433![]() |
Re:K&Rを読んでいて(ポインタと配列) 投稿者---lala(2004/08/30 21:33:50) |
||
処理系依存の為不定となってしまうということですか。自分だけでは気づけませんでした。 ありがとうございます。もっと勉強して色んな原因に気付けるよう努力します。 |
No.16434![]() |
Re:K&Rを読んでいて(ポインタと配列) 投稿者---シャノン(2004/08/30 21:34:36) |
||
> Cの勉強をしていて、幾つか関係の本を読んだ後に、今K&Rを読んでいます。 >ポインタの所で疑問が出たので質問します。 > char amessage[]="now is the time" > char *pmessage ="now is the time" >の違いについて説明してあったのですが(p127)、ここで後者のpmessageについて『文字列の内容を変更しようとすると不定になる』とあるのですが、これは前者のように一定のメモリを指してるのではなく"now is the time"というのが一つの塊となっているという事ですか?ここが少し分かりません。ご指導お願いします わかりやすく言えば、char[] の宣言と char* の宣言は同一ではなく、 後者の変更はしてはいけませんよ、ということです。 なぜ変更してはいけないかと言うと、変更したときの振る舞いが C 言語の規格に定められていないからです。 これが「不定になる」ということです。 振る舞いが不定とはどういうことかといいますと、 決められていないのですから、コンパイラはどんなことをする コードを生成してもいいわけです。 あたかも char[] と同じように振舞うのも合法ですし、 突然プログラムが不正終了しても合法ですし、 ハードディスクをフォーマットしても合法ですし、 家が火事になっても文句は言えません。 |
No.16435![]() |
Re:K&Rを読んでいて(ポインタと配列) 投稿者---シャノン(2004/08/30 21:36:02) |
||
>なぜ変更してはいけないかと言うと、変更したときの振る舞いが >C 言語の規格に定められていないからです。 >これが「不定になる」ということです。 失礼。 「不定」ではなく「未定義」でした。 |
No.16436![]() |
Re:K&Rを読んでいて(ポインタと配列) 投稿者---lala(2004/08/30 21:41:11) |
||
Sciggepyさんの言っていた処理系依存も『未定義』って事から来るってことなんですね。いやはや、良くわかりました!!『未定義』->『処理系依存』か。お二人ともどうもありがとうございました。 |
No.16438![]() |
Re:K&Rを読んでいて(ポインタと配列) 投稿者---YuO(2004/08/30 22:13:03) |
||
>Sciggepyさんの言っていた処理系依存も『未定義』って事から来るってことなんですね。 >『未定義』->『処理系依存』か。 未定義と処理系依存は違います。 未定義というのはシャノンさんの書かれているように, 標準に振る舞いが定義されていないことで,根本的に間違ったことをした場合に起きます。 処理系は何をしても良いし,何もしなくても良いです。 処理系依存というのは,正しい振る舞いではあるものの,どのような振る舞いをするかは処理系に委ねられていて,その振る舞いは処理系が文書化する必要があるものです。 #文書化しなくて良い物は「未規定」と呼びます。 処理系依存の項目には,各型のサイズ,fprintf等で%pを使ったときの表示形式,malloc(0)に対する戻り値などがあります。 さて,問題の文字列リテラルの変更ですが,これは未定義の振る舞いとなっています。 #ISO/IEC 9899:1999 6.4.5 String literals / Paragraph.6 つまり,文字列リテラルを変更してはいけません。 |
No.16458![]() |
Re:K&Rを読んでいて(ポインタと配列) 投稿者---lala(2004/08/31 18:03:13) |
||
分かりました。皆さん分かりやすい説明ありがとうございました。 皆さんの意見を参考に大学で本を探して読んでみました。もっと勉強させていただきます。 |