本文へスキップ
BecomeCoder

C++コース · 第9章 参照とconst ― 効率と安全のかなめ · レッスン35

参照渡し ― 関数に本体を渡す

ブラウザで完結

導入

第6章では、関数の中から呼び出し元の変数を書き換えるためにポインタを使いました。参照を使うと、それをもっと自然に書けます。加えて「大きなデータをコピーせず効率よく渡す」という重要な用途があります。

説明

引数を 型& で受け取ると、呼び出し元の変数そのものを受け取ります(値のコピーではありません)。関数内での変更が呼び出し元に反映されます。

#include <iostream>
using namespace std;

void addOne(int& n) {   // 参照で受け取る
    n += 1;             // 呼び出し元の変数を直接書き換える
}

int main() {
    int x = 5;
    addOne(x);
    cout << x << endl;  // 6(x 自身が変わった)
    return 0;
}

もう一つの用途が「効率」です。vectorstring を値で渡すと丸ごとコピーされ、大きいほど遅くなります。書き換えないなら const 型& で渡すのが定石です。

flowchart TB
  a["void f(vector&lt;int&gt; v)<br/>値渡し:全要素をコピー(遅い)"]
  b["void f(vector&lt;int&gt;&amp; v)<br/>参照渡し:コピーなし・書き換え可"]
  c["void f(const vector&lt;int&gt;&amp; v)<br/>参照渡し:コピーなし・読み取り専用(推奨)"]
  a --- b --- c
#include <iostream>
#include <vector>
using namespace std;

// 合計を返すだけ → 書き換えないので const 参照で受ける(コピーなし)
int sum(const vector<int>& v) {
    int total = 0;
    for (int x : v) total += x;
    return total;
}

int main() {
    vector<int> data = {10, 20, 30};
    cout << sum(data) << endl;   // 60(data はコピーされない)
    return 0;
}

まとめ

関数の引数は「書き換えたい → 型&」「大きいデータを読むだけ → const 型&」「小さい値をコピーでよい → そのまま値渡し」と使い分けます。const 型& は実務でもっとも多い受け取り方です。

実際に動かしてみよう

下のエディタにC++を書いて「コンパイル & 実行」を押すと、ブラウザ内で本物のC++コンパイラ(clang + libc++)がその場でコンパイルして実行し、出力が表示されます。std::string・vector・クラス・テンプレート・STL などモダンC++がそのまま動きます。本文の例を書き換えて試しながら進めましょう(初回だけコンパイラの読み込みに時間がかかります。以降はキャッシュされます。この回は標準入力(cin)は使わず、値はコードに直接書きます)。

C/C++ — ブラウザ内で本物のコンパイラで実行

ブラウザ内で本物のC/C++コンパイラ(clang + libc++ / WebAssembly)を動かします。構造体・malloc/free・std::string・vector・クラス・テンプレート・STL などがそのまま実行できます(初回のみコンパイラの読み込みに時間がかかります。以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。