C++: 関数のパラメータ

最終更新:2026-08-31

前のレッスンで関数を学んだ。このレッスンでは、データを関数に渡す方法——値渡し参照渡し——と、それがコードのパフォーマンスと動作にどう影響するかを深く掘り下げる。


1. 値渡し

(1) 1.1 値渡しの仕組み

値渡しでは、引数のコピーがパラメータに作成される。関数内の変更は元の変数に影響しない。

CPP
#include <iostream>

void doubleValue(int x) { // xは引数のコピー
    x = x * 2; // コピーを変更——元の変数には影響しない
    std::cout << "関数内のx: " << x << std::endl;
}

int main() {
    int num = 5;
    doubleValue(num);
    std::cout << "main内のnum: " << num << std::endl; // まだ5
    return 0;
}

出力:

TEXT 📖 参照専用
関数内のx: 10
main内のnum: 5

(2) 1.2 値渡しはいつ使う?



2. 参照渡し

(1) 2.1 参照渡しの仕組み

参照渡しでは、パラメータは引数のエイリアス(別名)になる。コピーは作成されない。

CPP
#include <iostream>

void doubleValue(int &x) { // xは引数のエイリアス
    x = x * 2; // 元の変数を直接変更
}

int main() {
    int num = 5;
    doubleValue(num);
    std::cout << "main内のnum: " << num << std::endl; // 10になる
    return 0;
}

出力:

TEXT 📖 参照専用
main内のnum: 10
💡 ヒント: &が参照パラメータを示す。呼び出し側では何も変わらない——doubleValue(num)のまま。

(2) 2.2 参照渡しはいつ使う?



3. const参照

(1) 3.1 「読み取り専用」パラメータ

大きなオブジェクトを渡すが、変更はしたくない場合、const参照を使う。

CPP
#include <iostream>
#include <string>

void printString(const std::string &s) { // コピーなし、変更不可
    std::cout << s << std::endl;
    // s = "Hello"; // ❌ コンパイルエラー: constオブジェクトを変更できない
}

int main() {
    std::string name = "Alice";
    printString(name);
    printString("Bob"); // 一時オブジェクトも可能
    return 0;
}

(2) 3.2 const参照の利点

利点 説明
効率的 コピーを作成しない
安全 呼び出し元の値が変更されないことを保証
柔軟 一時オブジェクト(リテラル)も受け取れる


4. デフォルト引数

(1) 4.1 基本構文

パラメータにデフォルト値を指定できる。引数を渡さなければ、デフォルトが使われる。

CPP
#include <iostream>

void greet(std::string name = "Guest", int times = 1) {
    for (int i = 0; i < times; i++) {
        std::cout << "Hello, " << name << "!" << std::endl;
    }
}

int main() {
    greet();                     // Hello, Guest!
    greet("Alice");              // Hello, Alice!
    greet("Bob", 3);             // Hello, Bob! x3
    return 0;
}

(2) 4.2 デフォルト引数のルール

  1. 右から左へ —— デフォルト引数はパラメータリストの右端から始める
  2. 連続 —— 中抜けは不可
  3. プロトタイプでのみ指定 —— 定義ではなくプロトタイプでデフォルト値を書く
TEXT 📖 参照専用
void func(int a, int b = 2, int c = 3); // ✅ OK
void func(int a = 1, int b, int c = 3); // ❌ エラー: 中抜け


5. 複数の値を返す

C++の関数は1つの戻り値しか返せないが、参照パラメータを使えば複数の値を「返せる」。

▶ サンプル 1:複数の値を返す(難易度 ⭐⭐)

CPP
#include <iostream>

void calculateStats(int a, int b, int &sum, int &product, double &average) {
    sum = a + b;
    product = a * b;
    average = (a + b) / 2.0;
}

int main() {
    int x = 10, y = 3;
    int sum, product;
    double average;
    
    calculateStats(x, y, sum, product, average);
    
    std::cout << "和: " << sum << std::endl;
    std::cout << "積: " << product << std::endl;
    std::cout << "平均: " << average << std::endl;
    
    return 0;
}
▶ 試してみよう

6. 値渡し vs 参照渡し

特徴 値渡し 参照渡し
コピー 作成する 作成しない
元の変数 変更されない 変更できる
パフォーマンス 小さな型では高速 大きな型では高速
安全性 安全(副作用なし) 注意が必要
構文 void f(int x) void f(int &x)

▶ サンプル 2:デフォルト引数を使う(難易度 ⭐)

CPP
#include <iostream>
#include <string>

void greet(std::string name = "Guest", int times = 1) {
    for (int i = 0; i < times; i++) {
        std::cout << "Hello, " << name << "!" << std::endl;
    }
}

int main() {
    greet();                // Hello, Guest!
    greet("Alice");         // Hello, Alice!
    greet("Bob", 3);        // Hello, Bob! x3
    return 0;
}
▶ 試してみよう

▶ サンプル 3:const参照で文字列を処理(難易度 ⭐⭐)

CPP
#include <iostream>
#include <string>

int countVowels(const std::string& text) {
    int count = 0;
    for (char c : text) {
        if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ||
            c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
            count++;
        }
    }
    return count;
}

int main() {
    std::string message = "Hello World";
    std::cout << "母音の数: " << countVowels(message) << std::endl;
    return 0;
}
▶ 試してみよう

❓ よくある質問

Q 配列は値渡しできる?
A いいえ!C++では配列はポインタとして減衰——配列をパラメータに渡すと、最初の要素へのポインタになる。配列を「値渡し」したい場合、構造体でラップするかstd::arrayを使う。
Q const参照と値渡しのどちらを使うべき?
A 小さな型(intchardouble)は値渡し——コピーは安価。大きな型(std::string、構造体)はconst参照——コピーを避ける。
Q デフォルト引数を途中で省略できる?
A いいえ。デフォルト引数は右から左へ適用。func(1, , 3)は無効。
Q 参照パラメータはnullptrになり得る?
A いいえ。参照は有効なオブジェクトを指す必要がある。ポインタのような「参照先なし」は存在しない。

📖 まとめ


📝 練習問題

  1. 初級(難易度 ⭐): 文字列を大文字に変換するvoid toUpper(std::string &s)関数を書く。

  2. 中級(難易度 ⭐⭐): void getStats(const std::string &s, int &letters, int &digits, int &spaces)関数を書く。文字列内の文字、数字、スペースの数をカウント。

  3. 上級(難易度 ⭐⭐⭐): 数のリストから最小値、最大値、平均を計算する関数を書く。3つの値すべてを参照パラメータで返す。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%