プログラミングにおいて、関数の呼び出し先でも同じ実体が参照されるように引数を渡す方法のことです。
参照渡しでは、呼び出し元で実引数として指定した変数が、呼び出し先の関数の仮引数でまったく同じ実体を参照するように渡されます。そのため、関数内で仮引数の値を変更すると、呼び出し元の変数の値も変更されます。
対応する用語に値渡し(あたいわたし)があります。値渡しの場合、実引数と仮引数は異なる実体として扱われ、呼び出し先の関数内で仮引数の値を変更しても、呼び出し元の変数の値は変更されません。これは値だけを渡していると考えることができます。
また、プログラミング言語によっては、参照を値で渡すという考え方をして、すべてが値渡しであると説明されるものもあります(参照の値渡し)。Java や Python などがこの考え方を採用しています。
C言語や C++ において、ポインタ型の引数で渡すことを参照渡しと表現することがありますが、これは正確ではありません。
ポインタで渡すことが参照渡しであるのなら、以下のサンプルプログラムのように、仮引数の値を変更したときに、呼び出し側の変数の値も変更されていなければなりません。
#include <stdio.h>
int a = 10;
int b = 20;
void f(int* p)
{
p = &b; // 仮引数の値を変更する
}
int main(void)
{
int* p = &a;
printf("%d (%p)\n", *p, p);
f(p);
printf("%d (%p)\n", *p, p);
}実行結果:
10 (00007FF790DAC000)
10 (00007FF790DAC000)
実行結果のとおり、関数 f の中で仮引数 p の値を変更しても、呼び出し元の変数 p の値は変更されません。
ポインタ型の引数で渡すことは、メモリアドレスのような参照先を表現する値を、値渡しで渡しているのだといえます。標準規格の用語ではありませんが、ポインタ渡しと呼ぶことがあります。
C++ でもC言語の場合と同様に、ポインタ型の引数を渡すことは参照渡しではありませんが、C++ には参照型があるため、参照型の引数で渡すことで参照渡しが可能です。ただし、C++ の参照型の値の変更(参照先の変更)はできず、r = 0; のような代入は参照先の値の変更になるため、参照型の仮引数自体の値を変更することはできません。
#include <iostream>
int a {10};
void f(int& r)
{
std::cout << "in function: " << r << " (" << &r << ")\n";
r = 20; // これは参照先の値の書き換え
}
int main(void)
{
int& r = a;
std::cout << "before call: " << r << " (" << &r << ")\n";
f(r);
std::cout << "after call: " << r << " (" << &r << ")\n";
}実行結果:
before call: 10 (00007FF78D42D000)
in function: 10 (00007FF78D42D000)
after call: 20 (00007FF78D42D000)
メモリアドレスによる確認により、関数 f に渡した実引数の r と、仮引数の r が同じ実体を参照していることが分かります。また、関数内で参照先の値を書き換えた影響が、呼び出し側でも確認できます。
Programming Place Plus のトップページへ
| はてなブックマーク に保存 | Facebook でシェア | X で ポスト/フォロー |
| LINE で送る | noteで書く |
|
| 管理者情報 | プライバシーポリシー |