こんにちは、ナナです。
構造体、列挙型に続いて、共用体のunionを紹介しましょう。
共用体は実践で使用することは多くありませんが、C言語に共用体という仕組みがあることは知っておきましょう。
構造体と似ている部分もあるので、知らない方はこちらの記事を事前に読んでおくとよいです。
本記事では次の疑問点を解消する内容となっています。
では、共用体の使い方を学んでいきましょう。
共用体ってそもそも何?捉え方を学ぶ
ほーい。就職したら1人暮らししたいんです。家具屋さんに行ったら、ソファーとベッドが一緒になったソファーベッドってやつがあったんです。あれって一挙両得で欲しくなりましたー!
時には2人で分けて座り、時には1人で大きなベッドとして使う。使いたいシーンで用途が分けられるのが、ソファーベッドの良さだよね。
じゃあ、今日はメモリを複数の用途で使うことができる機能「共用体」を紹介しようね。
ソファーベッドは、とある空間を「ソファー」と「ベッド」という2つの用途として使い方を変えられる家具ですね。
共用体は、とあるメモリ領域を複数のデータ型でアクセスできる仕組みを提供します。これはまさしく、メモリのソファーベッドですね。
共用体の定義方法と使い方
はい、はーい。メモリを共用?ど、ど、ど、どういう意味ですかー?全然イメージが掴めてませーん。
そうだね。共用体は少しイメージが掴みづらい機能なんだよね。具体的なメモリを示しながら解説するね。
共用体の型定義
共用体は「union」というキーワードを使って定義します。
定義の形は構造体と似ており、typedefを利用して定義するのがこちらも一般的です。例としてソファーベッドを共用体で定義してみましょう。
// ソファーベッド共用体
typedef union
{
char sofa[2]; // ソファー[2人掛け]
short bed; // ベッド[1名用]
} U_SOFABED;
この共用体の型定義が、一体どのような効果をもたらすのでしょう。プログラムから変数を使って確認してみましょう。
共用体の変数を使ったプログラム
構造体の場合は、構造体メンバが並んだ順にメモリが確保されます。共用体の場合は、各共用体メンバの開始位置が同じ場所から配置されます。
つまり、重なっているメモリ部分は、共用体メンバがメモリを共用(シェア)します。
それでは具体的に共用体の変数定義を行い、各共用体メンバにアクセスしてみましょう。
#include <stdio.h>
// ソファーベッド共用体
typedef union
{
char sofa[2]; // ソファー[2人掛け]
short bed; // ベッド[1名用]
} U_SOFABED;
int main(void)
{
// ソファーベッドの変数定義
U_SOFABED sofabed;
// ソファーとして1バイト単位でアクセス
sofabed.sofa[0] = 0x12;
sofabed.sofa[1] = 0x34;
// ベッドとして2バイトでアクセス
sofabed.bed = 0x5678;
return 0;
}
ソファとして1バイト単位でアクセス
ベッドとして2バイトでアクセス
このように、同じメモリに対して各共用体メンバで、異なるアクセスが可能になります。
Q&A:共用体でよくある質問
Q:共用体ってどんなときに使うの?
質問、はい、はーい。結局、共用体ってどんな時使うんですか?
これはシンプルだけど答えづらい質問だね。共用体はかなり癖の強い機能なので、実践的に利用されるシーンは限られているね。
共用体を有効活用するシーンはかなり限定的なものです。
組み込み開発では共用体を使った特殊なデータ構造を使用することがあります。マイコン入門編では非常に効果的な使い方があるのですが、その時に解説をしましょう。