位域,就是把一个字节中的二进制位划分为几个不同的区域,并说明每个区域的位数。
1、位域可以跨两个字节存储。(很多地方说不可以,其实有误,当位宽之和不大于类型的sizeof大小时,可以跨字节)如:
struct ss
{
short a:5;
short b:5;
short c:5;
}sa;
int main( ) {
printf("%d\n", sizeof(sa));
return 0;
}
打印出:2
2、位域允许无位域名,用来填充或调整位置,不能使用。
3、如果相邻域字段类型相同,且位宽之和小于类型的sizeof大小,则后面字段可以紧临前一个字段存储;若大于,从新的存储单元开始。
4、如果相邻域字段类型不同,依赖于编译器的具体实现。VC和VS采用不压缩方式,即不同位域字段存放在不同的位域类型字节中,而gcc采用压缩方式。如:
#include <stdio.h>
struct ss
{
char a:1;
char b:2;
char c:3;
long d:2;
};
typedef struct ss A;
int main( ) {
A test;
printf("%d\n", sizeof(test));
return 0;
}
a, b, c三字段类型相同,遵守规则3,紧临存储,共占一个字节;
在VC和VS下,由于采取不压缩方式,加上内存对齐规则,sizeof(ss)为1 + 3(填充) + 4 = 8字节;
GCC下,采取压缩方式,sizeof(ss)= sizeof(long) = 4,即全部存储在long的4个字节中。
再例如:
view plainprint?
struct ss
{
int a:8;
char d:4;
int b:3;
long c:2;
};
int和long可看成同一类型,在VC和VS下b和c占用同一字节,sizeof(ss)= 12,如果将c改为char类型,大小将变为4 +4+4+4 = 16;
GCC下sizeof(ss)= sizeof(long) = 4