[C++] 2次元配列を引数にわたす方法
C++で2次元配列を関数に引数として渡すには、配列のサイズを明示する必要があります。
具体的には、関数の引数として「固定サイズの配列」または「ポインタ」を使用します。
固定サイズの場合、配列の列数を指定する必要があります(例: int array[][列数])。
動的配列の場合は、ポインタを使い、メモリを動的に確保します。
2次元配列を引数に渡す基本的な方法
C++では、2次元配列を関数に渡す方法はいくつかありますが、最も基本的な方法は固定サイズの2次元配列を使用することです。
この方法では、配列のサイズを関数の引数として指定する必要があります。
以下にそのサンプルコードを示します。
#include <iostream>
// 固定サイズの2次元配列を引数に取る関数
void printArray(int array[3][4]) {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            std::cout << array[i][j] << " "; // 配列の要素を出力
        }
        std::cout << std::endl; // 行の区切り
    }
}
int main() {
    int myArray[3][4] = { 
        {1, 2, 3, 4}, 
        {5, 6, 7, 8}, 
        {9, 10, 11, 12} 
    };
    
    printArray(myArray); // 2次元配列を関数に渡す
    return 0;
}1 2 3 4 
5 6 7 8 
9 10 11 12このコードでは、printArray関数が固定サイズの2次元配列を引数として受け取ります。
配列のサイズは関数内で明示的に指定されているため、呼び出し時に配列のサイズを気にする必要はありません。
固定サイズの2次元配列を渡す方法
固定サイズの2次元配列を関数に渡す方法は、C++において非常に一般的です。
この方法では、配列のサイズを関数の引数として指定する必要があります。
以下に具体的なサンプルコードを示します。
#include <iostream>
// 固定サイズの2次元配列を引数に取る関数
void displayMatrix(int matrix[2][3]) {
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
            std::cout << matrix[i][j] << " "; // 行列の要素を出力
        }
        std::cout << std::endl; // 行の区切り
    }
}
int main() {
    int myMatrix[2][3] = { 
        {1, 2, 3}, 
        {4, 5, 6} 
    };
    
    displayMatrix(myMatrix); // 固定サイズの2次元配列を関数に渡す
    return 0;
}1 2 3 
4 5 6このコードでは、displayMatrix関数が2行3列の固定サイズの2次元配列を引数として受け取ります。
配列のサイズは関数内で明示的に指定されているため、配列のサイズを気にせずに要素を出力することができます。
この方法は、配列のサイズが固定されている場合に特に便利です。
可変サイズの2次元配列を渡す方法
C++では、可変サイズの2次元配列を関数に渡すために、ポインタやstd::vectorを使用する方法があります。
ここでは、ポインタを使った方法と、std::vectorを使った方法の2つを紹介します。
ポインタを使った可変サイズの2次元配列の渡し方
ポインタを使用することで、可変サイズの2次元配列を関数に渡すことができます。
以下にそのサンプルコードを示します。
#include <iostream>
// 可変サイズの2次元配列をポインタで受け取る関数
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 = 3;
    int cols = 4;
    
    // 動的に2次元配列を確保
    int** myArray = new int*[rows];
    for (int i = 0; i < rows; i++) {
        myArray[i] = new int[cols];
    }
    // 配列に値を代入
    int value = 1;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            myArray[i][j] = value++;
        }
    }
    printDynamicArray(myArray, rows, cols); // 可変サイズの2次元配列を関数に渡す
    // メモリの解放
    for (int i = 0; i < rows; i++) {
        delete[] myArray[i];
    }
    delete[] myArray;
    return 0;
}1 2 3 4 
5 6 7 8 
9 10 11 12このコードでは、printDynamicArray関数がポインタを使って可変サイズの2次元配列を受け取ります。
配列の行数と列数を引数として渡すことで、関数内で配列のサイズを知ることができます。
動的にメモリを確保するため、使用後は必ずメモリを解放することが重要です。
std::vectorを使った可変サイズの2次元配列の渡し方
std::vectorを使用することで、可変サイズの2次元配列を簡単に扱うことができます。
以下にそのサンプルコードを示します。
#include <iostream>
#include <vector>
// std::vectorを使った可変サイズの2次元配列を受け取る関数
void displayVectorMatrix(const std::vector<std::vector<int>>& matrix) {
    for (const auto& row : matrix) {
        for (const auto& elem : row) {
            std::cout << elem << " "; // 行列の要素を出力
        }
        std::cout << std::endl; // 行の区切り
    }
}
int main() {
    std::vector<std::vector<int>> myMatrix = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
    
    displayVectorMatrix(myMatrix); // std::vectorを使った可変サイズの2次元配列を関数に渡す
    return 0;
}1 2 3 
4 5 6 
7 8 9このコードでは、displayVectorMatrix関数がstd::vectorを使って可変サイズの2次元配列を受け取ります。
std::vectorを使用することで、メモリ管理が自動的に行われ、可変サイズの配列を簡単に扱うことができます。
std::vectorを使った2次元配列の渡し方
C++のstd::vectorを使用することで、可変サイズの2次元配列を簡単に扱うことができます。
std::vectorは動的配列であり、サイズを変更することができるため、メモリ管理が容易になります。
以下に、std::vectorを使った2次元配列の渡し方を示すサンプルコードを紹介します。
#include <iostream>
#include <vector>
// std::vectorを使った2次元配列を受け取る関数
void printVectorMatrix(const std::vector<std::vector<int>>& matrix) {
    for (const auto& row : matrix) {
        for (const auto& elem : row) {
            std::cout << elem << " "; // 行列の要素を出力
        }
        std::cout << std::endl; // 行の区切り
    }
}
int main() {
    // 2次元ベクターの初期化
    std::vector<std::vector<int>> myMatrix = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
    
    printVectorMatrix(myMatrix); // std::vectorを使った2次元配列を関数に渡す
    return 0;
}1 2 3 
4 5 6 
7 8 9このコードでは、printVectorMatrix関数がstd::vector<std::vector<int>>型の引数を受け取ります。
std::vectorを使用することで、配列のサイズを動的に変更でき、メモリ管理も自動的に行われます。
関数内では、各行をループで回し、要素を出力しています。
std::vectorを使うことで、可変サイズの2次元配列を簡単に扱うことができ、コードの可読性も向上します。
参照渡しと値渡しの違い
C++では、関数に引数を渡す際に「値渡し」と「参照渡し」の2つの方法があります。
これらの違いを理解することは、プログラムの効率や動作を理解する上で重要です。
以下にそれぞれの特徴とサンプルコードを示します。
値渡し
値渡しでは、引数として渡された値のコピーが関数に渡されます。
これにより、関数内での変更は元の変数には影響を与えません。
以下に値渡しのサンプルコードを示します。
#include <iostream>
// 値渡しを使用する関数
void modifyArray(int array[3][3]) {
    array[0][0] = 99; // 配列の最初の要素を変更
}
int main() {
    int myArray[3][3] = { 
        {1, 2, 3}, 
        {4, 5, 6}, 
        {7, 8, 9} 
    };
    
    modifyArray(myArray); // 値渡しで関数に渡す
    // 元の配列を出力
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            std::cout << myArray[i][j] << " "; // 変更は反映されない
        }
        std::cout << std::endl;
    }
    return 0;
}1 2 3 
4 5 6 
7 8 9このコードでは、modifyArray関数内で配列の最初の要素を変更していますが、元の配列には影響がありません。
これは、値渡しによって配列のコピーが渡されたためです。
参照渡し
参照渡しでは、引数として渡された変数の参照(アドレス)が関数に渡されます。
これにより、関数内での変更が元の変数に影響を与えます。
以下に参照渡しのサンプルコードを示します。
#include <iostream>
// 参照渡しを使用する関数
void modifyArray(int (&array)[3][3]) {
    array[0][0] = 99; // 配列の最初の要素を変更
}
int main() {
    int myArray[3][3] = { 
        {1, 2, 3}, 
        {4, 5, 6}, 
        {7, 8, 9} 
    };
    
    modifyArray(myArray); // 参照渡しで関数に渡す
    // 元の配列を出力
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            std::cout << myArray[i][j] << " "; // 変更が反映される
        }
        std::cout << std::endl;
    }
    return 0;
}99 2 3 
4 5 6 
7 8 9このコードでは、modifyArray関数内で配列の最初の要素を変更していますが、元の配列にもその変更が反映されています。
これは、参照渡しによって元の配列の参照が渡されたためです。
| 特徴 | 値渡し | 参照渡し | 
|---|---|---|
| 影響 | 元の変数には影響しない | 元の変数に影響を与える | 
| メモリ使用 | コピーが作成されるためメモリを消費 | 参照を渡すためメモリ効率が良い | 
| 使用例 | 小さなデータ型や配列のコピーが必要な場合 | 大きなデータ型や配列を変更する場合 | 
このように、値渡しと参照渡しにはそれぞれの利点と欠点があります。
使用する場面に応じて適切な方法を選択することが重要です。
2次元配列を返り値として扱う方法
C++では、関数から2次元配列を返す方法はいくつかありますが、一般的にはポインタやstd::vectorを使用する方法が推奨されます。
ここでは、ポインタを使った方法と、std::vectorを使った方法の2つを紹介します。
ポインタを使った2次元配列の返り値
ポインタを使用して2次元配列を返す場合、動的にメモリを確保する必要があります。
以下にそのサンプルコードを示します。
#include <iostream>
// 2次元配列をポインタで返す関数
int** createDynamicArray(int rows, int cols) {
    int** array = new int*[rows]; // 行のポインタを確保
    for (int i = 0; i < rows; i++) {
        array[i] = new int[cols]; // 各行の配列を確保
    }
    // 配列に値を代入
    int value = 1;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            array[i][j] = value++;
        }
    }
    return array; // 配列のポインタを返す
}
int main() {
    int rows = 3;
    int cols = 4;
    
    int** myArray = createDynamicArray(rows, cols); // 2次元配列を作成して受け取る
    // 配列の要素を出力
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            std::cout << myArray[i][j] << " "; // 配列の要素を出力
        }
        std::cout << std::endl; // 行の区切り
    }
    // メモリの解放
    for (int i = 0; i < rows; i++) {
        delete[] myArray[i];
    }
    delete[] myArray;
    return 0;
}1 2 3 4 
5 6 7 8 
9 10 11 12このコードでは、createDynamicArray関数が動的に2次元配列を作成し、そのポインタを返します。
呼び出し元では、返されたポインタを使って配列の要素にアクセスできます。
使用後は、必ずメモリを解放することが重要です。
std::vectorを使った2次元配列の返り値
std::vectorを使用することで、より簡単に2次元配列を返すことができます。
以下にそのサンプルコードを示します。
#include <iostream>
#include <vector>
// std::vectorを使った2次元配列を返す関数
std::vector<std::vector<int>> createVectorMatrix(int rows, int cols) {
    std::vector<std::vector<int>> matrix(rows, std::vector<int>(cols)); // 2次元ベクターの初期化
    // 配列に値を代入
    int value = 1;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = value++;
        }
    }
    return matrix; // 2次元ベクターを返す
}
int main() {
    int rows = 3;
    int cols = 4;
    
    std::vector<std::vector<int>> myMatrix = createVectorMatrix(rows, cols); // 2次元ベクターを作成して受け取る
    // 配列の要素を出力
    for (const auto& row : myMatrix) {
        for (const auto& elem : row) {
            std::cout << elem << " "; // 配列の要素を出力
        }
        std::cout << std::endl; // 行の区切り
    }
    return 0;
}1 2 3 4 
5 6 7 8 
9 10 11 12このコードでは、createVectorMatrix関数がstd::vectorを使って2次元配列を作成し、そのまま返します。
std::vectorを使用することで、メモリ管理が自動的に行われ、可変サイズの配列を簡単に扱うことができます。
返されたstd::vectorは、呼び出し元でそのまま使用できます。
- ポインタを使った方法では、動的にメモリを確保し、配列のポインタを返す必要があります。
メモリ管理に注意が必要です。
- std::vectorを使った方法では、メモリ管理が自動的に行われ、簡単に2次元配列を返すことができます。
可読性も向上します。
このように、2次元配列を返り値として扱う方法にはそれぞれの利点がありますので、用途に応じて適切な方法を選択することが重要です。
まとめ
この記事では、C++における2次元配列の引数の渡し方や返り値の扱い方について詳しく解説しました。
特に、固定サイズの配列、可変サイズの配列、std::vectorを使用した方法、そして参照渡しと値渡しの違いについて触れました。
これらの知識を活用することで、より効率的で柔軟なプログラムを作成することが可能になります。
ぜひ、実際のプログラミングにおいてこれらの技術を試してみて、理解を深めてください。
 
![[C++] 配列の要素数を動的に変更する方法](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47463.png)
![[C++] 配列の要素数を定数として扱う方法(constexprの活用)](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47462.png)
![[C++] 配列の要素数を指定せず、後で要素数を決める方法](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47460.png)
![[C++] 配列に定義できる最大要素数はいくらまで?](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47458.png)
![[C++] 要素数0の配列を作成する方法 – std::vectorの応用](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47456.png)
![[C++] 配列の要素数を取得する方法](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47455.png)
![[C++] 二次元配列の使い方をマスターする](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47454.png)
![[C++] 動的配列と静的配列の違いについて解説](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47453.png)
![[C++] 動的に作成した配列を初期化する方法](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47452.png)
![[C++] 配列を動的に生成して可変長配列を実装する方法](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47451.png)
![[C++] 配列に様々な方法で値を代入する方法](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47450.png)
![[C++] 配列の宣言と初期化について解説](https://af-e.net/wp-content/uploads/2024/10/thumbnail-47449.png)