LoginSignup
0
0

More than 3 years have passed since last update.

奇妙なキャストについて

Last updated at Posted at 2019-09-03

ポインタとキャストの関係について

ポインタを宣言するときとりあえず変数の型とそろえて
 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* は汎用的なキャストで任意の型に変わる。)

と考えられます。
よくみる表現はこのようなことをしていた?ということです。

人間から見れば、この出力は同じですが
コンピュータから見れば上の解釈をしていることになります。
人間からするととても奇妙な解釈であると思います。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0