C++で関数を定義する際、引数の渡し方には「値渡し」と「ポインタ渡し(あるいは参照渡し)」の2つの方法があります。本記事では、それぞれの違いと、初心者が陥りやすい「関数で変数の値が変更されない」問題を、具体的なコード例を通じてわかりやすく解説いたします。
目次
サンプルコード:動作しない swap 関数(値渡し)
以下は、2つの変数の値を入れ替えようとしたが、うまく動作しない例です。
#include <iostream>
using namespace std;
// 値渡しによる swap 関数(失敗例)
void exchange(int x, int y);
int main()
{
int numA = 10;
int numB = 20;
cout << "変更前:" << numA << ", " << numB << endl;
exchange(numA, numB);
cout << "変更後:" << numA << ", " << numB << endl;
return 0;
}
void exchange(int x, int y)
{
int temp = x;
x = y;
y = temp;
}
解説
このコードは一見正しそうに見えますが、exchange
関数の中で値の入れ替えをしても、main
関数の中のnumA
やnumB
の値は変わりません。なぜなら、値渡しでは「呼び出し元の変数のコピー」が引数として渡されるため、元の値に影響が及ばないからです。
正しい書き方:ポインタ渡しによる swap 関数
次に、ポインタを使って正しく値を入れ替える方法を紹介いたします。
#include <iostream>
using namespace std;
// ポインタ渡しによる swap 関数(成功例)
void exchange(int* ptrA, int* ptrB);
int main()
{
int numA = 10;
int numB = 20;
cout << "変更前:" << numA << ", " << numB << endl;
exchange(&numA, &numB);
cout << "変更後:" << numA << ", " << numB << endl;
return 0;
}
void exchange(int* ptrA, int* ptrB)
{
int temp = *ptrA;
*ptrA = *ptrB;
*ptrB = temp;
}
解説
この場合、関数に渡すのは変数のアドレス(=実体の位置)です。そのため、関数内で*ptrA
や*ptrB
を使って間接的に値を変更すると、呼び出し元の変数に直接反映されます。
応用:参照渡しでも可能
C++では、ポインタを使わずに参照渡し(&
記号)を使うことでも同様の動作を実現できます。
void exchange(int& refA, int& refB)
{
int temp = refA;
refA = refB;
refB = temp;
}
この方法は、可読性が高く安全性も高いため、C++に慣れてきたら積極的に活用することをおすすめします。
まとめ
関数で変数の値を変更したい場合、「値渡し」ではなく「ポインタ渡し」や「参照渡し」を使う必要があります。C++における引数の渡し方をしっかりと理解することは、バグのない堅牢なプログラムを作成する上で非常に重要です。