関数

[C++] 関数の引数に二次元配列を渡す方法

C++で関数の引数に二次元配列を渡す場合、配列のサイズを明示する必要があります。

具体的には、配列の列数を固定して宣言する必要があります。

例えば、void func(int arr[][列数], int 行数)のように記述します。

列数が固定できない場合は、ポインタやstd::vectorを使用する方法が一般的です。

二次元配列を関数に渡す基本的な方法

C++では、二次元配列を関数に渡す方法はいくつかありますが、最も基本的な方法は、配列のポインタを使用することです。

以下に、二次元配列を関数に渡すサンプルコードを示します。

#include <iostream>
// 二次元配列を受け取る関数
void printArray(int (*array)[3], int rows) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < 3; j++) {
            std::cout << array[i][j] << " "; // 配列の要素を出力
        }
        std::cout << std::endl; // 行の区切り
    }
}
int main() {
    int myArray[2][3] = { {1, 2, 3}, {4, 5, 6} }; // 二次元配列の初期化
    printArray(myArray, 2); // 関数に配列を渡す
    return 0;
}
1 2 3 
4 5 6

このコードでは、printArray関数が二次元配列を受け取ります。

配列のサイズを指定するために、列数を固定し、行数を引数として渡しています。

これにより、関数内で配列の要素にアクセスすることができます。

配列のサイズを動的に扱う方法

C++では、動的メモリ割り当てを使用して、配列のサイズを実行時に決定することができます。

これにより、必要なサイズの二次元配列を作成し、関数に渡すことが可能になります。

以下に、new演算子を使用して動的に二次元配列を作成し、関数に渡すサンプルコードを示します。

#include <iostream>
// 二次元配列を受け取る関数
void printDynamicArray(int** array, int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            std::cout << array[i][j] << " "; // 配列の要素を出力
        }
        std::cout << std::endl; // 行の区切り
    }
}
int main() {
    int rows = 2; // 行数
    int cols = 3; // 列数
    // 動的に二次元配列を作成
    int** myArray = new int*[rows]; // 行のポインタを作成
    for (int i = 0; i < rows; i++) {
        myArray[i] = new int[cols]; // 各行に列を割り当て
    }
    // 配列に値を代入
    myArray[0][0] = 1; myArray[0][1] = 2; myArray[0][2] = 3;
    myArray[1][0] = 4; myArray[1][1] = 5; myArray[1][2] = 6;
    printDynamicArray(myArray, rows, cols); // 関数に配列を渡す
    // メモリの解放
    for (int i = 0; i < rows; i++) {
        delete[] myArray[i]; // 各行のメモリを解放
    }
    delete[] myArray; // 行のポインタのメモリを解放
    return 0;
}
1 2 3 
4 5 6

このコードでは、new演算子を使用して動的に二次元配列を作成しています。

printDynamicArray関数は、動的に割り当てられた配列を受け取り、行数と列数を引数として渡します。

最後に、使用したメモリを解放するためにdelete[]を使用しています。

これにより、メモリリークを防ぐことができます。

std::vectorを使った二次元配列の渡し方

C++の標準ライブラリに含まれるstd::vectorを使用すると、動的なサイズの二次元配列を簡単に扱うことができます。

std::vectorはメモリ管理を自動で行ってくれるため、手動でメモリを解放する必要がなく、使いやすいです。

以下に、std::vectorを使った二次元配列の渡し方のサンプルコードを示します。

#include <iostream>
#include <vector> // std::vectorを使用するためにインクルード
// 二次元ベクターを受け取る関数
void printVector(const std::vector<std::vector<int>>& vec) {
    for (const auto& row : vec) {
        for (const auto& elem : row) {
            std::cout << elem << " "; // ベクターの要素を出力
        }
        std::cout << std::endl; // 行の区切り
    }
}
int main() {
    // 二次元ベクターの初期化
    std::vector<std::vector<int>> myVector = {
        {1, 2, 3},
        {4, 5, 6}
    };
    printVector(myVector); // 関数にベクターを渡す
    return 0;
}
1 2 3 
4 5 6

このコードでは、std::vectorを使用して二次元配列を作成しています。

printVector関数は、const参照を通じて二次元ベクターを受け取り、要素を出力します。

std::vectorを使用することで、サイズの変更やメモリ管理が容易になり、より安全で効率的なプログラミングが可能になります。

テンプレートを使った汎用的な関数の作成

C++のテンプレート機能を利用すると、異なるデータ型に対して汎用的な関数を作成することができます。

これにより、特定のデータ型に依存しない二次元配列を扱う関数を作成することが可能です。

以下に、テンプレートを使った汎用的な二次元配列の出力関数のサンプルコードを示します。

#include <iostream>
#include <vector> // std::vectorを使用するためにインクルード
// テンプレートを使った二次元配列を受け取る関数
template <typename T>
void printGenericArray(const std::vector<std::vector<T>>& array) {
    for (const auto& row : array) {
        for (const auto& elem : row) {
            std::cout << elem << " "; // 配列の要素を出力
        }
        std::cout << std::endl; // 行の区切り
    }
}
int main() {
    // 整数型の二次元ベクターの初期化
    std::vector<std::vector<int>> intArray = {
        {1, 2, 3},
        {4, 5, 6}
    };
    // 文字型の二次元ベクターの初期化
    std::vector<std::vector<std::string>> stringArray = {
        {"A", "B", "C"},
        {"D", "E", "F"}
    };
    std::cout << "整数型の配列:" << std::endl;
    printGenericArray(intArray); // 整数型の配列を渡す
    std::cout << "文字型の配列:" << std::endl;
    printGenericArray(stringArray); // 文字型の配列を渡す
    return 0;
}
整数型の配列:
1 2 3 
4 5 6 
文字型の配列:
A B C 
D E F

このコードでは、テンプレートを使用してprintGenericArray関数を定義しています。

この関数は、任意のデータ型の二次元ベクターを受け取り、その要素を出力します。

std::vectorを使うことで、異なるデータ型の配列を簡単に扱うことができ、コードの再利用性が向上します。

配列のサイズを関数内で取得する方法

C++では、配列のサイズを関数内で取得する方法がいくつかありますが、特に固定サイズの配列の場合、sizeof演算子を使用することが一般的です。

ただし、ポインタとして渡された場合、サイズ情報は失われるため、注意が必要です。

以下に、固定サイズの二次元配列のサイズを関数内で取得するサンプルコードを示します。

#include <iostream>
// 二次元配列のサイズを取得する関数
void printArrayWithSize(int array[][3], int rows) {
    // 配列のサイズを取得
    int cols = sizeof(array[0]) / sizeof(array[0][0]); // 列数を計算
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            std::cout << array[i][j] << " "; // 配列の要素を出力
        }
        std::cout << std::endl; // 行の区切り
    }
}
int main() {
    int myArray[2][3] = { {1, 2, 3}, {4, 5, 6} }; // 二次元配列の初期化
    printArrayWithSize(myArray, 2); // 関数に配列を渡す
    return 0;
}
1 2 3 
4 5 6

このコードでは、printArrayWithSize関数内でsizeof演算子を使用して列数を計算しています。

sizeof(array[0])は最初の行のサイズを返し、sizeof(array[0][0])は最初の要素のサイズを返します。

これにより、列数を求めることができます。

ただし、この方法は固定サイズの配列にのみ適用可能であり、動的配列やポインタを使用する場合は、別の方法でサイズを管理する必要があります。

まとめ

この記事では、C++における二次元配列を関数に渡すさまざまな方法について解説しました。

具体的には、固定サイズの配列、動的配列、std::vectorを使用した方法、テンプレートを利用した汎用的な関数、そして配列のサイズを関数内で取得する方法を取り上げました。

これらの知識を活用して、より柔軟で効率的なプログラミングを行うことができるでしょう。

次のステップとして、実際にこれらの方法を使って自分のプロジェクトに応用してみることをお勧めします。

関連記事

Back to top button