相信很多人学c的时候就不知道c中还有位域这么一说,自认为c学得还行,可是离精通还是有一定的距离啊,赶紧搞明白位域这一说法。所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。

举个简单的例子吧:


struct  test
{
  int a:4;
  int b:8;
  int c:6;
};

c语言那些细节之结构体字节对齐_#pragma



由上图可知test结构体在内存中的分配了。

所以他的大小也即:sizeof(test) = 4;

 

再看下下面几个例子:

 

示例代码:


#include<stdio.h>

//#pragmapack(4) //设置4字节对齐
//#pragmapack() //取消4字节对齐

struct test1
{
int a:8;
int b:8;
short c;
char d;
};

struct test2
{
char a:4;
char b:5;
char d;
short c;
};

struct test3
{
char a:4;
char b:4;
char d;
short c;
};

struct test4
{
struct test1 test;
int a[3];
char c;
};

struct test5
{
int a:4;
int b:8;
int c:6;
};

int main(intargc, char *argv[])
{
printf("size = %d\n",sizeof(test1));
printf("size = %d\n",sizeof(test2));
printf("size = %d\n",sizeof(test3));
printf("size = %d\n",sizeof(test4));
printf("size = %d\n",sizeof(test5));

return 0;
}



 

运行结果:


size = 8
size = 6
size = 4
size = 24
size = 4



 

首先看下有人分析好的注意点:

1)若为空结构体,则只占1个字节的单元

 

2)若结构体中所有数据类型都相同,则其所占空间为成员数据类型长度×成员个数

若结构体中数据类型不同,则取最长数据类型成员所占的空间为对齐标准,数据成员包含  另一个结构体变量t的话,则取t中最长数据类型与其他数据成员比较,取最长的作为对齐标准,但是t存放时看做一个单位存放,只需看其他成员即可。

 

3)若使用了#pragma pack(n)命令强制对齐标准,则取n和结构体中最长数据类型占的字节数两者之中的小者作为对齐标准。

 

 

具体分析:

Test1:

c语言那些细节之结构体字节对齐_数据类型_02

由上图可知:因为a和b都是位域,所以都在int型中,最长数据类型是4字节,所以a和b占一个int4字节,后面补空,而c是short的,2字节,d是char的,1字节,刚好可以填满,所以最后的长度为8;

 

    Test2:

c语言那些细节之结构体字节对齐_#pragma_03

由上图可知:因为a和b都是位域,所以都在char型中,最长数据类型是2字节,所以a和b占一个short2字节,后面补空,而d是char的,1字节,c是short的,2字节,所以最后的长度为6;

 

Test3:

c语言那些细节之结构体字节对齐_#pragma_04

由上图可知:因为a和b都是位域,所以都在char型中,最长数据类型是2字节,所以a和b占一个short2字节,后面刚好可以填d,而d是char的,1字节,c是short的,2字节,所以最后的长度为4;

 

Test4:

c语言那些细节之结构体字节对齐_位域_05

由上图可知:test4包含了test1,而其中最长数据类型是4字节,如图可知最后的长度为24;

Test5:

       一个int型的,最后长度为4。

 

相信通过上面的例子应该可以很好的理解了。

纯属个人言论,若有不妥之处,请不吝赐教!