C語言位域的使用及其注意點(diǎn)
2013-03-08 17:33:08
所謂“位域”是把一個字節(jié)中的二進(jìn)位劃分為幾個不同的區(qū)域, 并說明每個區(qū)域的位數(shù)。每個域有一個域名,允許在程序中按域名進(jìn)行操作。 這樣就可以把幾個不同的對象用一個字節(jié)的二進(jìn)制位域來表示。位域的定義和位域變量的說明位域定義與結(jié)構(gòu)定義相仿,其形式為:
struct 位域結(jié)構(gòu)名
{ 位域列表 };
eg:struct weiyu {
int a:2;
int b:5;
int :5;//此五位為空域,不能使用
int c:3;
}
位域雖然簡單好用,但使用時需要注意:
1) 如果相鄰位域字段的類型相同,且其位寬之和小于類型的sizeof大小,則后面的字
段將緊鄰前一個字段存儲,直到不能容納為止;
2) 如果相鄰位域字段的類型相同,但其位寬之和大于類型的sizeof大小,則后面的字
段將從新的存儲單元開始,其偏移量為其類型大小的整數(shù)倍;
3) 整個結(jié)構(gòu)體的總大小為最寬基本類型成員大小的整數(shù)倍。
4) 如果相鄰的位域字段的類型不同,則各編譯器的具體實現(xiàn)有差異,VC6采取不壓縮方
式,Dev-C++采取壓縮方式;
5) 如果位域字段之間穿插著非位域字段,則不進(jìn)行壓縮;(不針對所有的編譯器)
4 ,5跟編譯器有較大的關(guān)系,使用時要慎重,盡量避免。
下面用代碼說話:
-
#include "stdio.h"
-
-
-
void main(int argn ,char *argv)
-
{
-
struct test {
-
unsigned a:10;
-
unsigned b:10;
-
unsigned c:6;
-
unsigned :2;//this two bytes can't use
-
unsigned d:4;
-
}data,*pData;
-
data.a=0x177;
-
data.b=0x111;
-
data.c=0x7;
-
data.d=0x8;
-
-
pData=&data;
-
printf("data.a=%x data.b= %x data.c=%x data.d=%xn",pData->a,pData->b,pData->c,pData->d);//位域可以使用指針
-
-
printf("sizeof(data)=%dn",sizeof(data)); //4 bytes ,最常用的情況
-
-
struct testLen{
-
char a:5;
-
char b:5;
-
char c:5;
-
char d:5;
-
char e:5;
-
}len;
-
-
printf("sizeof(len)=%dn",sizeof(len)); //5bytes 規(guī)則2
-
-
struct testLen1{
-
char a:5;
-
char b:2;
-
char d:3;
-
char c:2;
-
char e:7;
-
}len1;
-
printf("sizeof(len1) =%dn",sizeof(len1)); //3bytes 規(guī)則1
-
-
struct testLen2{
-
char a:2;
-
char :3;
-
char b:7;
-
long d:20; //4bytes
-
char e:4;
-
}len2;
-
printf("sizeof(len2)=%dn",sizeof(len2)); //12 規(guī)則3,4,5,總長為4的整數(shù)倍,2+3 占1byte,b占1bye 由于與long對其,2+3+7 占4字節(jié),后面 d 與 e進(jìn)行了優(yōu)化 占一個4字節(jié)
-
-
-
struct testLen3{
-
char a:2;
-
char :3;
-
char b:7;
-
long d:30;
-
char e:4;
-
}len3;
-
printf("sizeof(len3)=%dn",sizeof(len3));//12 規(guī)則3,4,5,總長為4的整數(shù)倍,2+3 占1byte,b占1bye 由于與long對其,2+3+7 占4字節(jié),后面 d占一個4字節(jié),為了保證與long對其e獨(dú)占一個4字節(jié)
-
}
|