C語(yǔ)言中位域的詳解
C 語(yǔ)言中位域的詳解在對(duì)STM8L 進(jìn)行引腳的位控制時(shí),看到了很多類似下面的定義:typedefstruct{unsigned char PORF : 1;unsigned char I
C 語(yǔ)言中位域的詳解
在對(duì)STM8L 進(jìn)行引腳的位控制時(shí),看到了很多類似下面的定義:
typedefstruct
{
unsigned char PORF : 1;
unsigned char IWDGF : 1;
unsigned char ILLOPF : 1;
unsigned char SWIMF : 1;
} __BITS_RST_SR;
從而引發(fā)了對(duì)C 語(yǔ)言中位域的探索,至今至少弄明白了一些,記下來(lái)。 首先引用百度文庫(kù)中關(guān)于位域的探討:
有些信息在存儲(chǔ)時(shí),并不需要占用一個(gè)完整的字節(jié),而只需占幾個(gè)或一個(gè)二進(jìn)制位。例如在存放一個(gè)開(kāi)關(guān)量時(shí),只有0和1 兩種狀態(tài),用一位二進(jìn)位即可。為了節(jié)省存儲(chǔ)空間,并使處理簡(jiǎn)便,C 語(yǔ)言又提供了一種數(shù)據(jù)結(jié)構(gòu),稱為“位域”或“位段”。所謂“位域”是把一個(gè)字節(jié)中的二進(jìn)位劃分為幾個(gè)不同的區(qū)域,并說(shuō)明每個(gè)區(qū)域的位數(shù)。每個(gè)域有一個(gè)域名,允許在程序中按域名進(jìn)行操作。這樣就可以把幾個(gè)不同的對(duì)象用一個(gè)字節(jié)的二進(jìn)制位域來(lái)表示。一、位域的定義和位域變量的說(shuō)明位域定義與結(jié)構(gòu)定義相仿,其形式為: struct 位域結(jié)構(gòu)名
{ 位域列表 };
其中位域列表的形式為:類型說(shuō)明符位域名:位域長(zhǎng)度
經(jīng)過(guò)上面位域的解釋,基本上對(duì)其中所占1位的位域操作有所了解,例如: Struct x
{
Unsigned char a :1;
}
x.a=1;或者x.a=0;
這樣便可以將單位賦值成0或者1。
那么這樣我們便產(chǎn)生一個(gè)疑問(wèn),若是定義的位域不是1位而是多位呢?例如 Struct x
{
Unsigned char a:4;
}
x.a=0110;可以這樣賦值嗎?
經(jīng)過(guò)一番不嚴(yán)謹(jǐn)?shù)牟樵兒途幊舔?yàn)證,在VS2010軟件條件下,編寫(xiě)一個(gè)C 語(yǔ)言輸出小程序,如下(主要寫(xiě)關(guān)鍵代碼)例一:
Struct x
{
Unsigned char a:4;
}
x.a=0xF;
,printf("x",x.a);
這樣輸出為F 。之所以這樣寫(xiě)程序,由于x.a 定義為只有4位的變量,賦值時(shí)用十六進(jìn)制來(lái)表示所要的數(shù)值,若想賦值一個(gè)二進(jìn)制,在這樣的軟件條件下也可以這樣賦值:x.a=1111;那么輸出x.a 變量時(shí)結(jié)果也是F 。為什么會(huì)這樣?
我認(rèn)為無(wú)論在程序語(yǔ)句中我們?cè)趺唇o一個(gè)變量賦值,其實(shí)在物理存儲(chǔ)時(shí)都是以二進(jìn)制保存的,所以只要在編譯器允許的條件下上述兩種賦值都是可以。下面將下單片機(jī)的軟件環(huán)境可以在賦值上有些限定,例如有的賦值二進(jìn)制需要:x.a=0b1111;
還有看見(jiàn)有些百度知道或者論壇帖子上有人出現(xiàn)過(guò)輸出結(jié)果并不是他想要的,例如:例二
賦值結(jié)果讓人想不通:
typedefstruct _ss_
{
int a:2;
int b:2;
int c:2;
int d:1;
}ss;
ssff;
intuu
ff.a=1;
ff.b=2;
ff.c=3;
ff.d=4;
uu = ff.a; //uu結(jié)果為1,沒(méi)疑問(wèn)
uu = ff.b; //uu結(jié)果為0xfffffffe ,為什么?不是應(yīng)該是2嗎? uu = ff.c; //uu結(jié)果為0xffffffff, 為什么?我覺(jué)得應(yīng)該是3啊
uu = ff.d; //uu結(jié)果為0,正確
這里面存在很多問(wèn)題,先說(shuō)下uu 結(jié)果為0xfffffffe ,為什么?不是應(yīng)該是2嗎?
首先這位童鞋使用的是32位系統(tǒng)的電腦,所以輸出0xfffffffe ,共32位,因?yàn)樵谖挥蚨x時(shí),int 在32位系統(tǒng)中是占32位存儲(chǔ)的,所以將定義中int 改為unsigned char;其次,在d 賦值時(shí)會(huì)出現(xiàn)溢出的情況;最后,有些童鞋在輸出時(shí)printf 中使用十進(jìn)制輸出,在遇到例一中若將x.a=1111;那么電腦輸出結(jié)果為7,出現(xiàn)了偏差,這樣是不行的,若想輸出十進(jìn)制,那么寫(xiě)個(gè)小函數(shù)進(jìn)行下十六進(jìn)制轉(zhuǎn)化為十進(jìn)制,才可以。若是在單片機(jī)C 語(yǔ)言編程中,對(duì)寄存器進(jìn)行位操作中,則無(wú)需輸出,也無(wú)需轉(zhuǎn)化了。
這里只是討論了位域的一些賦值的小討論,這里我胡亂說(shuō)了半天,也不知道對(duì)不?若有錯(cuò)誤,還請(qǐng)指正。關(guān)于位域在物理的存儲(chǔ)方式很多資料都討論過(guò)了,這里就不展開(kāi)討論。