位域/字节对齐
#include "stdafx.h"
#include "windows.h"
int _tmain(int argc, _TCHAR* argv[])
{
typedef struct
{
unsigned char a:2;
unsigned char :3;
unsigned char b:7;
unsigned char d:2;
} BIT_FIELDS;
BIT_FIELDS bit;
bit.a=1;
bit.b=7;
bit.d=15;
printf("sizeof(bit)=%d\n",sizeof(bit)); //=3
printf("a=%d\n",bit.b);
/////////////////////////////////////////////
typedef struct {
char a;
int b;
char d;
}t;
printf("sizeof(t)=%d\n",sizeof(t)); //=12
char str1[]="abcde";
char str2[]="我是中国人";
printf("strlen(str1)=%d\n",strlen(str1));
printf("sizeof(str1)=%d\n",sizeof(str1));
getchar();
return 0;
}
struct Mystruct1
{
bool a;
int b;
bool c;
}
在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。
第一个成员变量a占用1个字节,相对于结构的起始地址偏移量为0,满足对齐方式;第二个成员变量b占用4个字节,下一个可用的地址的偏移量为1,不是4的倍数,需要补足3个字节才能使偏移量为4(满足对齐方式),因此vc自动填充3个字节,b存放在偏移量为4的地址上,它占用4个字节。第三个变量c占用1个字节,下一个可用的地址为8(满足对齐方式),所以存放在偏移量为8的地址上;所有成员都分配了空间4+4+1=9,不是结构的字节边界数(sizeof(int))的倍数,所以填充三个字节以满足结构的大小为sizeof(int)的倍数,这样总的空间大小为4+4+4=12。
使用位域的主要目的是压缩存储,其大致规则为:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。