回答編集履歴

3 補足

Chironian

Chironian score 20270

2017/03/21 16:08  投稿

こんにちは。
ポインタ渡しと参照渡しは、動き的にはほぼ同じです。両者ともポイント先/参照先の変数先頭アドレスが引き渡されて、そのアドレス相対で当該変数へアクセスします。
ですので、どちらの場合でも呼び出し元の変数の値を変更することも可能です。
相違点としては、参照渡しの方ができることが少ないです。その分、安全になっていると考えて下さい。
原則としてNULLを渡すことができません。(不可能ではないですが、それなりに手間です。)
受け取った側で参照先を他の変数へ切り替えることができません。「参照」はポインタと違って初期化しかできないのです。
また、ポインタはポインタを記録する変数です。なので、その変数のアドレスを取ることができます。
例えば、int型変数へのポインタへのポインタへのポインタへの・・・なんて多重ポインタも作ることが可能です。([普通はしませんが](http://qiita.com/yohhoy/items/c3f898dafb3d8bc07bd1)。)
これに対して、参照は変数ではなくそのアドレスが記録されている(筈の)メモリへのポインタを作ることができません。&参照とすると、参照先の変数のアドレスになりますから。
下記サンプルを参考にしてみて下さい。[ここ](http://melpon.org/wandbox/permlink/oxNFAGVKU3COIQrg)にソースと実行環境を置いてます。(Wandbox便利ですよ。)
```C++
#include <iostream>
struct TEST
{
   int    a;
   int    b;
   bool   c;
   TEST() : a(0), b(0), c(false) { }  // structにもコンストラクタを用意すると超便利です
};
int main()
{
   TEST data;
   TEST& ref_data=data; // dataへの参照
   TEST* ptr_data=&data; // dataへのポインタ
   std::cout << "&data   =" << &data << "\n";
   std::cout << "&ref_data=" << &ref_data << "\n";
   std::cout << "ptr_data =" << ptr_data << "\n";
   std::cout << "&ptr_data=" << &ptr_data << "\n";
   std::cout << "------------------\n";
   TEST data2;
   data2.a=100;
   ptr_data=&data2;     // ポイント先がdata2へ切り替わります
   std::cout << "data.a=" << data.a << "\n";
   ref_data=data2;      // data=data2;と同じ意味です
   std::cout << "data.a=" << data.a << "\n";
   std::cout << "&data2  =" << &data2 << "\n";
   std::cout << "&ref_data=" << &ref_data << "\n";
   std::cout << "ptr_data =" << ptr_data << "\n";
   std::cout << "&ptr_data=" << &ptr_data << "\n";
   return 0;
}
```
参照は結構難しくて、上記以外にも特別な機能を持つ参照(const参照や右辺値参照)があります。
でも、まずはポインタと参照をマスターされると良いと思います。
でも、まずはポインタと参照をマスターされると良いと思います。
---
【追記】
あっとと、すいません。参照渡しではなくて参照を説明してました。
でも、仮引数はローカル変数とほとんど同じ振る舞いをします。
仮引数はそれを定義した関数内だけで有効です。ローカル変数はそれを定義したところからそのブロックの終わりまで有効です。
仮引数は関数呼び出しのタイミングで渡された実引数で初期化されます。
`CTestProc::Test_One(data);`として呼び出した時、`TEST& TestData=data;`が実行されているのと等価です。
2 微修正

Chironian

Chironian score 20270

2017/03/21 16:03  投稿

こんにちは。
ポインタ渡しと参照渡しは、動き的にはほぼ同じです。両者ともポイント先/参照先の変数先頭アドレスが引き渡されて、そのアドレス相対で当該変数へアクセスします。
ですので、どちらの場合でも呼び出し元の変数の値を変更することも可能です。
相違点としては、参照渡しの方ができることが少ないです。その分、安全になっていると考えて下さい。
原則としてNULLを渡すことができません。(不可能ではないですが、それなりに手間です。)
受け取った側で参照先を他の変数へ切り替えることができません。「参照」はポインタと違って初期化しかできないのです。
また、ポインタはポインタを記録する変数です。なので、その変数のアドレスを取ることができます。
例えば、int型変数へのポインタへのポインタへのポインタへの・・・なんて多重ポインタも作ることが可能です。([普通はしませんが](http://qiita.com/yohhoy/items/c3f898dafb3d8bc07bd1)。)
これに対して、参照は変数ではなくそのアドレスが記録されている(筈の)メモリへのポインタを作ることができません。&参照とすると、参照先の変数のアドレスになりますから。
下記サンプルを参考にしてみて下さい。[ここ](http://melpon.org/wandbox/permlink/oxNFAGVKU3COIQrg)にソースと実行環境を置いてます。(Wandbox便利ですよ。)
```C++
#include <iostream>
struct TEST
{
   int    a;
   int    b;
   bool   c;
   TEST() : a(0), b(0), c(false) { }  // structにもコンストラクタを用意すると超便利です
};
int main()
{
   TEST data;
   TEST& ref_data=data; // dataへの参照
   TEST* ptr_data=&data; // dataへのポインタ
   std::cout << "&data   =" << &data << "\n";
   std::cout << "&ref_data=" << &ref_data << "\n";
   std::cout << "ptr_data =" << ptr_data << "\n";
   std::cout << "&ptr_data=" << &ptr_data << "\n";
   std::cout << "------------------\n";
   TEST data2;
   data2.a=100;
   ptr_data=&data2;     // 参照先がdata2へ切り替わります
   ptr_data=&data2;     // ポイント先がdata2へ切り替わります
   std::cout << "data.a=" << data.a << "\n";
   ref_data=data2;      // data=data2;と同じ意味です
   std::cout << "data.a=" << data.a << "\n";
   std::cout << "&data2  =" << &data2 << "\n";
   std::cout << "&ref_data=" << &ref_data << "\n";
   std::cout << "ptr_data =" << ptr_data << "\n";
   std::cout << "&ptr_data=" << &ptr_data << "\n";
   return 0;
}
```
参照は結構難しくて、上記以外にも特別な機能を持つ参照(const参照や右辺値参照)があります。
でも、まずはポインタと参照をマスターされると良いと思います。
1 微修正

Chironian

Chironian score 20270

2017/03/21 16:01  投稿

こんにちは。
ポインタ渡しと参照渡しは、動き的にはほぼ同じです。両者ともポイント先/参照先の変数先頭アドレスが引き渡されて、そのアドレス相対で当該変数へアクセスします。
ですので、どちらの場合でも呼び出し元の変数の値を変更することも可能です。
相違点としては、参照渡しの方ができることが少ないです。原則としてNULLを渡すことができません。(不可能ではないですが、それなりに手間です。)
相違点としては、参照渡しの方ができることが少ないです。その分、安全になっていると考えて下さい。
原則としてNULLを渡すことができません。(不可能ではないですが、それなりに手間です。)
受け取った側で参照先を他の変数へ切り替えることができません。「参照」はポインタと違って初期化しかできないのです。
また、ポインタはポインタを記録する変数です。なので、その変数のアドレスを取ることができます。
例えば、int型変数へのポインタへのポインタへのポインタへの・・・なんて多重ポインタも作ることが可能です。(普通しませんが。)
例えば、int型変数へのポインタへのポインタへのポインタへの・・・なんて多重ポインタも作ることが可能です。([普通はしませんが](http://qiita.com/yohhoy/items/c3f898dafb3d8bc07bd1)。)
これに対して、参照は変数ではなくそのアドレスが記録されている(筈の)メモリへのポインタを作ることができません。&参照とすると、参照先の変数のアドレスになりますから。
下記サンプルを参考にしてみて下さい。[ここ](http://melpon.org/wandbox/permlink/oxNFAGVKU3COIQrg)にソースと実行環境を置いてます。(Wandbox便利ですよ。)
```C++
#include <iostream>
struct TEST
{
   int    a;
   int    b;
   bool   c;
   TEST() : a(0), b(0), c(false) { }  // structにもコンストラクタを用意すると超便利です
};
int main()
{
   TEST data;
   TEST& ref_data=data; // dataへの参照
   TEST* ptr_data=&data; // dataへのポインタ
   std::cout << "&data   =" << &data << "\n";
   std::cout << "&ref_data=" << &ref_data << "\n";
   std::cout << "ptr_data =" << ptr_data << "\n";
   std::cout << "&ptr_data=" << &ptr_data << "\n";
   std::cout << "------------------\n";
   TEST data2;
   data2.a=100;
   ptr_data=&data2;     // 参照先がdata2へ切り替わります
   std::cout << "data.a=" << data.a << "\n";
   ref_data=data2;      // data=data2;と同じ意味です
   std::cout << "data.a=" << data.a << "\n";
   std::cout << "&data2  =" << &data2 << "\n";
   std::cout << "&ref_data=" << &ref_data << "\n";
   std::cout << "ptr_data =" << ptr_data << "\n";
   std::cout << "&ptr_data=" << &ptr_data << "\n";
   return 0;
}
```
参照は結構難しくて、上記以外にも特別な機能を持つ参照(const参照や右辺値参照)があります。
でも、まずはポインタと参照をマスターされると良いと思います。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る