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

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

举个简单的例子吧:

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


由上图可知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:


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

 

    Test2:


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

 

Test3:


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

 

Test4:


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

Test5:

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

 

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

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

原文地址:https://www.cnblogs.com/wuyida/p/6300016.html