第10回 他の変数からも書き換え可能なポインタの実装
はじめに
前回は、特定の処理をまとめて再利用するための関数について学びました。
関数を使用すると、処理を分割して整理できます。
しかし、関数を使う中で次のような問題が発生することがあります。
例えば、
void change(int x)
{
x = 100;
}
という関数を作り、
int num = 10;
change(num);
と呼び出した場合、元のnumの値は変化しません。
これは、関数へ渡された値がコピーされているためです。
では、どうすれば別の場所から変数そのものを操作できるのでしょうか。
そこで使用するのがポインタです。
今回の到達目標
- 変数のアドレスについて理解する。
- ポインタとは何かを説明できる。
- ポインタを宣言できる。
- アドレス演算子
&を使用できる。 - 間接参照演算子
*を使用できる。 - ポインタを使って値を変更できる。
変数のアドレス
これまで、変数には値が保存されると説明してきました。
例えば、
int num = 10;
では、
num
┌────┐
│ 10 │
└────┘
のように、変数numの中に10が保存されています。
しかし、コンピュータ内部では、変数はメモリ上の場所に保存されています。
その場所を表す番号をアドレスといいます。
イメージとしては、
メモリ
住所1000番地
┌────┐
│ 10 │
└────┘
のように、値だけではなく「どこに保存されているか」という情報も存在します。
アドレスを取得する
変数のアドレスを取得するには、&を使用します。
#include <iostream>
int main()
{
int num = 10;
std::cout << #
}
&numは、
変数
numが保存されている場所
を表します。
実行すると、メモリ上のアドレスが表示されます。
※アドレスの値は実行するたびに変化する場合があります。
ポインタとは
ポインタとは、アドレスを保存するための変数です。
通常の変数は値を保存します。
int num = 10;
一方、ポインタはアドレスを保存します。
int* ptr;
このように、型の後ろに*を付けて宣言します。
ポインタへアドレスを保存する
ポインタには、変数のアドレスを保存できます。
#include <iostream>
int main()
{
int num = 10;
int* ptr = #
std::cout << ptr;
}
この場合、
num
┌────┐
│ 10 │
└────┘
↑
│
ptr
のように、ptrはnumの場所を保存しています。
ポインタから値を取得する
ポインタが保存しているアドレスの値を取得するには、*を使用します。
これを間接参照といいます。
#include <iostream>
int main()
{
int num = 10;
int* ptr = #
std::cout << *ptr;
}
実行結果
10
ptrはnumの場所を保存しているため、
*ptr
と書くことで、その場所にある値を取得できます。
ポインタを使って値を変更する
ポインタを使用すると、保存先の値を変更できます。
#include <iostream>
int main()
{
int num = 10;
int* ptr = #
*ptr = 100;
std::cout << num;
}
実行結果
100
*ptrはnumそのものを指しているため、
*ptr = 100;
によってnumの値が変更されます。
変数とポインタの違い
通常の変数とポインタでは、保存しているものが違います。
種類
保存しているもの
通常の変数
値
ポインタ
アドレス
例えば、
int num = 10;
では、
num
↓
10
を保存しています。
一方、
int* ptr = #
では、
ptr
↓
numの場所
を保存しています。
ポインタを使う理由
ポインタを使用する大きな理由の一つは、別の場所から変数を操作できることです。
例えば、
void change(int* ptr)
{
*ptr = 100;
}
int main()
{
int num = 10;
change(&num);
std::cout << num;
}
実行結果
100
関数へアドレスを渡すことで、関数の中から元の変数を書き換えることができます。
ポインタ使用時の注意
ポインタには注意点があります。
例えば、
int* ptr;
だけでは、どこを指しているか決まっていません。
この状態で、
*ptr = 10;
のように使用すると、予期しない動作の原因になります。
ポインタを使用するときは、必ず有効なアドレスを保存してから利用しましょう。
nullptr
何も指していないポインタを表す場合は、nullptrを使用します。
int* ptr = nullptr;
nullptrは、
このポインタは現在どこも指していない
という意味です。
まとめ
今回は、アドレスを扱うためのポインタについて学びました。
- 変数はメモリ上の場所に保存されています。
- その場所を表すものがアドレスです。
- ポインタはアドレスを保存する変数です。
&を使用すると変数のアドレスを取得できます。*を使用するとポインタが指す場所の値を取得できます。- ポインタを使用すると、別の場所から変数の値を変更できます。
- ポインタを使用するときは、どの場所を指しているか注意する必要があります。
ポインタを理解することで、C++ではメモリを意識した高度なプログラムを書くことができます。
次回は、今回学んだポインタと配列がどのように関係しているのかを学びます。