C言語における二次元配列と文字配列の宣言・初期化・操作

二次元配列の基本概念

宣言とメモリ構造

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;
}

タグ: C言語 二次元配列 文字配列 文字列操作 メモリ管理

9月21日 06:02 投稿