ポインタとキャストの関係について
ポインタを宣言するときとりあえず変数の型とそろえて
int a = 0;
int *hoge_p = &a;
のように宣言しています。
この型宣言をなぜ揃えるのか。
hoge_p の型と a の型はどんな関係があるのか。
そして、サンプルコードを見るとアドレスを表示するときに
printf("%p",(void*)hoge_p);
というのを見かけます。
これが何を表しているのかを考えます。
実験してみる
# include <stdio.h>
int main(void)
{
// 中身がint型のポインタ hoge_p
int a = 0;
int *hoge_p = &a;
// 中身がint型?double型?のポインタ foo_p
double *foo_p = &a; // warning!!!
// それぞれのポインタの中身の大きさを表示する
printf("%d\n",(int)sizeof(*hoge_p));
printf("%d\n",(int)sizeof(*foo_p));
// 試しに色々な型でキャストしてみる
printf("%p\n",hoge_p); // 1
printf("%p\n",(int*)hoge_p); // 2
printf("%p\n",(double*)hoge_p); // 3
return 0;
}
これを実行すると
warning: initialization from incompatible pointer type
という警告が出ます。これを無視し実行してみると
私のパソコンでは
4
8
0061FF14
0061FF14
0061FF14
となります。
8という結果からポインタが中身の変数の型を
int型からdouble型に置き換えたと考えられます。(警告を無視したため)
つまり、なぜポインタの型と変数の型を
同じにするかは中身の型を揃えるためでした。
次にコードの1,2,3の部分について考えると出力は同じですが
1はhoge_p の先頭アドレスを表示している
2はhoge_p の中身がint型の変数(a)の先頭アドレスを表示している
3はhoge_p の中身がdouble型の変数(a)の先頭アドレスを表示している
(注 void* は汎用的なキャストで任意の型に変わる。)
と考えられます。
よくみる表現はこのようなことをしていた?ということです。
人間から見れば、この出力は同じですが
コンピュータから見れば上の解釈をしていることになります。
人間からするととても奇妙な解釈であると思います。