结构体的大小的计算与空间的优化--之位域字段
/*********************************************************************
* Author : Samson
* Date : 09/21/2013
* Test platform:
* #1 SMP Debian 3.7.2-0+kali8
* gcc (Debian 4.7.2-5) 4.7.2
* *******************************************************************/
前面进行了基本类型的结构体的讨论:http://blog.csdn.net/yygydjkthh/article/details/11850735
现在就结构体中有位域的字段时的长度计算:
通过以下的例子可以看出,关于位域的计算和基本类型的值所构成的结构体的长度不是一个算法儿。
测试代码与结果:
#include <stdio.h>
#include <stdlib.h>
typedef struct BitArea1
{
char c:4;
int l:30;
}BITAREA1;
//上面这个结构体的长度为:4bit+30bit=34bit,大于了一个字节(32bit),又因为:对齐规则的第2条:结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。所以此处应该是按照int类型的4字节进行对齐,所以这里的34bit补充对齐后的空间占用为8个字节;
若是两个的字段的总和小于等于32bit,那么此结构体所占用的空间为4个字节:
typedef struct BitArea1
{
char c:4;
int l:20;
}BITAREA1;
同理,若是把int类型修改为short类型的,则在两字段相加的bit数小于等于sizeof(short)=2Byte=16bit的情况下,占用空间应该为2个字节:
typedef struct BitArea1
{
char c:4;
short l:10;
}BITAREA1;
若是两字段相加的bit数大于2Byte=16bit的话则空间占用为4个字节;
typedef struct BitArea1
{
char c:4;
short l:13;
}BITAREA1;
typedef struct BitArea
{
int a:1;
char b:1;
int c;
char d:3;
char e:5;
int f;
char g:3;
}BITAREA;
//以上的结构体的长度应该为:a和b的长度为2bit,又因为a是int类型的,且C是int,按照规则的第一条和第二条,那么a+b+c=4+4=8,d+e刚好8bit,又因为f为int的,所以d+e+f=4+4=8,而g为3bit,8+8+1=17,又根据第一条规则:结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。最后的结果为20;
typedef struct BitAreaBetter
{
char b:1;
char d:3;
char e:5;
char g:3;
int c;
int f;
int a:1;
}BITAREABETTER;
//以上的结构体的长度根据前面的总结,同理可得长度应该为:4+4+4+4=16;前面的4个char类型的由于C是int类型的,所以前4个char加起来的2字节的长度应该按4字节来进行补齐;
typedef struct BitAreaBest
{
char b:1;
char d:3;
char e:5;
char g:3;
int a:1;
int c;
int f;
}BITAREABEST;
//以上的结构体的长度根据前面的总结,同理可得长度应该为:4+4+4=12;前面的4个char类型加上一个int的位域的总和小于一个int类型的大小,所以总的空间占用通过第一条规则补齐为4字节,其后两个为int类型的为4字节;
//存在位域字段的结构体的优化方法为:把位域字段尽量放到一块;
typedef struct BitAreaBest1
{
int a:1;
int c;
int f;
char b:1;
char d:3;
char e:5;
char g:3;
}BITAREABEST1;
//以上结构体的长度其实和BITAREABETTER的一样,只是把顺序调整了一下;
int main()
{
int len, lenBest, lenBett, len01, lenBest01;
BITAREA BitArea;
BITAREA1 BitArea1;
BITAREABETTER BitAreaBetter;
BITAREABEST BitAreaBest;
BITAREABEST1 BitAreaBest01;
len = sizeof(BitArea);
lenBett = sizeof(BITAREABETTER);
lenBest = sizeof(BitAreaBest);
len01 = sizeof(BitArea1);
lenBest01 = sizeof(BitAreaBest01);
printf("BitArea1 len is %d BITAREABETTER len is %d BitAreaBest len is %d len01 is %d BitAreaBest01 len is %d\n", len, lenBett, lenBest, len01, lenBest01);
return 0;
}
root@quieter:/usr/local/samsonfile/yygytest# ./a.out
BitArea1 len is 20 BITAREABETTER len is 16 BitAreaBest len is 12 len01 is 8 BitAreaBest01 len is 16