天天看點

C語言:結構體相關

 結構體(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是必須注明的,因為編譯器需要确切的知道所定義的變量的精确取值範圍。

但是,應該注意的是:不同的編譯器對于比特域如何配置設定是有不同定義的,而且使用比特域組織的程式往往

可移植性不好,是以,除非是确實需要節省記憶體,否則比特域(包括聯合)最好不要使用。