共用体の仕組みをしらべてみましょう。
ソーラー「今のプログラム↓で
🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋
#include <stdio.h>
union Kyouyoutai {
int a;
int b;
};
int main(void)
{
union Kyouyoutai Kyouyoutaihensuu;
Kyouyoutaihensuu.a=1;
Kyouyoutaihensuu.b=2;
printf("%d\n",Kyouyoutaihensuu.a);
printf("%d\n",Kyouyoutaihensuu.b);
return 0;
}
コンパイル結果
2
2
🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋
共用体変数のメンバ変数
Kyouyoutaihensuu.a
Kyouyoutaihensuu.b
は
最後にKyouyoutaihensuu.b格納された数値2
を共有、格納することになった・・
しかし
こ、これって・・・
こうなると
共用体union Kyouyoutaiにいくら たくさん
変数宣言
int a;
int b;
int c;
int d;
int e;
・
・
・
を格納して、
変数
a
b
c
d
e
・
・
・
を
メンバ変数とし
共用体union Kyouyoutai型の
Kyouyoutaihensuuの共用体変数宣言をおこない
共用体変数Kyouyoutaihensuuのメンバ変数である
Kyouyoutaihensuu.a
Kyouyoutaihensuu.b
Kyouyoutaihensuu.c
Kyouyoutaihensuu.d
Kyouyoutaihensuu.a
Kyouyoutaihensuu.e
・
・
・
を作製し
共用体変数Kyouyoutaihensuuのメンバ変数に
たくさんの数値が格納できるようにしても
結局
[全部の共用体変数のメンバ変数に格納される値]は
ぜんぶ、ぜ~んぶ
最後に 共用体変数のメンバ変数
Kyouyoutaihensuu.a
Kyouyoutaihensuu.b
や どれでもいいや
どれかの共用体変数のメンバ変数に代入された値を
共有することでになっちゃうわけ
これだと ほんとに
いろんな数値を格納するために
変数をたくさん用意して
共用体にメンバ変数として格納しても
結局、全部同じ値が
共用体変数のメンバ変数に格納されることになっちゃうよ。
これは 一体 どういうシステムなのか・・・」
アレサ「そうですね
今度は
共用体union Kyouyoutaiに
変数宣言
int a;
char b;
を格納して
変数
a
b
をメンバ変数とし
共用体union Kyouyoutai型の
Kyouyoutaihensuuの共用体変数宣言をおこない
共用体変数Kyouyoutaihensuuのメンバ変数である
Kyouyoutaihensuu.a
Kyouyoutaihensuu.b
を作製し
それぞれ数値
512
2
を代入して
共用体の仕組みを観察してみませんか。ソーラーさん」
ソーラー「そうだね、やってみるかな~😊
プログラムはこうかな?」
#include <stdio.h>
union Kyouyoutai {
int a;
char b;
};
int main(void)
{
union Kyouyoutai Kyouyoutaihensuu;
Kyouyoutaihensuu.a=512;
Kyouyoutaihensuu.b=2;
printf("%d\n",Kyouyoutaihensuu.a);
printf("%d\n",Kyouyoutaihensuu.b);
return 0;
}
コンパイル結果
514
2
ソーラー「おおっ なんか変化がでた。
共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.a
Kyouyoutaihensuu.b
は同じ値を格納してない。
それに
Kyouyoutaihensuu.aに代入された数値は512だったけど
512に2が足された514になってる?
な、なんで?」
アレサ「はい それについては
さきのプログラム
#include <stdio.h>
union Kyouyoutai {
int a;
int b;
};
int main(void)
{
union Kyouyoutai Kyouyoutaihensuu;
Kyouyoutaihensuu.a=1;
Kyouyoutaihensuu.b=2;
printf("%d\n",Kyouyoutaihensuu.a);
printf("%d\n",Kyouyoutaihensuu.b);
return 0;
}
コンパイル結果
2
2
で
なぜコンパイル結果が
2
2
となったのか
その場合まで もどって一緒にしらべてみればわかりますの。」
ソーラー「じゃあ、そこまでもどってみるかな?」
アレサ「はいっ
int型(4バイト=32ビット)の変数に格納された数値1は
(2進数表示で)
00000000 00000000 00000000 00000001
⇧ ⇧ ⇧ ⇧
8ビット 8ビット 8ビット 8ビット
とコンピュータ内のメモリに格納されています。
先程のプログラム
#include <stdio.h>
union Kyouyoutai {
int a;
int b;
};
int main(void)
{
union Kyouyoutai Kyouyoutaihensuu;
Kyouyoutaihensuu.a=1;
Kyouyoutaihensuu.b=2;
printf("%d\n",Kyouyoutaihensuu.a);
printf("%d\n",Kyouyoutaihensuu.b);
return 0;
}
コンパイル結果
2
2
では
共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.a
には数値1がメモリ内に
00000000 00000000 00000000 00000001
と格納されました。
その次に
共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.b
に数値2がメモリ内に
00000000 00000000 00000000 00000010
と格納されました。
そうすると
共用体のシステムでは
共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.a
共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.b
ともに
最後に
共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.bに格納された
00000000 00000000 00000000 00000010
を共有することになります。」
ソーラー「な~るほど。メモリ内ではこういう状態になってるわけだ。」
アレサ「次に
🌹char型🌹(1バイト、8ビット)の変数に代入されている数値1は
(👆ここでchar型というのが重要なポイントです)
コンピュータのメモリ内で
(2進数表示で)
00000001
⇧
8ビット
と格納されています。
同様に
数値2は
00000010
と格納されています。
int型とchar型では格納容量が
1バイト、4バイトと違いがあるので
同じ数値1をメモリに格納するのにも
char型では
00000001とメモリ内に格納され
int型では
00000000 00000000 00000000 00000001
とメモリ内に格納されます
では、本題の2番目のプログラムの説明にはいりますね。
#include <stdio.h>
union Kyouyoutai {
int a;
char b;
};
int main(void)
{
union Kyouyoutai Kyouyoutaihensuu;
Kyouyoutaihensuu.a=512;
Kyouyoutaihensuu.b=2;
printf("%d\n",Kyouyoutaihensuu.a);
printf("%d\n",Kyouyoutaihensuu.b);
return 0;
}
コンパイル結果
514
2
なぜこのプログラムのコンパイル結果が
514
2
となるのでしょうか?
このプログラムにおいては、まず
数値512が
int型の
共用体変数Kyouyoutaihensuuのメンバ変数Kyouyoutaihensuu.a
に格納されています。
そのとき
512はコンピュータのメモリ内で
00000000 00000000 00000001 00000000
⇧ ⇧ ⇧ ⇧
8ビット 8ビット 8ビット 8ビット
と格納されています。
次に
char型の共用体変数Kyouyoutaihensuuのメンバ変数Kyouyoutaihensuu.bに
数値2=00000010が格納されると
⇧
8ビット
前に
int型の共用体変数のメンバ変数Kyouyoutaihensuu.aに格納された数値512が
メモリ内には
00000000 00000000 00000001 00000000
と格納されていますが
char型の共用体変数Kyouyoutaihensuuのメンバ変数Kyouyoutaihensuu.bに
数値2=00000010が格納されると
⇧
8ビット
00000000 00000000 00000001 00000000
⇧
8ビット
の8ビット⇧上に
このように↓
00000000 00000000 00000001 00000010
(10進数では514をあらわしています。)
00000010が00000000の上に上書きされます。
ですので
int型の
共用体変数Kyouyoutaihensuuのメンバ変数Kyouyoutaihensuu.a
と
char型の
共用体変数Kyouyoutaihensuuのメンバ変数Kyouyoutaihensuu.b
は
データを格納するメモリを共有しているので
数値データ
00000000 00000000 00000001 00000010を
共有することになりますが
ここで
int型の
共用体変数Kyouyoutaihensuuのメンバ変数Kyouyoutaihensuu.aには
{int型(4バイト、32ビット容量)なので}
共有された数値データ
00000000 00000000 00000001 00000010
がすべて格納される
つまり 数値514が格納されることになります
そして
char型の
共用体変数Kyouyoutaihensuuのメンバ変数Kyouyoutaihensuu.bには
{char型(1バイト、8ビット容量)なので}
共有された数値データ
00000000 00000000 00000001 00000010
の右端から
8ビット分の 00000010の数値データ
すなわち
00000010=
数値2が格納されることになります。
図で示すと
共用体変数のメンバ変数Kyouyoutaihensuu.aに格納される部分
⇩ ⇩ ⇩ ⇩
00000000 00000000 00000001 00000010
⇧
共用体変数のメンバ変数Kyouyoutaihensuu.bに格納される部分
はこのようになっています」
ソーラー
「(*´▽`*)
共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.aを数値1を代入すると
Kyouyoutaihensuu.a
Kyouyoutaihensuu.b
はint型32ビットの数値データ
00000000 00000000 00000001 00000000
を共有することになります。
char型の
共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.b
は
8ビット分しか数値データ格納容量がないので
00000000 00000000 00000001 00000000
⇧この部分
の右端から⇧で示された8ビット分
のデータ
00000000
を格納しています。
次に
char型の
共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.b
に数値2=00000010が格納されると
今 メモリに共有しているデータ
00000000 00000000 00000001 00000000
⇧この部分
の
00000000
の部分に
00000010が上書きされます
このようにして
共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.a
Kyouyoutaihensuu.b
に共有される数値データは
ひとまず
00000000 00000000 00000001 00000010
となるんだね。」
アレサ「はい
そうなのです。(*^-^*) ソーラーさん
Kyouyoutaihensuu.bに数値00000010を格納されたことによって
以前に共有された
00000000 00000000 00000001 00000000に
変更をくわえられた数値データ
00000000 00000000 00000001 00000010を
Kyouyoutaihensuu.a
Kyouyoutaihensuu.bは
共有し
int型の共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.aは
00000000 00000000 00000001 00000010
を格納し
char型の共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.bは
00000000 00000000 00000001 00000010の
右端から8ビット分の数値データ
00000010
を格納するわけです。」
ソーラー「では
先に
char型の共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.b
に数値2を
その次に
int型の共用体変数Kyouyoutaihensuuのメンバ変数
Kyouyoutaihensuu.a
に数値512を代入したら
ど~なるかな」
アレサ「それでは、プログラムを書き換えて試してみましょう。
#include <stdio.h>
union Kyouyoutai {
int a;
char b;
};
int main(void)
{
union Kyouyoutai Kyouyoutaihensuu;
Kyouyoutaihensuu.b=2;
Kyouyoutaihensuu.a=512;
/* 👆ここですね😊
今度は
Kyouyoutaihensuu.bに数値2を代入した後
Kyouyoutaihensuu.aに数値512を代入します*/
printf("%d\n",Kyouyoutaihensuu.a);
printf("%d\n",Kyouyoutaihensuu.b);
return 0;
}
コンパイル結果
512
0
アレサ「このプログラムでは
まず
Kyouyoutaihensuu.b=2;
により
char型の共用体変数のメンバ変数Kyouyoutaihensuu.bに
数値2=00000001が格納されます。
その後
Kyouyoutaihensuu.a=512;
により
int型の共用体変数のメンバ変数Kyouyoutaihensuu.aに
数値512=00000000 00000000 00000001 00000000が代入されると
この⇧最後にKyouyoutaihensuu.aに代入された数値データ
00000000 00000000 00000001 00000000
を
全ての共用体変数Kyouyoutaihensuuのメンバ変数である
Kyouyoutaihensuu.a
Kyouyoutaihensuu.b
は共有することになるわけですの。
Kyouyoutaihensuu.aはint型 容量32ビットなので
そのまま数値データ
00000000 00000000 00000001 00000000(=数値512)
を右端から32ビット分を共有、格納し
Kyouyoutaihensuu.bはchar型 容量8ビットなので
数値データ
00000000 00000000 00000001 00000000
の右端から8ビット分
00000000(=数値0)だけを共有、格納します。
ですので
Kyouyoutaihensuu.a
Kyouyoutaihensuu.b
のなかに格納されている数値を
命令文
printf("%d\n",Kyouyoutaihensuu.a);
printf("%d\n",Kyouyoutaihensuu.b);
によって表示すると
コンパイル結果
512
0
となるんですの。」
ソーラー「これが 共用体の仕組みとなっているんだね。」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます