C言語に関する補足
Copyright(C)24Aug2008
coskx
TNCT
1.ビットフィールド
ビットフィールドは1ビットの変数や4ビットの変数を用いる時に使われる。Cの文法の範囲であるが通常のプログラミングでは,あまり使われていない。マイクロコンピュータプログラミングでは時々使われている。
次のプログラムは1ビットの変数を使った例である。1ビットの変数なので,とりうる値は0と1しかないため,1ずつ増加させると,すぐに桁あふれするので,0と1を繰り返すこととなる。
ビットフィールドは構造体のメンバ変数としてのみ使用が許されている。
List 1.1 1ビットの変数を使ったプログラム (PC用のコンパイラでコンパイルしてPC上で実行) |
#include<stdio.h> typedef struct { int main() |
実行結果 |
i=0 x.test=0 i=1 x.test=1 i=2 x.test=0 i=3 x.test=1 i=4 x.test=0 |
複数の変数の例
変数 test は1ビットの変数
変数 testa は2ビットの変数(とりうる値は0,1,2,3)
List 1.2 1ビットの変数と2ビットの変数を使ったプログラム (PC用のコンパイラでコンパイルしてPC上で実行) |
#include<stdio.h> typedef struct { int main() |
実行結果 |
i=0 x.test=0 x.testa=0 i=1 x.test=1 x.testa=1 i=2 x.test=0 x.testa=2 i=3 x.test=1 x.testa=3 i=4 x.test=0 x.testa=0 |
2.共用体(union)
同じメモリを2つ以上の名前で使うことができる。例えば,unsigned long intの変数は4バイトでできているが,同じメモリを,unsigned short int(2バイト)の変数2個,あるいはunsigned char(1バイト)の変数4個として使うことができる。
しかし,多バイト変数をメモリにどのように置くかは,CPU開発者に依存している。WindowsPCなどIntel系のCPUは下位バイトをメモリの若い番地に置くようにしているので,リトルエンディアン(little endian)と呼ばれ,H8のようなMotorola系のCPUは上位バイトをメモリの若い番地に置くようにしているためビッグエンディアン(big endian)と呼ばれている。そのため,同じプログラムでも結果が異なってしまう。
List 2.1 共用体を使ったプログラム(WinPC リトルエンディアン) (PC用のコンパイラでコンパイルしてPC上で実行) | ||||
#include<stdio.h> typedef union { int main() | ||||
実行結果 | ||||
12345678 5678 1234 78 56 34 12 | ||||
「x.test=0x12345678;」の実行直後
|
List 2.2 共用体を使ったプログラム(H8 ビッグエンディアン) | ||||
#include "h8-01.h" typedef union { int main() | ||||
実行結果 | ||||
12345678 1234 5678 12 34 56 78 | ||||
「x.test=0x12345678;」の実行直後
|
3.共用体(union)とビットフィールド
共用体とビットフィールドを用いた場合も,エンディアンの違いに気をつけて使わなければならない。
次の例は,1バイト(8ビット)の変数と,2ビット+2ビット+4ビットの変数を共用体としたものである。
List 3.1 共用体とビットフィールドを使ったプログラム(WinPC リトルエンディアン) (PC用のコンパイラでコンパイルしてPC上で実行) | ||||||||||||||||||||||||||||||||||||||||||||
#include<stdio.h> typedef struct { typedef union { int main() | ||||||||||||||||||||||||||||||||||||||||||||
実行結果 | ||||||||||||||||||||||||||||||||||||||||||||
51 1 1 1 71 1 3 1 | ||||||||||||||||||||||||||||||||||||||||||||
「x.test=0x51;」の実行直後
「x.test1.dual0=3;」の実行直後
|
List 3.2 共用体とビットフィールドを使ったプログラム(H8 ビッグエンディアン) (H8用クロスコンパイラでコンパイルしてH8上で実行) | ||||||||||||||||||||||||||||||||||||||||||||
#include "h8-01.h" typedef struct { typedef union { int main()
x.test=0x51; | ||||||||||||||||||||||||||||||||||||||||||||
実行結果 | ||||||||||||||||||||||||||||||||||||||||||||
51 5 0 1 5d 5 3 1 | ||||||||||||||||||||||||||||||||||||||||||||
「x.test=0x51;」の実行直後
「x.test1.dual0=3;」の実行直後
|