関数

[C++] 関数に配列をポインタ渡しではなく参照渡しする方法

C++では、配列を関数に参照渡しすることで、ポインタを使用せずに配列そのものを操作できます。

配列の参照渡しは、関数の引数で配列の型に参照記号&を付けることで実現します。

この方法では、配列のサイズも型情報に含まれるため、誤ったサイズの配列を渡すことを防げます。

例えば、void func(int (&arr)[5])のように記述します。

この場合、サイズ5のint型配列のみが渡せます。

配列を参照渡しする方法

C++では、配列を関数に渡す際にポインタを使うことが一般的ですが、参照渡しを利用することで、より直感的に配列を扱うことができます。

ここでは、配列を参照渡しする方法について解説します。

参照渡しの基本

参照渡しを使用することで、関数内で配列の内容を直接操作することができます。

これにより、配列のコピーを作成する必要がなく、効率的にデータを扱うことが可能です。

以下は、配列を参照渡しする例です。

#include <iostream>
void modifyArray(int (&arr)[5]) { // 配列を参照渡し
    for (int i = 0; i < 5; ++i) {
        arr[i] += 1; // 各要素を1増加させる
    }
}
int main() {
    int myArray[5] = {1, 2, 3, 4, 5}; // 配列の初期化
    modifyArray(myArray); // 配列を参照渡しで関数に渡す
    // 結果を表示
    for (int i = 0; i < 5; ++i) {
        std::cout << myArray[i] << " "; // 変更後の配列を表示
    }
    std::cout << std::endl;
    return 0;
}
2 3 4 5 6

このコードでは、modifyArray関数が配列を参照渡しで受け取ります。

配列の各要素に1を加算することで、元の配列が変更されます。

参照渡しを使用することで、配列のコピーを作成せずに直接操作できるため、メモリの効率が向上します。

ポインタ渡しとの比較

C++では、配列を関数に渡す方法としてポインタ渡しと参照渡しの2つがあります。

それぞれの特徴や利点、欠点を比較してみましょう。

ポインタ渡しの特徴

  • 構文: ポインタを使って配列を渡す場合、関数の引数はポインタ型になります。
  • 柔軟性: ポインタを使うことで、配列のサイズを動的に変更することが可能です。
  • 明示的な操作: ポインタを使う場合、配列の要素にアクセスする際に、ポインタ演算を行う必要があります。

参照渡しの特徴

  • 構文: 参照渡しでは、配列を参照型で受け取ります。

これにより、配列のサイズを明示的に指定する必要があります。

  • 直感的な操作: 参照を使うことで、配列の要素に対する操作がより直感的になります。
  • コピーの回避: 参照渡しでは、配列のコピーを作成せずに直接操作できるため、メモリ効率が良いです。

比較表

特徴ポインタ渡し参照渡し
構文void function(int* arr)void function(int (&arr)[5])
配列サイズの指定不要(動的)必要(固定サイズ)
アクセス方法ポインタ演算が必要直接アクセス可能
メモリ効率コピーが発生する可能性ありコピーなし
可読性やや低い高い

ポインタ渡しと参照渡しはそれぞれ異なる利点があります。

ポインタ渡しは柔軟性が高く、動的な配列操作に適していますが、参照渡しはコードの可読性が高く、メモリ効率も良好です。

使用する場面に応じて、どちらの方法を選択するかを考えることが重要です。

配列参照渡しの応用

配列を参照渡しする方法は、さまざまな場面で応用可能です。

ここでは、具体的な例を挙げて、配列参照渡しの利点や使い方を紹介します。

1. 複数の配列を同時に操作

参照渡しを利用することで、複数の配列を同時に操作することができます。

以下の例では、2つの配列の要素を相互に加算する関数を示します。

#include <iostream>
void addArrays(int (&arr1)[5], int (&arr2)[5]) { // 2つの配列を参照渡し
    for (int i = 0; i < 5; ++i) {
        arr1[i] += arr2[i]; // arr1の各要素にarr2の要素を加算
    }
}
int main() {
    int array1[5] = {1, 2, 3, 4, 5}; // 配列1の初期化
    int array2[5] = {5, 4, 3, 2, 1}; // 配列2の初期化
    addArrays(array1, array2); // 2つの配列を参照渡しで関数に渡す
    // 結果を表示
    for (int i = 0; i < 5; ++i) {
        std::cout << array1[i] << " "; // 変更後の配列1を表示
    }
    std::cout << std::endl;
    return 0;
}
6 6 6 6 6

2. 配列のサイズを固定する

参照渡しを使用することで、配列のサイズを固定し、関数内での不正なアクセスを防ぐことができます。

以下の例では、固定サイズの配列を受け取る関数を示します。

#include <iostream>
void printArray(const int (&arr)[3]) { // 固定サイズの配列を参照渡し
    for (int i = 0; i < 3; ++i) {
        std::cout << arr[i] << " "; // 配列の要素を表示
    }
    std::cout << std::endl;
}
int main() {
    int myArray[3] = {10, 20, 30}; // 配列の初期化
    printArray(myArray); // 配列を参照渡しで関数に渡す
    return 0;
}
10 20 30

3. テンプレートを使った汎用的な関数

参照渡しを使ったテンプレート関数を作成することで、異なる型の配列にも対応できます。

以下の例では、任意の型の配列を受け取る関数を示します。

#include <iostream>
template <typename T, size_t N>
void displayArray(const T (&arr)[N]) { // テンプレートで配列を参照渡し
    for (size_t i = 0; i < N; ++i) {
        std::cout << arr[i] << " "; // 配列の要素を表示
    }
    std::cout << std::endl;
}
int main() {
    int intArray[4] = {1, 2, 3, 4}; // 整数型配列の初期化
    double doubleArray[3] = {1.1, 2.2, 3.3}; // 浮動小数点型配列の初期化
    displayArray(intArray); // 整数型配列を表示
    displayArray(doubleArray); // 浮動小数点型配列を表示
    return 0;
}
1 2 3 4 
1.1 2.2 3.3

配列を参照渡しする方法は、複数の配列を同時に操作したり、配列のサイズを固定したり、テンプレートを使って汎用的な関数を作成したりする際に非常に便利です。

これにより、コードの可読性や効率性が向上し、より柔軟なプログラミングが可能になります。

まとめ

この記事では、C++における配列の参照渡しの方法やその利点、ポインタ渡しとの比較、さらには具体的な応用例について詳しく解説しました。

参照渡しを利用することで、配列の操作がより直感的になり、メモリ効率も向上することがわかりました。

これを機に、配列を扱う際には参照渡しを積極的に活用し、より効率的なプログラミングを実践してみてください。

関連記事

Back to top button