C++言語などでポインタと参照ってあるよな。どちらも変数のアドレスを指すらしいが、どう違うのでしょう。関数の引数に何かを渡すときにも使い分けがあるらしいのです。ポインタと参照の違いや特徴を、プログラマでもあるライターのwoinaryと一緒に解説していきます。

ライター/woinary

某社で社内向け業務システムの開発、運用を30年近くやっていたシステム屋さん。現在はフリーランス。ガジェットやゲーム、ラノベが大好きなおっさんです。

ポインタと参照の違いは?

image by iStockphoto

ポインタと参照はC++言語でプログラミングする際に出てくる言葉です。C++言語の元になったC言語からポインタがあります。その後、C++で参照が追加されたのです。どちらも変数や関数に関係する言葉ですが、使い分けが必要になります。その違いを見ていきましょう。

ポインタ:メモリ上のどこかを指すもの

まずは元々あったポインタからですが、その前に変数の解説をしましょう。変数は値を入れる箱のようなものと言われます。実際にはコンピュータのメモリの中に変数用の場所を用意して、その中に値をしまうのです。そのメモリ中の変数の場所の住所(アドレス)がポインタ

ポインタというとマウスポインタなどの矢印を思い浮かべるかと思います。メモリのある場所を指すコンピュータ内の矢印がポインタなのです。

参照:変数のアドレスを指すもの

参照は後から追加された考え方です。ポインタと似ていますが、ポインタにあった問題を解決したものになります。そこは後で詳しく触れますが、参照も変数を指すポインタのようなものです。ポインタとの最大の違いは足し引きできるかどうか。

ポインタは指している場所に数字を足し引きして指しているところを変更できます。一方、参照は変更ができないのです。なぜそうなっているかは、この後使い方を示しながら確認していきます。

参照かポインタか?関数での使い方がポイント

image by iStockphoto

プログラミングで関数を使う際、呼び出し元から値を渡すために使うのが引数です。この引数の渡し方がいくつかあります。この渡し方を考える際にポインタや参照が出てきますので、引数のポインタ渡しや参照渡しについて見ていきましょう。

\次のページで「関数の「値渡し」と「ポインタ渡し」の違い」を解説!/

関数の「値渡し」と「ポインタ渡し」の違い

関数に引数を渡すときに、その値をコピーして渡すのが「値渡し」です。プログラミング言語によって引数の渡し方は違いますが、C++言語では何も指定しなければ値渡しになります。値渡しの場合、コピーを渡すので関数の中で引数を変更しても元の変数には影響しません

一方、ポインタ渡しでは変数の値ではなくポインタを渡します。ポインタは変数のある場所を示す矢印ですね。そのため、関数の中でポインタの指す先を変更すると、元の変数の値も変わってしまいます値渡しは変数の中の値だけ渡し、ポインタ渡しは変数そのものを渡す、と考えてください。

ポインタ渡しと参照渡しの違い

関数には参照を渡すこともできます。参照も変数の場所を指す矢印だと説明しました。では、ポインタ渡しと参照渡しは何が違うのでしょう。どちらも変数そのものを渡している、という点は同じです。ただし、そのために使うのがポインタか参照かの違いがあります。それでは、もう少しポインタと参照の違いを見てみましょう。

配列とポインタ

ポインタと参照の違いとして、ポインタは指している先を変更できる、参照はできないと説明しました。その違いが一番関係するのが配列とポインタです。

配列とはある値を入れる箱を複数並べたもの。普通の変数が一軒家とすれば、配列はマンションやアパートです。普通の変数には1つの値しかしまえませんが、配列は部屋の数だけ値をしまうことができます。マンションの住所は1つですが、どの部屋を示すかを「○号室」と指定しますよね。これが添字です。配列の先頭を指すポインタをずらしていくとそれぞれの部屋を指すように変更できます。このように配列とポインタは深い関係があります。実際のプログラム例を以下に示します。

#include <iostream>
using namespace std;
int main(void){
   int array[5]; // 大きさ5の配列
   for (int i = 0; i < 5; i++) {
      array[i] = (i + 1) * 2; // 配列arrayを初期化(2, 4, 6, 8, 10)
   }
   cout << array[1] << endl; // 2番目の値「4」を出力

   int *pointer = array; // arrayの先頭を指すポインタ変数pointerを宣言
   cout << *(pointer + 4) << endl; // array[4]と同じ意味。5番目の「10」を表示
}

クラスと参照

C++の変数には数値や文字などの種類があります。これがデータ型。データ型にもいろいろありますが、大きく分けるとプリミティブ型と参照型があります。数字や文字はプリミティブ型、クラスは参照型です。クラスとはデータや関数をまとめたもののことをいいます。

変数の参照はプリミティブ型の変数にも使えますが、クラスとの関係が深いものです。クラスから作った変数(インスタンス)を関数に渡す際には参照を使います。これが参照渡し。クラスを関数に渡す場合に、値渡しも使うことができます。しかし、通常クラスに使うのは参照渡しです。

\次のページで「ポインタと参照の特徴、速度は?使い分けは?」を解説!/

ポインタと参照の特徴、速度は?使い分けは?

image by iStockphoto

ポインタと参照の違い、関数での使い分けについて見てきましたが、実際の違いはどうなのでしょう。簡単に両者を比較します。

ポインタ渡しと参照渡し、どちらが速い?

ポインタ渡しと参照渡し、スピードに違いがあるのでしょうか。その前に値渡しです。値渡しは変数の中の値をコピーするので時間がかかります。数値1つだけであれば大きな違いはありませんが、複雑なクラスでは時間がかかります。

一方、実際に計測してもポインタ渡しと参照渡しは大きな違いはないようです。スピードからどちらかを選ぶという必要性はありませんね。

ケース別、ポインタ渡しと参照渡しの使い分け

スピードに違いがないのであれば、どのように使い分けるのでしょう。まず、プリミティブ型の場合です。関数の中で変更を元の変数に影響しないようにする場合は値渡しを使います。一方、関数の中での変更を反映したい場合はポインタ渡しか参照渡しです。どちらでも良いのですが、迷った場合には参照渡しを使いましょう。その理由は後で説明します。

クラスの場合は参照渡しを使うことが多いです。ポインタ渡しは使わないようにしましょう。

ポインタは危ない?nullとは何か

C++言語や元になったC言語ではポインタがありますが、ポインタは難しいとか危ないと聞いたことはないですか。実はポインタの扱いには注意が必要なのです。

例えば、大きさ5の配列をポインタを使ってアクセスした場合、6番目の値にアクセスできてしまいます。もちろん、大きさ5なので、6番目はありませんのでエラーです。ポインタは指す先を自由に変更できる分、正しい場所を指しているか注意が必要なのですね

また、ポインタがどこも指していないことを示す「null」というものがあります。このnullの先の値を見てしまうとエラーです。このようにポインタを使う場合、その指している先がnullなのかどうかを常に意識する必要があります。参照は必ず何かの変数を指しており、また指す先を変更できないので、nullやアクセスできないところを指してしまう心配はありませんポインタの良い点を残しつつ改良したのが参照なのです。

C++以外のポインタと参照

ポインタには危ない部分もあるので、他の言語ではポインタがないものも多いです。例えば、C++から発展したJava言語にはポインタはありません。一方、マイクロソフトが開発したRust言語やGoogleが開発したGo言語にはポインタがあります。ただ、これらの言語ではポインタを渡すことを「参照渡し」と呼ぶので注意が必要です。

同じ用語で似たような概念でもプログラミング言語によって考え方に違いがあります。他の言語で似たような言葉が出てきた場合、同じだろうと考えずに確認してください。

\次のページで「ポインタはメモリ内の場所を示す、参照は変数の別名、用途に応じて使い分けよう」を解説!/

ポインタはメモリ内の場所を示す、参照は変数の別名、用途に応じて使い分けよう

ポインタは変数のある場所を指し示すものです。参照も変数を指しますが、変数に別名をつけているという考え方もあります。その違いは、ポインタは指している先を変更できますが、参照はできません。ポインタは元の変数とは違う変数を指すこともできますが、参照は変更できないので「別名をつけている」という考え方になります。

ポインタは強力で自由度が高い反面、危険な部分も。そのため他の言語ではポインタがないものが多いです。必要がなければ安全な参照を使い、どうしても必要な部分はポインタを使う、という使い分けが必要になります。

" /> ポインタと参照の違いとは?C++での違いや使い分けをプログラマーがわかりやすく解説 – Study-Z
IT・プログラミング雑学

ポインタと参照の違いとは?C++での違いや使い分けをプログラマーがわかりやすく解説

C++言語などでポインタと参照ってあるよな。どちらも変数のアドレスを指すらしいが、どう違うのでしょう。関数の引数に何かを渡すときにも使い分けがあるらしいのです。ポインタと参照の違いや特徴を、プログラマでもあるライターのwoinaryと一緒に解説していきます。

ライター/woinary

某社で社内向け業務システムの開発、運用を30年近くやっていたシステム屋さん。現在はフリーランス。ガジェットやゲーム、ラノベが大好きなおっさんです。

ポインタと参照の違いは?

image by iStockphoto

ポインタと参照はC++言語でプログラミングする際に出てくる言葉です。C++言語の元になったC言語からポインタがあります。その後、C++で参照が追加されたのです。どちらも変数や関数に関係する言葉ですが、使い分けが必要になります。その違いを見ていきましょう。

ポインタ:メモリ上のどこかを指すもの

まずは元々あったポインタからですが、その前に変数の解説をしましょう。変数は値を入れる箱のようなものと言われます。実際にはコンピュータのメモリの中に変数用の場所を用意して、その中に値をしまうのです。そのメモリ中の変数の場所の住所(アドレス)がポインタ

ポインタというとマウスポインタなどの矢印を思い浮かべるかと思います。メモリのある場所を指すコンピュータ内の矢印がポインタなのです。

参照:変数のアドレスを指すもの

参照は後から追加された考え方です。ポインタと似ていますが、ポインタにあった問題を解決したものになります。そこは後で詳しく触れますが、参照も変数を指すポインタのようなものです。ポインタとの最大の違いは足し引きできるかどうか。

ポインタは指している場所に数字を足し引きして指しているところを変更できます。一方、参照は変更ができないのです。なぜそうなっているかは、この後使い方を示しながら確認していきます。

参照かポインタか?関数での使い方がポイント

image by iStockphoto

プログラミングで関数を使う際、呼び出し元から値を渡すために使うのが引数です。この引数の渡し方がいくつかあります。この渡し方を考える際にポインタや参照が出てきますので、引数のポインタ渡しや参照渡しについて見ていきましょう。

\次のページで「関数の「値渡し」と「ポインタ渡し」の違い」を解説!/

次のページを読む
1 2 3 4
Share: