C++入門シリーズの第5回です。変数はメモリ内のアドレスに存在します。ポインタと参照は、変数を間接的に参照する2つの方法で、どちらもC++では不可欠です。
変数のアドレス#
すべての変数はメモリアドレスに存在します。&で取得します:
int a = 42;
std::cout << &a << '\n'; // 例: 0x7ffee2b3d5accppポインタ#
ポインタはアドレスを格納します。何を指すかを表す型があります:
int a = 42;
int* p = &a; // pはaを指すcpp*でデリファレンスして読み書きします:
std::cout << *p << '\n'; // 42
*p = 100; // aを変更
std::cout << a << '\n'; // 100cppヌルポインタ#
ポインタはアドレスを持たないこともできます。キーワードnullptrを使い、デリファレンス前に必ずチェックします:
int* p = nullptr;
if (p != nullptr) {
std::cout << *p << '\n';
}cppnullptrのデリファレンスはクラッシュです — ヌルポインタ参照。
参照#
参照は既存の変数のエイリアスです。一度バインドされ、再バインドできません:
int a = 42;
int& r = a; // rはaの別名
r = 100; // aを変更
std::cout << a << '\n'; // 100cpp参照はnullにはならず、後から別の変数を指すこともできません。
関数への渡し方#
参照渡しで、コピーなしに呼び出し元の変数を変更します:
void increment(int& x) {
++x;
}
int main() {
int a = 5;
increment(a);
std::cout << a << '\n'; // 6
}cppコピーを避けたいが変更はしない場合はconst int&を使います:
void describe(const std::string& s) {
std::cout << s.size() << '\n';
}cppポインタと参照の比較#
| ポインタ | 参照 | |
|---|---|---|
| nullにできる | 可(nullptr) | 不可 |
| 対象を変更できる | 可 | 不可 |
| デリファレンスが必要 | 可(*) | 暗黙 |
| 再代入 | p = &other | 不可 |
現代のC++では、関数パラメータには参照を優先します。nullや再バインドが必要な場合はポインタを使います。
結論#
ポインタも参照も変数に間接的にアクセスします。安全性には参照を優先し、nullや再バインドが必要ならポインタを使います。シリーズ次回はクラスとオブジェクトです。