二次元配列の基本概念
宣言とメモリ構造
C言語における二次元配列は、以下のような構文で宣言します。
データ型 配列名[行数][列数];
厳密には、C言語のメモリモデルにおいて真の多次元配列は存在せず、二次元配列は「一次元配列の要素として一次元配列を持つ」構造、すなわち連続したメモリブロックとして実装されています。
初期化の方法
一次元配列と同様に、二次元配列も宣言時に全体または一部を初期化可能です。行数は省略できますが、列数は必ず指定する必要があります。
int matrix1[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; // 平坦な初期化
int matrix2[3][3] = {1, 2, 3, 4}; // 部分初期化(残りは0)
int matrix3[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; // 行ごとの初期化
int matrix4[3][3] = {{1, 2}, {4}, {7, 8, 9}}; // 行ごとの部分初期化
int matrix5[3][3] = {0}; // 全要素を0で初期化
要素の入出力サンプル
可変長配列(VLA)を活用し、標準入力からサイズを指定して二次元配列を構築・出力する例を示します。
#include <stdio.h>
int main(void) {
int rows, cols;
if (scanf("%d %d", &rows, &cols) != 2) {
return 1;
}
int grid[rows][cols];
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
scanf("%d", &grid[r][c]);
printf("%4d", grid[r][c]);
}
printf("\n");
}
return 0;
}
文字配列と文字列処理
文字配列の宣言
文字を格納するための配列は char 型を用いて宣言します。
char single_str[16]; // 15文字+Null終端を格納可能な一次元配列
char multi_str[5][16]; // 5つの文字列を格納可能な二次元配列
文字配列と文字列リテラルの違い
文字の集合を表現する方法には、文字配列と文字列リテラルの2通りがあります。
char arr[] = {'C', 'o', 'd', 'e'}; // 文字配列(サイズは4)
char str[] = "Code"; // 文字列リテラル(サイズは5、末尾に'\0'が含まれる)
文字列リテラルは自動的にNull文字(\0)が末尾に付与されるため、sizeof(str) は sizeof(arr) + 1 となります。
主要な文字列操作関数
C標準ライブラリ(<string.h> および <stdio.h>)が提供する文字列操作関数を解説します。なお、バッファオーバーフローの脆弱性を持つ gets 関数はC11で削除されているため、安全な fgets を使用します。
1. 文字列の入出力 (fgets / puts)
char buffer[64];
// 標準入力から最大63文字読み込み(改行文字も含まれる場合がある)
fgets(buffer, sizeof(buffer), stdin);
// 標準出力へ文字列を出力し、末尾に改行を付与
puts(buffer);
2. 文字列長の取得 (strlen)
Null文字を除いた文字列の長さを返します。
char text[] = "Programming";
size_t length = strlen(text); // 11が返る
3. 文字列のコピー (strcpy)
コピー元からコピー先へ文字列を複製します。コピー先のバッファサイズが十分であるか確認が必要です。
char source[] = "Data";
char destination[20];
strcpy(destination, source);
4. 文字列の連結 (strcat)
既存の文字列の末尾に別の文字列を追加します。
char base[32] = "Hello";
char append[] = " World";
strcat(base, append); // baseは "Hello World" になる
5. 文字列の比較 (strcmp)
2つの文字列を辞書順で比較します。等しければ0、第一引数の方が大きければ正の値、小さければ負の値を返します。
int result = strcmp("Apple", "Banana"); // 負の値が返る
二次元文字配列の応用:最長の文字列を探索する
複数の文字列を格納した二次元文字配列から、最も長い文字列を検索する実装例です。安全な入力処理と正確な長さ比較を行っています。
#include <stdio.h>
#include <string.h>
int main(void) {
char words[5][32];
int max_length = 0;
int max_index = 0;
// 5つの文字列を入力
for (int i = 0; i < 5; i++) {
fgets(words[i], sizeof(words[i]), stdin);
// 末尾の改行文字をNull文字に置換
words[i][strcspn(words[i], "\n")] = '\0';
int current_length = strlen(words[i]);
if (current_length > max_length) {
max_length = current_length;
max_index = i;
}
}
printf("最も長い文字列: %s (文字数: %d)\n", words[max_index], max_length);
return 0;
}