結構體(struct)是C語言重應用比較多的一種資料結構,它可以有效的各種資料(包括各種不同類型的資料)整合
在一個資料體中,可以更好的實作程式的結構化,更友善的管理資料及其對資料的操作。
在嵌入式系統開發中,一方面由于系統資源的嚴重不足,另一方面各種變量互相通信,互相作用,正确合理使用結構體不僅可以為系統節約一部分寶貴的資源,而且還可以簡化程式的設計,使軟體設計的魯棒性和可維護性都大大增強。
以下程式都在Windows 2000+Visual C++ 6.0上調試通過。
首先考察結構體的大小(size):
struct a
{
unsigned char code;
unsigned int student;
};
如果按照各個資料的各自的大小進行累加,結構體a的size應該是:sizeof(char)+sizeof(int)=5;
而實際上,以上程式的運作結果為:the size of struct a is 8。
為什麼會出現這樣的情況?
這是因為在32位的作業系統上,作業系統組織資料是以32位(4個位元組)作為一個标準,是以各種變量的size都
一般都是4的倍數。而且結構體資料都是按照定義時所使用的順序存放的,是以盡管code變量隻會占有一個位元組,但是code+student=5>4,是以第一個4位位元組存放code,第二個4位位元組用于存放student,這樣實際上就浪
費了3個位元組。
有了上面的例子,後面的例子也就不難了解了:
struct b
{
unsigned char code;
unsigned char result;
unsigned int student;
};
結構體b的size仍然是8,code+result共2個位元組,實際上占據了4個位元組的容量,這樣就浪費了2個位元組。
以下結構體的浪費更為明顯:
struct c
{
unsigned char code;
unsigned int student;
unsigned char result;
};
結構體c的size是12,這是因為sizeof(code)<4,但是sizeof(code+student)在4與8之間,是以實際上code占
據了4個位元組,student占據了4個位元組,同樣的道理result也将占據4個位元組,sizeof(c)=12,這樣就總共浪
費了6個位元組的容量。
是以,對于潛入式系統和電子系統的設計來說,由于系統資源的不足,這方面的情況更需要格外的考慮,在
設計上更改以下資料定義的順序,有可能使得這樣的情況得到緩解。例如,結構體b和結構體c所定義的資料
實際上是相同的,因為定義的順序不同,結構體b所浪費的位元組數遠遠小于結構體c所浪費的位元組數。
比特域是一種由結構體擴充而來的資料結構組織形式,也稱為位域,占位符等。類似下面的定義:
struct card{
unsigned int pips:4;//占據4個位的長度
unsigned int suit:2;
unsigned char kq:2;
...}
跟在變量聲明後面的非負正常數是該資料所占據的比特寬度,比特寬度最多是機器字的長度,對于PC機和
Windows作業系統而言,這個值是32。一個32位的int型資料可以存放的資料範圍是極大的,在我們的程式中
往往并不需要這樣大的表示範圍,是以,使用比特域把資料壓縮到一定的表示範圍内,可以有效的節省程式
所需要的記憶體量,這在系統記憶體容量極為有限的嵌入式系統開發中是很重要的!
在上面的結構中,card變量擁有一個4比特的域pips來存貯0--15的非負整數,一個2比特的域suit來存貯
0--3以及一個2比特的域kq。
實際上,上面定義中的int和char在很多情況下也是可以省略掉的,這樣在比特域中所定義的資料結構實際上
就與這些基本類型是無關的,隻是表示一定區域的一些有符号整形數或者無符号整形數。是以,在聲明變量
的時候unsigned或者signed是必須注明的,因為編譯器需要确切的知道所定義的變量的精确取值範圍。
但是,應該注意的是:不同的編譯器對于比特域如何配置設定是有不同定義的,而且使用比特域組織的程式往往
可移植性不好,是以,除非是确實需要節省記憶體,否則比特域(包括聯合)最好不要使用。