導入
構造体はメンバ全部の分だけメモリを使います。一方、union(共用体)は複数のメンバが同じメモリ領域を共有する型で、どれか1つの値だけを保持できます。また enum(列挙型)を使うと、0, 1, 2, ... のような数値に名前をつけて読みやすくできます。
説明
union の定義は struct とまったく同じ書き方ですが、意味が違います。メンバは同じ場所に重なって置かれるので、sizeof はメンバの中で一番大きいものと同じになります。
#include <stdio.h>
union Data {
int i;
float f;
char c;
};
int main(void) {
union Data d;
d.i = 65;
printf("i=%d\n", d.i);
printf("c=%c\n", d.c); // 同じ場所を1バイトだけ文字として読む → 'A'(65のASCII文字)
printf("size=%zu\n", sizeof(d)); // メンバの最大サイズ(構造体なら合計サイズになるところ)
return 0;
}
flowchart TB
subgraph S["struct(別々の場所)"]
direction LR
s1["i(4バイト)"]
s2["f(4バイト)"]
end
subgraph U["union(同じ場所を共有)"]
direction LR
u1["i と f と c が<br/>同じアドレスを指す"]
end
enum は名前つきの整数定数の集まりです。何も書かなければ 0 から順に振られます。
#include <stdio.h>
enum Color { RED, GREEN, BLUE }; // RED=0, GREEN=1, BLUE=2
int main(void) {
enum Color c = GREEN;
printf("%d\n", c); // 1
switch (c) {
case RED: printf("red\n"); break;
case GREEN: printf("green\n"); break;
case BLUE: printf("blue\n"); break;
}
return 0;
}
RED や GREEN は、実際にはただの int(0, 1, 2, …)ですが、名前がついているおかげで switch や if の条件が「何を表しているか」を読みやすくなります。
やってみよう
union Data に d.f = 3.14; を入れてから d.i を表示すると、期待した 3.14 にはならないことを確かめましょう(同じ場所を違う型として読んでいるためです)。enum Color の値を BLUE に変えて switch の結果が変わることも確かめてください。
演習
enum Weekday { SUN, MON, TUE, WED, THU, FRI, SAT }; を定義してください。enum Weekday day = WED; として、まず printf("%d\n", day); で数値を1行表示し、続けて if 文で day が SUN または SAT なら「休日」、それ以外なら「平日」と表示してください(WED なら 3 と 平日 の2行になります)。
ヒント1を見る
enum Weekday { SUN, MON, TUE, WED, THU, FRI, SAT }; は SUN=0 から順に番号が振られます。
ヒント2を見る
if (day == SUN || day == SAT) { ... } else { ... } の形で分けます。