MA-SATANのエンジニアブログ

とある大阪の日本酒Loveなエンジニアの開発ブログ

C/C++ 配列変数の宣言時の初期化方法あれこれ

配列変数時の宣言方法を整理してみました。
C言語の配列変数の初期化方法は複数ありますが、意味は同じです。こういうのをシンタックスシュガーと言うみたいです。charの多次元配列なんかは、時々書き方を忘れるので復習、復習。。。

数値型の1次元配列の宣言時の初期化

#include <stdio.h>

int main(int argc, char* argv[])
{
    int number1[]  = {1, 2, 3};
    int number2[3] = {4, 5, 6};

    printf("number1=%d,%d,%d\n", number1[0], number1[1], number1[2]);
    printf("number2=%d,%d,%d\n", number2[0], number2[1], number2[2]);

    return 0;
}

=== 実行結果 ===
number1=1,2,3
number2=4,5,6

ちなみに、要素数を指定して初期化する場合に、要素数以上の値を入れると警告が出ます。実行時にnumber[2]などの範囲外の値を見ると、代入した値は入っていません。

int main(int argc, char* argv[])
{
    int number1[]  = {1, 2, 3};
    int number2[2] = {4, 5, 6};  /* 配列数2で宣言しているのに、3個代入している */

    printf("number1=%d,%d,%d\n", number1[0], number1[1], number1[2]);
    printf("number2=%d,%d,%d\n", number2[0], number2[1], number2[2]);

    return 0;
}

=== コンパイル結果 ===
In function ‘main’:
警告: 配列初期化子内の要素が多すぎます
警告: (near initialization for ‘number2’)

文字型(char)の1次元配列の宣言時の初期化

鍵かっこ({})を付ける方法、ダブルクォート("")を付ける方法の2通りあります。
素数を書略した場合は、最後に'\0'を挿入してくれます。要素数を指定する場合、最後の'\0'を考慮したサイズを設定するように!

#include <stdio.h>

int main(int argc, char* argv[])
{
    char str1[]  = "1abcd";
    char str2[]  = {'2', 'a', 'b', 'c', 'd'};
    char str3[6]  = "3abcd";
    char str4[6] = {'4', 'a', 'b', 'c', 'd'};

    printf("str1=%s\n", str1);
    printf("str2=%s\n", str2);
    printf("str3=%s\n", str3);
    printf("str4=%s\n", str4);

    return 0;
}

=== 実行結果 ===
str1=1abcd
str2=2abcd
str3=3abcd
str4=4abcd

多次元配列の宣言時の初期化

一番迷うのが多次元配列の宣言&初期化ではないでしょうか。
読み取り専用データであれば、要素数を省略する書き方が楽ですね。

#include <stdio.h>

int main(int argc, char* argv[])
{
    char str1[3][6] = {"1abcd", "12345", "zzzzz"}; /* 要素数を指定 */
    char str2[][6]  = {"2abcd", "12345", "zzzzz"}; /* 1次元目の要素数を省略 */
    char *str3[6]   = {"3abcd", "12345", "zzzzz"}; /* charポインタ、配列の組合せ */
    char *str4[]    = {"4abcd", "12345", "zzzzz"}; /* charポインタ、配列の組合せ */

    int num1[][3]   = { {1,2,3}, {100,200,300}, {-1, -2, -3} };

    printf("str1[0]=%s\tstr1[1]=%s\tstr1[2]=%s\n", str1[0], str1[1], str1[2]);
    printf("str2[0]=%s\tstr2[1]=%s\tstr2[2]=%s\n", str2[0], str2[1], str2[2]);
    printf("str3[0]=%s\tstr3[1]=%s\tstr3[2]=%s\n", str3[0], str3[1], str3[2]);
    printf("str4[0]=%s\tstr3[1]=%s\tstr3[2]=%s\n", str4[0], str4[1], str4[2]);

    printf("num1[0] = %d,%d,%d\n", num1[0][0], num1[0][1], num1[0][2]);
    printf("num1[1] = %d,%d,%d\n", num1[1][0], num1[1][1], num1[1][2]);
    printf("num1[2] = %d,%d,%d\n", num1[2][0], num1[2][1], num1[2][2]);
    return 0;
}

=== 実行結果 ===
str1[0]=1abcd   str1[1]=12345   str1[2]=zzzzz
str2[0]=2abcd   str2[1]=12345   str2[2]=zzzzz
str3[0]=3abcd   str3[1]=12345   str3[2]=zzzzz
str4[0]=4abcd   str3[1]=12345   str3[2]=zzzzz
num1[0] = 1,2,3
num1[1] = 100,200,300
num1[2] = -1,-2,-3