ノートンを叩いて砕く話の続き
windowsでC++のコンパイラ(g++)を使っています。
今回はノートンは関係ないですし、何も叩いて砕きません。
ポインタ遊び第二弾です。
こんな感じの配列を用意しました。で、何がしたいかというと、char(1バイト変数型)で定義されたはずのこの配列を先頭から順に4バイト変数型であるint型(あくまで私の環境では4バイト)で読み込んでやろうという話です。
(なぜ4バイトのintで読むのに配列の長さを5にしたかというのはまた後の話。今はhoge[4]は無いものだと思って大丈夫です。)
どうやって?
→もちろんポインタで
まずint型用のポインタを用意します。
(補足)なぜhoge_pではなくhogege_pという名前にしたかというと、やはり型が違うためhogeとは明確に区別したかっただけです。もしかしたらこの先、配列hogeの先頭を指すポインタが必要になるかもしれませんからね、その時のためにhoge_pという名前はとっておきます(結局使いませんでしたけど)。(hogege_pじゃなくて他のもっといい名前あっただろ.........)
で、あとは分かりますね。このhogege_pに配列hogeの先頭のアドレスを代入します。
"hoge"はhoge[0]を指す「char型を指すポインタ型」であるので、int*型への型キャストが必要になります。
全体のコードは次の通り。
出力は
61fe13
1
となりました。
あと、対照実験とは言えないですけど、似たようなことをしました。
まぁ、hogeの初期化の内容を変えただけです。
出力は次のようになりました。
61fe13
16777216
これで何がわかるかというと、int型は若いアドレス(?)を低い桁に持ってきているということです。自分がその辺の知識が無いのが悪いんですが、あくまで私の環境ではこうだというだけであることに注意してください。
例えば、
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ||
0x600000 | ←hoge[0] | ||||||||
0x600001 | ←hoge[1] | ||||||||
0x600002 | ←hoge[2] | ||||||||
0x600003 | ←hoge[3] |
こんなふうにアドレスとビットが並んでいて、&piyo == 0x600000であるようなint型変数piyoがあったとするなら、0x600000の8から0x600003の1という方向にビットを、2^0, 2^1, 2^2, ... 2^31という順番で読んでいくわけですね。(同一アドレス内のビットの方向までは知りませんが、すくなくともアドレスの方向はこれで合ってるはずです。)
実際のアドレスは違いますが、要は
の場合は上の表の0x600000の8のビットが1で他すべてが0だったため、hogege_pの指す値が1になって、
の場合は上の表の0x600003の8のビットが1で他がすべて0だったため、hogege_pの指す値が2^24 = 16777216になった、ということですね。
先に「char(1バイト変数型)で定義されたはずのこの配列を先頭から順に4バイト変数型であるint型(あくまで私の環境では4バイト)で読み込」みたい、と述べましたが、実は真の目的は違います。
本当は、配列hogeを先頭からじゃなくて2番目や3番目から読んでメチャクチャな数字を出したかっただけです。
なのでアドレスを1バイトずらす必要があります。hogege_pにアドレスを代入するところで、こうします。
"hoge"は正しくはhoge[0]を指すポインタですので、(hoge + 1)はhoge[0]のアドレスの次のアドレス、つまりhoge[1]を指すわけです。
こうして晴れて、真の目的は達成されるわけです。
出力は
61fe13
1
61fe14
16777216
となりました。メチャクチャな数字を出したいと言いましたが、ここでは理解してもらうために、さっき表で説明した内容で理解できる数値を出力するようにしました。
なにか疑問や修正すべきことなど何でも良いので、あればTwitterの西園寺やきしゃも(このブログのアイコンと同じアイコンのアカウント)まで