11.構造体

11-6. 構造体の中の構造体

◇構造体の中の構造体

構造体の中に構造体(言いかえれば構造体を含む構造体)を定義するには2通りの方法があります。

(1) 構造体の中で構造体を宣言する
(2) 構造体の中で構造体を定義・宣言する

1.構造体の中で構造体を宣言する場合

#include<stdio.h>

struct st_child {
        int a,b;
        char c;
};

struct st_parent{
        char ch;
        struct st_child s1;  /* ここで宣言されている */
        int i,j;
};

main()
{
        struct st_parent st1 = {'A', 1, 2, 'E', 5, 6};
        struct st_child  st2 = {10, 11, 'F'};
        printf("st1.ch   = %c\n",st1.ch);
        printf("st1.s1.a = %d\n",st1.s1.a);
        printf("st1.s1.b = %d\n",st1.s1.b);
        printf("st1.s1.c = %c\n",st1.s1.c);
        printf("st1.i    = %d\n",st1.i);
        printf("st1.j    = %d\n\n",st1.j);

        printf("st2.a = %d\n",st2.a);
        printf("st2.b = %d\n",st2.b);
        printf("st2.c = %c\n",st2.c);

        return;
}

/* 結果
st1.ch   = A
st1.s1.a = 1
st1.s1.b = 2
st1.s1.c = E
st1.i    = 5
st1.j    = 6

st2.a = 10
st2.b = 11
st2.c = F
*/

 説明しやすいように構造体名をそれぞれ st_parent, st_child にしてみました。
 結果としてst_parent(親)内にst_child(子)を宣言したので親が子を含む形になりました。

 ちなみにメモリーの構造は次のようになります。

<struct st_child st2>
+—————-+
int a | |
+—————-+
int b | |
+——–+——-+
char c | |
+——–+

<struct st_parent st1>
+——–+
char ch | |
+——–+——-+
st_child s1 | |
| |
| |
| +——-+
| |
+——–+——-+
int i | |
+—————-+
int j | |
+—————-+

変数の順番も宣言された通りになるので初期化も順番どおりでかまいません。
また、注意点として、この例の場合、st_child はst_parentで宣言される前に定義しておく必要があり、必然的にst_parentの定義より前に記述されなければなりません。

2.構造体の中で構造体を定義・宣言する場合

#include<stdio.h>

struct st_parent{
        char ch;
        struct st_child { /* ここで定義と宣言 */
                int a,b;
                char c;
        }s1;
        int i,j;
};

main()
{
        struct st_parent st1 = {'A', 1, 2, 'E', 5, 6};
        struct st_child  st2 = {10, 11, 'F'};
        printf("st1.ch   = %c\n",st1.ch);
        printf("st1.s1.a = %d\n",st1.s1.a);
        printf("st1.s1.b = %d\n",st1.s1.b);
        printf("st1.s1.c = %c\n",st1.s1.c);
        printf("st1.i    = %d\n",st1.i);
        printf("st1.j    = %d\n\n",st1.j);

        printf("st2.a = %d\n",st2.a);
        printf("st2.b = %d\n",st2.b);
        printf("st2.c = %c\n",st2.c);

        return;
}

/* 結果
st1.ch   = A
st1.s1.a = 1
st1.s1.b = 2
st1.s1.c = E
st1.i    = 5
st1.j    = 6

st2.a = 10
st2.b = 11
st2.c = F
*/

 結果としてはさっきの1とまったく同じです。
ただ、st_parentの中にst_childの定義を含めるか含めないかの違いです。
st_childをst_parentに含んでしまってもst_childだけの宣言は可能です。

3.ビットフィールドや共用体等を含める

 ビットフィールドは構造体の中で宣言されるのでここで説明するまでもないのですが、構造体中に共用体を含むことが可能です。
 もちろん1と2のどちらの方法でも可能です。