質問: FALSE; //ここで変更した値はTest_Twoの外でも反映されるってことですか? } void foo() { TEST data; //Twoを実行後にOneを実行 CTestProc::Test_Two(&data); // ポインタ渡し CTestProc::Test_One(data); // 参照渡し //上記2つの関数実行後のa,b,cの値を出力。 //○質問5 //ここでの値は、twoの値である、200,800,FALSEが入っていますか? AfxMessageBox(_T("%d"),data.a); AfxMessageBox(_T("%d"),data.b); AfxMessageBox(_T("%b"),data.c); } ``` ### 補足情報(言語/FW/ツール等のバージョンなど) C++ VS2010 MFC
回答: こんにちは。 ポインタ渡しと参照渡しは、動き的にはほぼ同じです。両者ともポイント先/参照先の変数先頭アドレスが引き渡されて、そのアドレス相対で当該変数へアクセスします。 ですので、どちらの場合でも呼び出し元の変数の値を変更することも可能です。 相違点としては、参照渡しの方ができることが少ないです。その分、安全になっていると考えて下さい。 原則としてNULLを渡すことができません。(不可能ではないですが、それなりに手間です。) 受け取った側で参照先を他の変数へ切り替えることができません。「参照」はポインタと違って初期化しかできないのです。 また、ポインタはポインタを記録する変数です。なので、その変数のアドレスを取ることができます。 例えば、int型変数へのポインタへのポインタへのポインタへの・・・なんて多重ポインタも作ることが可能です。(普通はしませんが。) これに対して、参照は変数ではなくそのアドレスが記録されている(筈の)メモリへのポインタを作ることができません。&参照とすると、参照先の変数のアドレスになりますから。 下記サンプルを参考にしてみて下さい。ここにソースと実行環境を置いてます。(Wandbox便利ですよ。) ``` #include 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;`が実行されているのと等価です。