共用体の仕組みをしらべてみましょう。

ソーラー「今のプログラム↓で


🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋


#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


となるんですの。」


ソーラー「これが 共用体の仕組みとなっているんだね。」





  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます