Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C言語の指定初期化子(designated initializer)の使い方を解説

C90規格では、配列はインデックス0、1、2…というように固定された順序で初期化しなければなりませんでした。しかし、C99規格からは指定初期化子(designated initializer)という機能が導入され、要素を任意の順序で初期化できるようになっています。初期化には配列のインデックス、あるいは構造体のメンバー名を使用できます。なお、この拡張機能はGNU C++では実装されていない点に注意してください。

特定のインデックスに値を指定して初期化する場合は、次のように記述します。

int arr[6] = {[3] = 20, [5] = 40}; または
int arr[6] = {[3]20, [5]40};

これは、以下の記述と同じ意味になります。

int arr[6] = {0, 0, 0, 20, 0, 40};

明示的に初期化されなかった要素は、自動的に0で埋められます。

また、「[first … last] = value」という構文を使うと、範囲を指定して複数の要素を一括で初期化することも可能です。

int arr[6] = {[2 … 4] = 10};

この結果は以下と同等になります。

int arr[6] = {0, 0, 10, 10, 10, 0};

さらに、配列のサイズを宣言時に指定しなかった場合でも、指定された最大のインデックス位置をもとに配列サイズが自動的に決定されます。実際のコードで動作を確認してみましょう。

サンプルコード

#include <stdio.h>
int main() {
    int Array[] = {10, 20, 30, [3 ... 9] = 100, [10] = 65, 15, [80] = 50, [42] = 400 };
    int i;
    for (i = 0; i < 20; i++)
        printf("%d ", Array[i]);
    printf("\nArray[%d] = %d\n", 80, Array[80]);
    printf("Array[%d] = %d\n", 42, Array[42]);
    printf("Size of this array: %ld\n", sizeof(Array) / sizeof(Array[0]));
}

出力結果

10 20 30 100 100 100 100 100 100 100 65 15 0 0 0 0 0 0 0 0
Array[80] = 50
Array[42] = 400
Size of this array: 81

この例では、インデックス3〜9がすべて100で初期化され、続くインデックス10に65、その次の11に15が代入されています。さらに、インデックス80と42への代入により、配列全体のサイズは81要素として確保されています。

指定初期化子は、構造体や共用体のオブジェクトに対しても利用できます。この場合、メンバー変数名の先頭にドット(.)を付け、任意の順序で初期化を行います。具体的には、以下のコードをご覧ください。

サンプルコード

#include <stdio.h>
struct myStruct {
    int x;
    float y;
    char z;
};
int main() {
    struct myStruct str1 = {.y = 2.324, .z = 'f', .x = 78};
    struct myStruct str2 = {.z = 'r'};
    printf("x = %d, y = %f, z = %c\n", str1.x, str1.y, str1.z);
    printf("z = %c\n", str2.z);
}

出力結果

x = 78, y = 2.324000, z = f
z = r

str1では、メンバーの宣言順とは異なる順序(y、z、x)で初期化していますが、各メンバーに正しく値が設定されていることがわかります。一方、str2のように一部のメンバーだけを初期化した場合、指定されていないメンバーは0で初期化されます。このように指定初期化子を使うと、可読性の高い柔軟な初期化処理を記述できます。

  1. C言語の指定初期化子(designated initializer)の使い方を解説

    C90規格では、配列はインデックス0、1、2…というように固定された順序で初期化しなければなりませんでした。しかし、C99規格からは指定初期化子(designated initializer)という機能が導入され、要素を任意の順序で初期化できるようになっています。初期化には配列のインデックス、あるいは構造体のメンバー名を使用できます。なお、この拡張機能はGNU C++では実装されていない点に注意してください。 特定のインデックスに値を指定して初期化する場合は、次のように記述します。 int arr[6] = {[3] = 20, [5] = 40}; または int arr[6] = {[3]

  2. C++17で導入されたif文・switch文の初期化ステートメント(init-statement)の使い方

    プログラミングでは、関数が返した値を検証し、その値に応じて条件分岐の処理を行いたい場面が数多くあります。従来のC++では、次のようにコードを書くのが一般的でした。// 何らかのメソッドまたは関数 return_type foo(Params); // 引数を渡して関数を呼び出し、 // 戻り値をvar1に格納する auto var1 = foo(Params); if (var1 == /* 何らかの値 */) { // 何らかの処理を行う } else { // 別の処理を行う }上記のコードは、一般的なif-elseブロックの形式に従っています。まず変数をセットアップする