您的位置:首页 > 运维架构 > Linux

懂这个程序,就记住如何使用sizeof了

2012-03-01 20:27 387 查看
 
#include <stdio.h>

int main()
{
union u1
{
double a;
int b;
}u1;
union u2
{
char a[13];
int b;
}u2;

union u3
{
char a[13];
char b;
}u3;

union u4
{
char a[13];
int b;
}u4;

union u5
{
char a[13];
char b;
}u5;

struct s1
{
char a;
double b;
int c;
char d;
}s1;

struct s2
{
char a;
char b;
int c;
double d;
}s2;

struct s11
{
char a[8];
}s11;

struct s22
{
double d;
}s22;

struct s33
{
struct s11 s;
char a;
}s33;

struct s44
{
struct s22 s;
char a;
}s44;

printf("size of u1 is %d.\n",sizeof(u1));//8
printf("size of u2 is %d.\n",sizeof(u2));//16
printf("size of u3 is %d.\n",sizeof(u3));//13
printf("size of u4 is %d.\n",sizeof(u4));//16
printf("size of u5 is %d.\n",sizeof(u5));//13
printf("size of s1 is %d.\n",sizeof(s1));//24
printf("size of s2 is %d.\n",sizeof(s2));//16
printf("size of s11 is %d.\n",sizeof(s11));//8
printf("size of s22 is %d.\n",sizeof(s22));//8
printf("size of s33 is %d.\n",sizeof(s33));//9
printf("size of s44 is %d.\n",sizeof(s44));//16

return 0;

}


结论:复合数据类型,如union,struct,class的对齐方式为成员中对齐方式最大的成员的对齐方式。

结论1:都知道union的大小取决于它所有的成员中,占用空间最大的一个成员的大小。所以对于u1来说,大小就是最大的double类型成员a了,所以 sizeof(u1)=sizeof(double)=8。但是对于u2和u3,最大的空间都是char[13]类型的数组,为什么u3的大小是13,而 u2是16呢?关键在于u2中的成员int b。由于int类型成员的存在,使u2的对齐方式变成4,也就是说,u2的大小必须在4的对界上,所以占用的空间变成了16(最接近13的对界)。

 

 

结论2 :struct 里面的元素是顺序存储的,每个元素占用的字节数根据对齐字节数N(struct 里占用字节最多的元素与CPU对齐字节数中较小的一个)进行调整.如果从左至右M个元素加起来的字节数大于N,则按从右至左舍去K个元素直至M-K个元素 加起来的字节数小于等于N,如果等于N则不用字节填充,小于N则把M-K-1的元素填充直至=N. 

 

附:设置对齐方式

一 #pragma pack ( [ show ] | [ push | pop ] [, identifier ] , n )


 

[]里面的是可有可无的但是n一定要指定,如果没有编译器默认n=8
使用方法:
1.	#pragma pack(push) //保存对齐状态
2.	#pragma pack(1)//设定为1字节对齐
3.	#pragma pack(show); //编译的时候会在警告信息里面体现具体的字长的设置信息
4.	struct test
5.	{
6.
7.	    char m1;
8.
9.	    double m4;
10.	    int   m3;
11.	};
12.	#pragma pack(pop)


 
test将不再以double的大小为准则,开始用1个字节的对齐方式。
二 另外一种设置对齐方式的是:
__declspec( align( # ) )


 
里面#必须的是2的n次方,从1,2,4,8,16到8192,这样的话,如果定义一个结构体,他将以结构体的大小为准,补足到最临近的#的的整数倍。
比如:
__declspec(align(8)) struct Str1{

int a, b, c, d, e;

char f;

char *g;

}; //本身是25个字节补足到最近的8的倍数也就是32

__declspec(align(4)) struct Str1{

int a, b, c, d, e;

char f;

char *g;

}; //本身是25个字节补足到最近的4的倍数也就是28


 
另外,需要注意。

另外有一点要注意的就是GCC编译的程序,最大就是以4字节对齐,,不管你怎么弄,或者说怎么设置,它是不可能以8比如double来对齐的,比如:
struct test
{
char m1;
double m4;
}


 
gcc编译的话,那么他的大小是多少呢?如果不设置对齐的话是12,4个字节对齐的结果.
但是如果设置了:
#pragma pack(8)
是什么效果?
依旧是4个字节对齐,而且 #pragma pack()是属于c语言的,跟系统无关,不管是windows还是linux!
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐