[C言語] 2次元配列を関数に引数として渡す方法
C言語で2次元配列を関数に引数として渡すには、配列のサイズを明示的に指定する必要があります。
関数のプロトタイプでは、配列の行数は省略可能ですが、列数は指定しなければなりません。
例えば、void function(int array[][COLS])
のように宣言します。
この方法により、関数内で配列の要素にアクセスすることが可能になります。
また、ポインタを使用して配列を渡すこともできますが、配列のサイズ情報を別途渡す必要があります。
- 2次元配列の基礎知識とメモリ上の配置
- 関数に2次元配列を渡す際のプロトタイプの定義方法
- ポインタを使った2次元配列の操作方法
- 動的メモリ確保を用いた2次元配列の柔軟な扱い方
2次元配列の基礎知識
2次元配列とは
2次元配列は、行と列の2つの次元を持つ配列で、表形式のデータを扱うのに適しています。
C言語では、2次元配列は配列の配列として実装され、各要素は同じデータ型を持ちます。
例えば、整数型の2次元配列は以下のように宣言されます。
int matrix[3][4];
この例では、matrix
は3行4列の整数型の2次元配列です。
メモリ上の配置
2次元配列はメモリ上に連続して配置されます。
C言語では、2次元配列は行優先で格納されます。
つまり、最初の行のすべての要素がメモリ上に連続して配置され、その後に次の行の要素が続きます。
以下の表は、3行4列の2次元配列のメモリ上の配置を示しています。
行番号 | メモリ上の配置 |
---|---|
0 | matrix[0][0] , matrix[0][1] , matrix[0][2] , matrix[0][3] |
1 | matrix[1][0] , matrix[1][1] , matrix[1][2] , matrix[1][3] |
2 | matrix[2][0] , matrix[2][1] , matrix[2][2] , matrix[2][3] |
宣言と初期化の方法
2次元配列の宣言と初期化は、以下のように行います。
宣言時に初期化を行うことで、配列の各要素に初期値を設定できます。
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
この例では、matrix
は3行4列の2次元配列で、各要素に初期値が設定されています。
初期化リストを使用することで、配列の要素を簡潔に設定できます。
また、初期化リストの一部を省略することも可能で、その場合は省略された要素はデフォルト値(整数型の場合は0)で初期化されます。
関数に2次元配列を渡す基本
2次元配列を関数に渡す際には、配列のサイズやポインタを適切に扱う必要があります。
ここでは、関数プロトタイプの定義方法や配列のサイズ指定、ポインタを使った渡し方について解説します。
関数プロトタイプの定義
2次元配列を関数に渡すためには、関数プロトタイプを正しく定義する必要があります。
関数プロトタイプでは、配列の行数を指定し、列数を明示する必要があります。
以下は、2次元配列を引数に取る関数のプロトタイプの例です。
void processMatrix(int matrix[][4], int rows);
この例では、processMatrix
という関数が2次元配列matrix
と行数rows
を引数として受け取ります。
列数4
は固定されているため、プロトタイプで明示されています。
配列のサイズ指定
関数に2次元配列を渡す際には、少なくとも列数を指定する必要があります。
行数は関数内で別途引数として渡すことが一般的です。
以下のコードは、2次元配列を関数に渡す際のサイズ指定の例です。
void printMatrix(int matrix[][4], int rows) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
この関数printMatrix
は、行数rows
を引数として受け取り、配列の各要素を出力します。
ポインタを使った渡し方
2次元配列をポインタとして渡す方法もあります。
この方法では、配列の先頭アドレスをポインタとして渡し、関数内で配列を操作します。
以下は、ポインタを使った2次元配列の渡し方の例です。
void modifyMatrix(int *matrix, int rows, int cols) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
*(matrix + i * cols + j) += 1; // 各要素に1を加算
}
}
}
この例では、modifyMatrix関数
がポインタmatrix
を受け取り、行数rows
と列数cols
を使って配列の各要素にアクセスしています。
ポインタを使うことで、配列のサイズを柔軟に扱うことができます。
以上の方法を理解することで、2次元配列を関数に渡す際の基本的なテクニックを習得できます。
具体的なコード例
ここでは、2次元配列を関数に渡す具体的なコード例を紹介します。
これらの例を通じて、2次元配列の操作方法を理解しましょう。
2次元配列を引数に取る関数の例
以下のコードは、2次元配列を引数に取る関数の例です。
この関数は、配列の各要素を出力します。
#include <stdio.h>
// 2次元配列を引数に取る関数
void printMatrix(int matrix[][3], int rows) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int main() {
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
printMatrix(matrix, 2);
return 0;
}
1 2 3
4 5 6
このコードでは、printMatrix関数
が2次元配列matrix
を受け取り、各要素を出力しています。
配列の要素を操作する関数の例
次に、2次元配列の要素を操作する関数の例を示します。
この関数は、配列の各要素に1を加算します。
#include <stdio.h>
// 配列の要素を操作する関数
void incrementMatrix(int matrix[][3], int rows) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 3; j++) {
matrix[i][j] += 1;
}
}
}
int main() {
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
incrementMatrix(matrix, 2);
printMatrix(matrix, 2); // 先ほどのprintMatrix関数を使用
return 0;
}
2 3 4
5 6 7
このコードでは、incrementMatrix関数
が配列の各要素に1を加算し、printMatrix関数
で結果を出力しています。
配列のサイズを動的に扱う例
最後に、配列のサイズを動的に扱う例を示します。
この例では、ポインタを使って2次元配列を操作します。
#include <stdio.h>
#include <stdlib.h>
// 動的に配列を操作する関数
void dynamicMatrix(int *matrix, int rows, int cols) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
*(matrix + i * cols + j) = i * cols + j;
}
}
}
int main() {
int rows = 3, cols = 4;
int *matrix = (int *)malloc(rows * cols * sizeof(int));
dynamicMatrix(matrix, rows, cols);
// 結果を出力
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%d ", *(matrix + i * cols + j));
}
printf("\n");
}
free(matrix);
return 0;
}
0 1 2 3
4 5 6 7
8 9 10 11
このコードでは、dynamicMatrix関数
が動的に確保したメモリを使って2次元配列を操作し、各要素に値を設定しています。
動的メモリを使用することで、配列のサイズを柔軟に扱うことができます。
ポインタと2次元配列
ポインタはC言語において非常に強力な機能であり、2次元配列を操作する際にも重要な役割を果たします。
ここでは、ポインタと配列の関係、ポインタを使った2次元配列の操作、そしてポインタ配列を使った関数への渡し方について解説します。
ポインタと配列の関係
配列とポインタは密接な関係にあります。
配列の名前は、その配列の先頭要素のアドレスを指すポインタとして扱われます。
例えば、int matrix[3][4];
という2次元配列がある場合、matrix
はmatrix[0]
の先頭アドレスを指すポインタとして扱われます。
以下の表は、配列とポインタの関係を示しています。
配列名 | ポインタとしての意味 |
---|---|
matrix | &matrix[0] (最初の行の先頭アドレス) |
matrix[i] | &matrix[i][0] (i番目の行の先頭アドレス) |
ポインタを使った2次元配列の操作
ポインタを使って2次元配列を操作することができます。
ポインタを使うことで、配列の要素にアクセスしたり、操作したりすることが可能です。
以下のコードは、ポインタを使って2次元配列の要素を操作する例です。
#include <stdio.h>
// ポインタを使った2次元配列の操作
void modifyMatrix(int *matrix, int rows, int cols) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
*(matrix + i * cols + j) += 10; // 各要素に10を加算
}
}
}
int main() {
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
modifyMatrix((int *)matrix, 2, 3);
// 結果を出力
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
11 12 13
14 15 16
このコードでは、modifyMatrix関数
がポインタを使って2次元配列の各要素に10を加算しています。
ポインタ配列を使った関数への渡し方
ポインタ配列を使って2次元配列を関数に渡す方法もあります。
この方法では、各行を指すポインタの配列を作成し、それを関数に渡します。
以下のコードは、ポインタ配列を使った関数への渡し方の例です。
#include <stdio.h>
// ポインタ配列を使った関数
void printMatrix(int *matrix[], int rows, int cols) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int main() {
int row1[] = {1, 2, 3};
int row2[] = {4, 5, 6};
int *matrix[] = {row1, row2};
printMatrix(matrix, 2, 3);
return 0;
}
1 2 3
4 5 6
このコードでは、各行を指すポインタの配列matrix
を作成し、printMatrix関数
に渡しています。
ポインタ配列を使うことで、関数に渡す際の柔軟性が向上します。
応用例
2次元配列を関数に渡す方法は、さまざまな応用が可能です。
ここでは、文字列の2次元配列を関数に渡す方法、動的メモリ確保を用いた2次元配列の渡し方、そして多次元配列を関数に渡す方法について解説します。
文字列の2次元配列を関数に渡す
文字列の2次元配列は、文字列の配列として扱われます。
各文字列は文字の配列であり、2次元配列として関数に渡すことができます。
以下のコードは、文字列の2次元配列を関数に渡す例です。
#include <stdio.h>
// 文字列の2次元配列を関数に渡す
void printStrings(char strings[][20], int count) {
for (int i = 0; i < count; i++) {
printf("%s\n", strings[i]);
}
}
int main() {
char strings[3][20] = {"Hello", "World", "C Language"};
printStrings(strings, 3);
return 0;
}
Hello
World
C Language
このコードでは、printStrings関数
が文字列の2次元配列を受け取り、各文字列を出力しています。
動的メモリ確保を用いた2次元配列の渡し方
動的メモリ確保を用いることで、実行時に配列のサイズを決定することができます。
以下のコードは、動的メモリ確保を用いた2次元配列の渡し方の例です。
#include <stdio.h>
#include <stdlib.h>
// 動的メモリ確保を用いた2次元配列の渡し方
void fillMatrix(int **matrix, int rows, int cols) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j] = i * cols + j;
}
}
}
int main() {
int rows = 3, cols = 4;
int **matrix = (int **)malloc(rows * sizeof(int *));
for (int i = 0; i < rows; i++) {
matrix[i] = (int *)malloc(cols * sizeof(int));
}
fillMatrix(matrix, rows, cols);
// 結果を出力
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
// メモリの解放
for (int i = 0; i < rows; i++) {
free(matrix[i]);
}
free(matrix);
return 0;
}
0 1 2 3
4 5 6 7
8 9 10 11
このコードでは、fillMatrix関数
が動的に確保したメモリを使って2次元配列を操作し、各要素に値を設定しています。
多次元配列を関数に渡す方法
多次元配列を関数に渡す場合も、2次元配列と同様に扱うことができます。
ただし、すべての次元のサイズを指定する必要があります。
以下のコードは、多次元配列を関数に渡す方法の例です。
#include <stdio.h>
// 多次元配列を関数に渡す
void print3DArray(int array[][3][2], int depth) {
for (int i = 0; i < depth; i++) {
printf("Layer %d:\n", i);
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 2; k++) {
printf("%d ", array[i][j][k]);
}
printf("\n");
}
}
}
int main() {
int array[2][3][2] = {
{{1, 2}, {3, 4}, {5, 6}},
{{7, 8}, {9, 10}, {11, 12}}
};
print3DArray(array, 2);
return 0;
}
Layer 0:
1 2
3 4
5 6
Layer 1:
7 8
9 10
11 12
このコードでは、print3DArray関数
が3次元配列を受け取り、各要素を出力しています。
多次元配列を扱う際には、すべての次元のサイズを指定することが重要です。
よくある質問
まとめ
2次元配列を関数に渡す方法について、基本的な概念から応用例までを詳しく解説しました。
2次元配列の操作には、配列のサイズ指定やポインタの活用が重要であることが理解できたでしょう。
この記事を参考に、実際のプログラムで2次元配列を効果的に活用してみてください。