#はじめに
私の苦手なポインタについて、基本的な使い方、値渡し、ポインタ渡しについて解説する。
#対象者
- 未経験新卒エンジニア
- C/C++ 入門者
- ポインタがイマイチ理解できていない方
#ポインタとは
・ポインタとはアドレスを記憶する変数である。
・例えば、型をpaとしたときpa*の型は、paへの"ポインタ"である。
と、言われてもピンと来ない人が大半だと思う。下記のコードを見てほしい。
int a = 100;
int* pa = &a; // paはaのアドレスを保持:&はアドレス演算子
cout << *pa << endl; // 出力結果:100(変数にアスタリスクをつけることによってアドレスの中身を参照できるようになる)
cout << &a << endl; // 出力結果:0x61ff08 (アドレスが出力される)※実行環境によって出力結果は異なる
・一行目:aの箱(変数)に100を代入
・二行目:100が代入されているaの"アドレス"をpaに代入している。
※アドレスを取得するには、アドレス演算子である&を使用する
つまり、アドレスの受け渡しで値の受け渡しができるということである。
次は通常の値の受け渡し方法とポインタを利用した値の受け渡し方法解説する。
#値渡しとポインタ渡し
###値渡し
値渡しを一言でいうと、値がコピーされて引数に渡される。
実際にコードで確認する。
#include <bits/stdc++.h>
using namespace std;
int add(int a, int b) {
a = a + b;
return(a);
}
int main(void) {
int x = 100;
int y = 200;
int total = add(x, y); // 引数として100と200をint a、int bにコピーする
cout << total << endl; // 出力結果:300
}
これはaddの引数にxとyを指定して受け取る引数にコピーさせている。
今回の例ではサイズが小さいので問題はないが、サイズの大きい型が引数である場合、プログラム実行結果に大きな差が現れてしまう。
また、int型は4バイトであるので、今回は8バイト、コピー分も含めると16バイトを使用してしまうことになる。
次はこれをポインタで行うとどうなるか確認していく。
###ポインタ渡し
値渡しでの処理をポインタ渡しで記述する。
#include <bits/stdc++.h>
using namespace std;
void add(int* a, int* b) {
*a = *a + *b;
cout << *a << endl; // 出力結果:300
}
int main(void) {
int x = 100;
int y = 200;
add(&x, &y); // 引数として「x」の"アドレス"と「y」の"アドレス"を設定する
}
- main関数のaddの引数としてxとyの"アドレス"を設定する。
- 呼び出されたadd関数は引数でアドレスを受け取り、その中身を参照する。
- 値渡しでは16バイトを使用していたが、今回のポインタ渡しでは8バイトで収まっている。
値渡しではxとyの値を"コピー"していたが、ポインタ渡しでは"アドレス"を参照することによってメモリの節約、処理速度の高速化につながっている。
#確認
最後に確認をしてみよう。
xとyの出力結果を考えてほしい。
#include <bits/stdc++.h>
using namespace std;
void add(int* a , int* b) {
*a = *a + *b;
}
int main(void) {
int x = 100;
int y = 200;
add(&x, &y);
cout << x << endl; // 出力結果x:
cout << y << endl; // 出力結果y:
}
答え:xは300、yは200
yが200というのは誰でもわかるだろう。
では、なぜ、xが300になるのか。
それはadd関数の引数として"アドレス"で渡しているからである。
100と200を指すアドレスを渡してxのアドレスにxのアドレスの中身(100) + yのアドレスの中身(200)を*aに加算し代入している。
add関数内のaはxの"アドレス"を保持しているのでaの値を書き換えるとxの値も書き換わる。
#まとめ
今回はポインタについて簡単に解説してみました。
初めてのQiita投稿でしたが、わかりやすく伝えるというのは本当に難しいですね。
しかし、それと同時に楽しさもありました。自分自身のアウトプットにもなるため、今後も少しずつ記事を投稿していきたいと思います。
#最後に
私自身、まだまだ理解が追いついていない部分のため、誤った記載がありましたら、ご一報いただけると幸いです。
#参考文献/参考サイト
ビャーネ・ストラウストラップ[柴田望洋 訳] プログラミング言語C++ [第4版]
C++ 値渡し、ポインタ渡し、参照渡しを使い分けよう
【 https://qiita.com/agate-pris/items/05948b7d33f3e88b8967 】
手を動かしてさくさく理解する C言語/C++ ポインタ入門
【 http://vivi.dyndns.org/tech/cpp/pointer.html 】