C++のポインタと参照の違いって何なの？

# はじめに
これはプログラム初心者の投稿者が書き綴っているため多分に**間違いが含まれている**可能性があります。
その際はご指摘いただけると幸いです。
(2021/04/24 12:43:47に可読性を上げるために実行結果も載せました。)

今回は軽く**ポインタ**と**参照**についての説明とその**違い**についての説明をしていこうと思います。
この投稿でなんとなく違いを分かっていただけたら嬉しいです。

# 目次
**1**.そもそもなぜこの2つを扱うのか
**2**.ポインタとは？
**3**.参照とは？
**4**.ポインタと参照の違い
**5**.まとめ
# そもそもなぜこの2つを扱うのか
**より多くのコードを書いたり構造が複雑化した際**に「使いこなしておいた方が良いと思ったから」
という自分の経験則です。

# ポインタとは？
ポインタとは分かりやすく言えば**自分の連絡先**のようなものです。
人は仲良くしたい人とL〇NE等を交換する事って多いと思います。(そうじゃない人はごめんなさい。)
そう、その際に自分から**ポインタ**(連絡先)を渡しているのです。
**そんな説明じゃ分からん！**っていう人。心配しないで下さい。しっかりとプログラムも用意しています。

```C++:Pointer.cpp
//----通常の場合----//
int num = 42;//変数の初期化
int* pointer = &num;//変数のアドレス(連絡先)をポインタに代入している
std::cout << "pointerのアドレス: " << pointer << std::endl; //numのアドレス(連絡先)が表示される
std::cout << "pointerの中身: " << *pointer << std::endl; //numの中身が表示される
std::cout << std::endl;
//----配列の場合----//
int arrayNum[] = { 1,2,3,4,5 };//配列の初期化
int* arrayPointer = arrayNum;//配列の先頭のアドレスをポインタに代入している
std::cout << "arrayPointerのアドレス: " << arrayPointer << std::endl; //arrayNumのアドレス(連絡先)(配列の0番目)が表示される
std::cout << "arrayPointerの中身: " << *arrayPointer << std::endl; //arrayNumの中身(配列の0番目)が表示される
std::cout << std::endl;
arrayPointer += 2;//ポインタは移動させることが出来る！<-ここ重要
std::cout << "arrayPointerのアドレス: " << arrayPointer << std::endl; //arrayNumのアドレス(連絡先)(配列の2番目)が表示される
std::cout << "arrayPointerの中身: " << *arrayPointer << std::endl; //arrayNumの中身(配列の2番目)が表示される
std::cout << std::endl;
arrayPointer--;//1つ前に戻る
std::cout << "arrayPointerのアドレス: " << arrayPointer << std::endl; //arrayNumのアドレス(連絡先)(配列の1番目)が表示される
std::cout << "arrayPointerの中身: " << *arrayPointer << std::endl; //arrayNumの中身(配列の1番目)が表示される
std::cout << std::endl;

//----クラスの場合----//
int* classPointer = new int(42);//インスタンス化する
std::cout << "classPointerのアドレス: " << classPointer << std::endl; //classPointerのアドレス(連絡先)が表示される
std::cout << "classPointerの中身: " << *classPointer << std::endl; //classPointerの中身が表示される
std::cout << std::endl;
//クラスを生成したら後片付けをする
if (classPointer != nullptr) {//numPointerのアドレスが存在していれば
    delete classPointer;//削除
    classPointer = nullptr;//アドレスが存在していないことを示す
}

```
```C++:実行結果
pointerのアドレス: 00CFFCE0
pointerの中身: 42

arrayPointerのアドレス: 00CFFCB8
arrayPointerの中身: 1

arrayPointerのアドレス: 00CFFCC0
arrayPointerの中身: 3

arrayPointerのアドレス: 00CFFCBC
arrayPointerの中身: 2

classPointerのアドレス: 00FD6858
classPointerの中身: 42
```
通常、**ポインタを初期化する**際には**他の変数のアドレス**(連絡先)を代入する、もしくは**nullptr**(存在していない事と同じ)を代入しなければなりません。
それを怠った場合、コンパイラが「何も無いんだけど！？何してんの！？」みたいな感じで**エラー**を吐いてきます。気を付けましょう。
**[追記]** もう1つポインタのメリットとして**どんな大きなクラスでも4バイトに収める事が出来る**事にあります。
実体の場合(単なるコピー)では大きなもの程メモリが使われてしまいますがポインタの場合はメモリの節約にもつながるのです。
# 参照とは？
参照とは分かりやすく言えば**他人にメモ用紙を渡している**ようなものです。(良い例えがなかった…ﾕﾙｼﾃ…)
例えば、信頼できる人に「この情報渡しておくから誰か聞いてきたら代わりに教えてあげて！」という事があったとします。
そして、聞かれた人に代わりに答えていく。この行為が**参照**です。

```C++:Reference.cpp
int num = 42;//変数の初期化
int& refNum = num;//numの情報をrefNumに渡している
std::cout << "numの中身: " << num << std::endl; //numの中身が表示される
std::cout << "refNumの中身: " << refNum << std::endl; //numから渡された情報の中身が表示される
std::cout << "numのアドレス: " << &num << std::endl; //numのアドレス(連絡先)が表示される
std::cout << "refNumのアドレス: " << &refNum << std::endl; //numから渡された情報のアドレス(連絡先)が表示される
```

```C++:実行結果
numの中身: 42
refNumの中身: 42
numのアドレス: 005AF874
refNumのアドレス: 005AF874
```
この結果からどちらで表示しても**同じ結果**だという事が分かりますね。
また**参照**を使うと、**使うメモリを少なくしたり、実行速度を上げる事が出来る**というメリットもあります。(左から、逐一情報をコピーする必要がないため、情報を取得する手間が少しでも省けるから。)

# ポインタと参照の違い
今までの説明を分かりやすく表にまとめました。

|項目|ポインタ|参照|
|:------:|:------:|:------:|
|使用記号|*(間接参照演算子)|&(アンバサンド)|
|アドレスの表示|変数名|&変数名|
|中身の表示|*変数名|変数名|
|メリット|配列の場合、参照場所を移動できる<br>どれほど大きなクラスでも4バイトで済む|メモリの節約、実行速度の向上|

# まとめ
こうして書いてきた訳ですが、実質無くても大丈夫だと思います。
ですが、この2つの点を学習した上でプログラムに取り込んでいけば多少なりともコードが見やすくなったり応用を利かせられると思います。
ここまでの閲覧ありがとうございました。