【C言語】配列を初期化する方法を解説

この記事では、C言語で配列を初期化する方法について詳しく解説します。

配列の初期化は、プログラムの動作を安定させるために非常に重要です。

静的初期化と動的初期化の違いや、多次元配列の初期化方法、そして初期化時の注意点について学びます。

初心者の方でも理解しやすいように、具体的なサンプルコードとその実行結果を交えて説明しますので、ぜひ参考にしてください。

目次から探す

配列の初期化方法

C言語では、配列を初期化する方法がいくつかあります。

ここでは、静的初期化と動的初期化の方法について詳しく解説します。

静的初期化

静的初期化とは、プログラムのコンパイル時に配列の初期値を設定する方法です。

以下に、静的初期化の具体的な方法を紹介します。

宣言と同時に初期化

配列を宣言すると同時に初期化する方法です。

以下の例では、整数型の配列を初期化しています。

#include <stdio.h>
int main() {
    int array[5] = {1, 2, 3, 4, 5}; // 配列の宣言と同時に初期化
    for (int i = 0; i < 5; i++) {
        printf("%d ", array[i]);
    }
    return 0;
}

このコードを実行すると、配列の各要素が初期化されていることが確認できます。

部分的な初期化

配列の一部の要素だけを初期化することも可能です。

未初期化の要素はデフォルトで0になります。

#include <stdio.h>
int main() {
    int array[5] = {1, 2}; // 部分的に初期化
    for (int i = 0; i < 5; i++) {
        printf("%d ", array[i]);
    }
    return 0;
}

このコードを実行すると、出力は 1 2 0 0 0 となります。

サイズを省略した初期化

配列のサイズを省略して初期化することもできます。

この場合、初期化リストの要素数が配列のサイズになります。

#include <stdio.h>
int main() {
    int array[] = {1, 2, 3, 4, 5}; // サイズを省略して初期化
    for (int i = 0; i < 5; i++) {
        printf("%d ", array[i]);
    }
    return 0;
}

このコードを実行すると、出力は 1 2 3 4 5 となります。

動的初期化

動的初期化とは、プログラムの実行時にメモリを動的に確保して配列を初期化する方法です。

以下に、動的初期化の具体的な方法を紹介します。

malloc関数を使った初期化

malloc関数を使ってメモリを動的に確保し、配列を初期化する方法です。

#include <stdio.h>
#include <stdlib.h>
int main() {
    int *array = (int *)malloc(5 * sizeof(int)); // メモリを動的に確保
    for (int i = 0; i < 5; i++) {
        array[i] = i + 1; // 配列を初期化
    }
    for (int i = 0; i < 5; i++) {
        printf("%d ", array[i]);
    }
    free(array); // メモリを解放
    return 0;
}

このコードを実行すると、出力は 1 2 3 4 5 となります。

calloc関数を使った初期化

calloc関数を使うと、メモリを確保すると同時に0で初期化することができます。

#include <stdio.h>
#include <stdlib.h>
int main() {
    int *array = (int *)calloc(5, sizeof(int)); // メモリを動的に確保し、0で初期化
    for (int i = 0; i < 5; i++) {
        printf("%d ", array[i]);
    }
    free(array); // メモリを解放
    return 0;
}

このコードを実行すると、出力は 0 0 0 0 0 となります。

realloc関数を使った再初期化

realloc関数を使って、既に確保されたメモリのサイズを変更することができます。

#include <stdio.h>
#include <stdlib.h>
int main() {
    int *array = (int *)malloc(3 * sizeof(int)); // メモリを動的に確保
    for (int i = 0; i < 3; i++) {
        array[i] = i + 1; // 配列を初期化
    }
    array = (int *)realloc(array, 5 * sizeof(int)); // メモリを再確保
    for (int i = 3; i < 5; i++) {
        array[i] = i + 1; // 新しい要素を初期化
    }
    for (int i = 0; i < 5; i++) {
        printf("%d ", array[i]);
    }
    free(array); // メモリを解放
    return 0;
}

このコードを実行すると、出力は 1 2 3 4 5 となります。

以上が、C言語における配列の初期化方法です。

静的初期化と動的初期化の違いを理解し、適切な方法を選択することが重要です。

多次元配列の初期化

C言語では、一次元配列だけでなく、二次元や三次元以上の多次元配列も扱うことができます。

ここでは、二次元配列と三次元以上の配列の初期化方法について解説します。

二次元配列の初期化

二次元配列は、行と列の二つの次元を持つ配列です。

以下に、二次元配列の静的初期化と動的初期化の方法を説明します。

静的初期化

静的初期化では、配列の宣言と同時に初期化を行います。

以下に例を示します。

#include <stdio.h>
int main() {
    // 二次元配列の静的初期化
    int matrix[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
    // 配列の内容を表示
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
    return 0;
}

このコードでは、3×3の二次元配列 matrix を宣言し、同時に初期化しています。

各要素は {} を使って行ごとに初期化されています。

動的初期化

動的初期化では、メモリを動的に確保して配列を初期化します。

以下に例を示します。

#include <stdio.h>
#include <stdlib.h>
int main() {
    int rows = 3;
    int cols = 3;
    // 二次元配列の動的初期化
    int **matrix = (int **)malloc(rows * sizeof(int *));
    for (int i = 0; i < rows; i++) {
        matrix[i] = (int *)malloc(cols * sizeof(int));
    }
    // 配列の初期化
    int value = 1;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = value++;
        }
    }
    // 配列の内容を表示
    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;
}

このコードでは、3×3の二次元配列を動的に確保し、各要素に値を設定しています。

最後に、確保したメモリを解放しています。

三次元以上の配列の初期化

三次元以上の配列も同様に初期化できます。

ここでは、三次元配列の静的初期化と動的初期化の方法を説明します。

静的初期化

三次元配列の静的初期化は、二次元配列と同様に宣言と同時に行います。

以下に例を示します。

#include <stdio.h>
int main() {
    // 三次元配列の静的初期化
    int tensor[2][2][2] = {
        {
            {1, 2},
            {3, 4}
        },
        {
            {5, 6},
            {7, 8}
        }
    };
    // 配列の内容を表示
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            for (int k = 0; k < 2; k++) {
                printf("%d ", tensor[i][j][k]);
            }
            printf("\n");
        }
        printf("\n");
    }
    return 0;
}

このコードでは、2x2x2の三次元配列 tensor を宣言し、同時に初期化しています。

各要素は {} を使って初期化されています。

動的初期化

三次元配列の動的初期化は、二次元配列の動的初期化と同様に行いますが、次元が増えるため少し複雑になります。

以下に例を示します。

#include <stdio.h>
#include <stdlib.h>
int main() {
    int x = 2;
    int y = 2;
    int z = 2;
    // 三次元配列の動的初期化
    int ***tensor = (int ***)malloc(x * sizeof(int **));
    for (int i = 0; i < x; i++) {
        tensor[i] = (int **)malloc(y * sizeof(int *));
        for (int j = 0; j < y; j++) {
            tensor[i][j] = (int *)malloc(z * sizeof(int));
        }
    }
    // 配列の初期化
    int value = 1;
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            for (int k = 0; k < z; k++) {
                tensor[i][j][k] = value++;
            }
        }
    }
    // 配列の内容を表示
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            for (int k = 0; k < z; k++) {
                printf("%d ", tensor[i][j][k]);
            }
            printf("\n");
        }
        printf("\n");
    }
    // メモリの解放
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            free(tensor[i][j]);
        }
        free(tensor[i]);
    }
    free(tensor);
    return 0;
}

このコードでは、2x2x2の三次元配列を動的に確保し、各要素に値を設定しています。

最後に、確保したメモリを解放しています。

以上が、二次元配列および三次元以上の配列の初期化方法です。

静的初期化と動的初期化の違いを理解し、適切な方法を選択することが重要です。

配列初期化の注意点

配列を初期化する際にはいくつかの注意点があります。

これらの注意点を理解しておくことで、プログラムのバグを防ぎ、効率的なコードを書くことができます。

初期化されていない配列の挙動

C言語では、配列を宣言しただけでは自動的に初期化されません。

初期化されていない配列の要素には不定値が入っており、これを使用すると予期しない動作を引き起こす可能性があります。

#include <stdio.h>
int main() {
    int arr[5]; // 初期化されていない配列
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]); // 不定値が出力される
    }
    return 0;
}

このコードを実行すると、配列 arr の要素には不定値が含まれているため、予測できない値が出力されます。

これを防ぐためには、配列を宣言と同時に初期化するか、明示的に初期化する必要があります。

メモリリークの防止

動的に配列を初期化する場合、メモリリークを防ぐために確実にメモリを解放することが重要です。

malloccalloc で確保したメモリは、使用後に free 関数で解放しなければなりません。

#include <stdio.h>
#include <stdlib.h>
int main() {
    int *arr = (int *)malloc(5 * sizeof(int)); // 動的に配列を初期化
    if (arr == NULL) {
        printf("メモリの確保に失敗しました\n");
        return 1;
    }
    for (int i = 0; i < 5; i++) {
        arr[i] = i * 2;
    }
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    free(arr); // メモリを解放
    return 0;
}

このコードでは、malloc で確保したメモリを使用後に free で解放しています。

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

配列のサイズと初期化データの関係

配列のサイズと初期化データの数が一致していない場合、C言語は不足している要素をゼロで初期化します。

逆に、初期化データが配列のサイズを超える場合、コンパイルエラーが発生します。

#include <stdio.h>
int main() {
    int arr[5] = {1, 2}; // 残りの要素はゼロで初期化される
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]); // 1 2 0 0 0 が出力される
    }
    printf("\n");
    // int arr2[2] = {1, 2, 3}; // コンパイルエラー: 初期化データが多すぎる
    return 0;
}

このコードでは、配列 arr のサイズは5ですが、初期化データは2つしかありません。

そのため、残りの要素はゼロで初期化されます。

逆に、コメントアウトされた部分のように、初期化データが配列のサイズを超える場合はコンパイルエラーが発生します。

これらの注意点を理解し、適切に配列を初期化することで、より安全で効率的なプログラムを書くことができます。

まとめ

この記事では、C言語における配列の初期化方法について詳しく解説しました。

配列の初期化は、プログラムの安定性や効率性に大きく影響する重要な要素です。

この記事を参考に、適切な初期化方法を選択し、効果的なプログラミングを行ってください。

目次から探す