void*型のポインタ変数dを他のint*型やdouble*型にキャストしてみよう

ソーラー「まずは


void*型のポインタ変数dにint型の変数aのアドレスを格納するプログラムを


ご覧ください

👇


#include <stdio.h>


int main() {


int a = 1;


void* d;


d = &a;//🌞void*型のポインタ変数dにint型の変数aのアドレスを格納しています


printf("%p\n", d);



return 0;


}


プログラムの実行結果


012FFC78


C:\Users\solar\source\repos\Project6\Debug\Project6.exe (プロセス 23752) は、コード 0 で終了しました。

このウィンドウを閉じるには、任意のキーを押してください...



ソーラー「このプログラムでは


void* 型のポインタ変数dに


int型の変数aの管理する4バイトのメモリのうちの先頭のメモリのアドレス


012FFC78



格納されています


int型の変数aに格納されている数値データ1


にアクセスするには


(int*)d


おこない


void* 型のポインタ変数dに格納されているアドレス


012FFC78



int*型にキャストする(積み替える)


つまり


int*型の形式で格納し直すことになります


int*型の形式で格納されているアドレスデータは


🌞その格納されているアドレスデータのメモリを先頭とする(int型に対応する)

4バイトのメモリ領域にアクセスする情報も🌞


保有することになります


(void*型の形式で格納されているアドレスデータは


その格納されているアドレスデータを先頭とするメモリ領域にアクセスする情報をもっていません)


ですので


(int*)d


おこない


void* 型のポインタ変数dに格納されているアドレス


012FFC78



int*型にキャスト(積み替える)


した場合


(int*)dにアスタリスク*


をくっつけた


*(int*)d



int*dに格納されているアドレスデータ012FFC78のメモリを先頭とする(int型に対応する)

4バイトのメモリ領域にアクセスし


4バイトのメモリ領域にわたって格納されている


数値データ1

(0000000 0000000 0000000 00000001)

すなわち


int型の変数aに格納されている数値データ1を表すことになります


そのプログラムはこちらです

👇


#include <stdio.h>


int main() {


int a = 1;


void* d;


d = &a;//🌞void*型のポインタ変数dにint型の変数aのアドレスを格納しています


printf("%p\n", d);


printf("%d\n", *(int*)d);


return 0;


}


プログラムの実行結果


0133FB28

1


C:\Users\solar\source\repos\Project6\Debug\Project6.exe (プロセス 27428) は、コード 0 で終了しました。

このウィンドウを閉じるには、任意のキーを押してください...


ソーラー「


(int*)d


おこない


void* 型のポインタ変数dに格納されているアドレス


012FFC78



int*型にキャスト(積み替える)


したので



*(int*)d



int*dに格納されているアドレスデータ012FFC78のメモリを先頭とする(int型に対応する)

4バイトのメモリ領域にアクセスすることができることになったので


printf("%d\n", *(int*)d);


を実行して


4バイトのメモリ領域にわたって格納されている


数値データ1

(0000000 0000000 0000000 00000001)

すなわち


を表示することができたね


アレサ「

void*型の形式で格納されているアドレスデータを


int*型にキャストすると


int*型の形式で格納し直されたアドレスデータは


🌞その格納されているアドレスデータのメモリを先頭とする(int型に対応する)

4バイトのメモリ領域にアクセスする情報も🌞


保有することになる


のですか」


ソーラー「そうなんだ


だから


void*型の形式で格納されているアドレスデータを


double*型にキャストすると


double*型の形式で格納し直されたアドレスデータは


🌞その格納されているアドレスデータのメモリを先頭とする(int型に対応する)

💖バイトのメモリ領域にアクセスする情報も🌞


保有することになるんだよ」


次のプログラムをみてよ

👇


#include <stdio.h>


int main() {


double a = 1.2345;


void* d;


d = &a;//🌞void*型のポインタ変数dにdouble型の変数aのアドレスを格納しています


printf("%p\n", d);


printf("%f\n", *(double*)d);//👈🌞実数値をprintf出力表示するときは%f出力変換指定子を用いることに注意してね


return 0;


}


プログラムの実行結果


0079F8D4

1.234500


C:\Users\solar\source\repos\Project6\Debug\Project6.exe (プロセス 21124) は、コード 0 で終了しました。

このウィンドウを閉じるには、任意のキーを押してください...



ソーラー「


(double*)d


おこない


void* 型のポインタ変数dに格納されているアドレス


0079F8D4



double*型にキャスト(積み替える)


したので



*(double*)d



(double*)dに格納されているアドレスデータ0079F8D4のメモリを先頭とする(double型に対応する)

8バイトのメモリ領域にアクセスすることができることになったので


printf("%d\n", *(double*)d);


を実行して


8バイトのメモリ領域にわたって格納されている


数値データ1.2345


を表示することができているんだ


このように


void* 型のポインタ変数dにアドレスを格納しておいて


void* 型のポインタ変数dを


char*型にキャストした場合は


*(char*)d



そのアドレスを先頭とする(charに対応する)1バイトのメモリ領域に


アクセスすることになり



int*型にキャストした場合は


*(int*)d



そのアドレスを先頭とする(intに対応する)4バイトのメモリ領域に


アクセスすることになり



double*型にキャストした場合は


*(double*)d



そのアドレスを先頭とする(doubleに対応する)8バイトのメモリ領域に


アクセスすることになるんだね



でもちょっとまって


ふたたび



void*型のポインタ変数dにint型の変数aのアドレスを格納するプログラムを


ご覧ください

👇


#include <stdio.h>


int main() {


int a = 1;


void* d;


d = &a;//🌞void*型のポインタ変数dにint型の変数aのアドレスを格納しています


printf("%p\n", d);



return 0;


}


プログラムの実行結果


012FFC78


C:\Users\solar\source\repos\Project6\Debug\Project6.exe (プロセス 23752) は、コード 0 で終了しました。

このウィンドウを閉じるには、任意のキーを押してください...



ソーラー「このプログラムでは


void* 型のポインタ変数dに


int型の変数aの管理する4バイトのメモリのうちの先頭のメモリのアドレス


012FFC78



格納されています


int型の変数aに格納されている数値データ1


にアクセスするには


(int*)d


おこない


void* 型のポインタ変数dに格納されているアドレス


012FFC78



int*型にキャストする(積み替える)


つまり


int*型の形式で格納し直すことになります


int*型の形式で格納されているアドレスデータは


🌞その格納されているアドレスデータのメモリを先頭とする(int型に対応する)

4バイトのメモリ領域にアクセスする情報も🌞


保有することになります


(void*型の形式で格納されているアドレスデータは


その格納されているアドレスデータを先頭とするメモリ領域にアクセスする情報をもっていません)


ですので


(int*)d


おこない


void* 型のポインタ変数dに格納されているアドレス


012FFC78



int*型にキャスト(積み替える)


した場合


(int*)dにアスタリスク*


をくっつけた


*(int*)d



int*dに格納されているアドレスデータ012FFC78のメモリを先頭とする(int型に対応する)

4バイトのメモリ領域にアクセスし


4バイトのメモリ領域にわたって格納されている


数値データ1

(0000000 0000000 0000000 00000001)

すなわち


int型の変数aに格納されている数値データ1を表すことになります


そのプログラムはこちらです

👇


#include <stdio.h>


int main() {


int a = 1;


void* d;


d = &a;//🌞void*型のポインタ変数dにint型の変数aのアドレスを格納しています


printf("%p\n", d);


printf("%d\n", *(int*)d);


return 0;


}


プログラムの実行結果


0133FB28

1


C:\Users\solar\source\repos\Project6\Debug\Project6.exe (プロセス 27428) は、コード 0 で終了しました。

このウィンドウを閉じるには、任意のキーを押してください...



ソーラー「

だったら


このプログラムで


(int*)d


の代わりに


(double*)d


おこない


void* 型のポインタ変数dに格納されているアドレス


012FFC78



double*型にキャスト(積み替える)


した場合


(double*)dにアスタリスク*


をくっつけた


*(double*)d



(double*)dに格納されているアドレスデータ012FFC78のメモリを先頭とする(double型に対応する)

8バイトのメモリ領域にアクセスすることになるよね


つまり


*(double*)d



(double*)dに格納されているアドレスデータ012FFC78のメモリを先頭とする(double型に対応する)

8バイトのメモリ領域に格納されているデータを


表すことになるんだ


この場合


アドレスデータ012FFC78のメモリを先頭とする



4バイトのメモリ領域には


数値データ1

(0000000 0000000 0000000 00000001)


格納されているけど


つづく


4バイトのメモリ領域には


よくわからないデータが格納されています


ですので


*(double*)d



(double*)dに格納されているアドレスデータ012FFC78のメモリを先頭とする(double型に対応する)

8バイトのメモリ領域に格納されているデータを


表すことになるんだけど


何がなんだかよくわからないデータが表示されることになります


そのプログラムはこちらです

👇



#include <stdio.h>


int main() {


int a = 1;


void* d;


d = &a;//🌞void*型のポインタ変数dにint型の変数aのアドレスを格納しています


printf("%p\n", d);


printf("%f\n", *(double*)d);//👈🌞実数値をprintf出力表示するときは%f出力変換指定子を用いることに注意してね


return 0;


}


プログラムの実行結果


004FFD60

-92559592117432005122443784192846119323651547398128430475116544.000000


C:\Users\solar\source\repos\Project6\Debug\Project6.exe (プロセス 5744) は、コード 0 で終了しました。

このウィンドウを閉じるには、任意のキーを押してください...


ソーラー「おおっ


予想に反して


ものすごく変なデータが表示されたあ


だから


void* 型のポインタ変数dに


int型の変数を代入して


int型の変数に格納されているデータにアクセスしたい場合は


void* 型のポインタ変数dをint* 型にキャストする




void* 型のポインタ変数dに


double型の変数を代入して


double型の変数に格納されているデータにアクセスしたい場合は


void* 型のポインタ変数dをdouble* 型にキャストする


というように


アクセスしたいメモリ領域にあわせて


キャストに用いる型を選ぶ必要があるんだね」





  • Xで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る