C++ with Windows API講習/ポインタ
概要
本章では、ポインタを通してアドレスの使い方を学びます。
C++の中でも低層に位置する機能ではありますが、かなりややこしい構文を使います。
重要語
ポインタ
アドレスを保存する変数
間接参照
アドレスを変数のように扱うこと
値渡し
数値データをそのまま引数にすること
ポインタ渡し
データを指すポインタを引数にすること
必要語
アドレス
メモリ内の位置を表す数値
関数
結果を返す、動作のまとまり
引数
関数に渡す値
ポインタ
まずは以下のプログラムを実行してみましょう。
ポインタ
#include <Windows.h>
#include <string>
int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) {
//100で初期化
int a=100;
//int型へのポインタ
int* ptr;
//aのアドレスを代入する
ptr = &a;
//ここでの*ptrはaと同じ意味になる
MessageBoxW(NULL, std::to_wstring(*ptr).c_str(), L"(*ptr)の値", MB_OK);
//a = 200;と同じ
*ptr = 200;
//aが書き換えられている
MessageBoxW(NULL, std::to_wstring(a).c_str(), L"aの値", MB_OK);
return 0;
}
ポインタの宣言
アドレスを保存する変数のことを、ポインタといいます。
ポインタは型名* ポインタ名
という構文で宣言します。
型名には、そのポインタが指す値の型を書きます。
ポインタの型
C++の変数には型がありますが、メモリには型がありません。
そして、値の符号化方法は型によって違います。
別の型として読み出せば、全く異なる意味になってしまいます。
ここで、ポインタが値の型を表すことで、読み書き時に型を間違える事故を防げます。
また、int* ptr;
で宣言した変数を、int
型へのポインタptr
と呼びます。
変数のアドレス
さて、ポインタに入れるためのアドレスはどうやって取得するのでしょうか。
多くのC++の変数はメモリ上にあり、それぞれにアドレスがあります。
アドレスを取得するには、&変数名
という構文を用います。
上の例文では、int
型変数a
のアドレスを、int
型へのポインタptr
に代入しています。
間接参照
ポインタに入っているアドレスは、変数のように扱うことができます。
間接参照
#include <Windows.h>
#include <string>
int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) {
//通常のint型変数
int a;
//int型の変数を指すポインタ
int* ptr;
//aのアドレスを代入する
ptr = &a;
//std::wstringはアドレスを受け取らないのでint型にキャストする
MessageBoxW(NULL, std::to_wstring((int)ptr).c_str(), L"アドレス", MB_OK);
return 0;
}
構文
*ポインタ名
で、ポインタが指すメモリを変数のように扱うことができます。
例文では、ptr
が指すメモリをa
も使っています。
そのため、*ptr
はa
と同じように扱うことができます。
ポインタ渡し
コンピュータの関数の引数にできるのは、数値だけです。
int
型などであれば、そのまま渡すことができます。
しかし、std::wstring
型のようなデータは、そのまま渡すことができません。
ですから、コンピュータの関数の引数の渡し方には2種類があります。
値渡し
先ほど述べた、int
型のほかに、double
型などの数値型は、そのまま引数にすることができます。
このことを、値渡しといいます。
ポインタ渡し
一方、文字列型のような、数値1つで表せない型は、一度メモリに保存し、そのアドレスを引数とします。
こちらの方法を、ポインタ渡しといいます。