[932] Re:774RRさん、お返事ありがとうございます。
投稿者:774RR
2007/02/20 02:13:25
御意。およそ何がしたいのか意図がつかめないので、あの程度のコメントとなった次第。
あえてもっと詳しくコメントしてみるテスト
char buf[10]; は char が 10 個の配列、の意味。10個の内訳は
buf[0] .. buf[9] の10個 // 0から開始するので
ということは buf[10] は存在しないので、その中身を使ってはならない。
もちろん buf[-1] や buf[-2] や buf[11] や buf[498914] 等も全部ダメ。
char *cp=buf; は char *cp=&buf[0]; の短縮形であるため cp は buf[0] を指す。
んでそもそも buf[1] ってのは *(&buf[0]+1) のこと。
cp[1] も *(cp+1) のこと。
だからこの場合 cp[1] と buf[1] は同じところを意味する。
cp=&buf[1]; とか cp=buf+1; とかすれば cp は1つずれるわけだ。
なのでこうすると、 cp がずれてる分 cp[2] と buf[3] が同じところを意味する。
当然 cp[9] は buf[10] に相当するので前述のごとくこれも使っちゃダメ。
あと配列外をアクセスするとダメってことの解説。
多くの場合配列外に相当するメモリ/アドレス表現は存在していたりする。
存在するけど、そこは他の変数だったり、他の重要な情報だったりする。
ということで配列外をアクセスすると他の変数を壊す=遠くでクラッシュしたりする。
エラーを OS/CPU が検出してくれる場合もあるが、多くは検出なしにメモリを壊すだけ。
OS/CPU が検出をサボってよい代わりにプログラマが細心の注意を払え、ってのが C/C++
その分、正常に動いている限りにおいては他言語より高速なプログラムが書けたりする。
これとは別に
配列外のオブジェクトの中身を見てはならない (buf[10] はダメ) んだけど
配列直後に限りアドレスを計算しても良い (&buf[10] はOK) という決まりがある。
for (i=0; i<10; ++i) buf[i]=0; と書いてよいごとくに
for (cp=&buf[0]; cp<&buf[10]; ++cp) *cp=0; と書いてよいということ。
直後以外はダメ。なので &buf[11] や &buf[-1] は計算しちゃダメ。
計算したらエラーになるかもしれないし、
エラーにならずにおかしな値が得られるかもしれない。
C/C++ は「やっちゃだめ」なことをしたときに「何が起こるかわからない」のだ。
これを「鼻から悪魔が飛び出してもかまわない」と表現したりする。
何が起こるかわからない=エラー発生、ならまだ良かったりする。
何が起こるかわからない=一見、プログラマの期待通りに動いたりする、こともある。
後者は怖いよー。