以下为在32位编译环境下的信息 1字节:char 2字节:short(不管是不是signed或unsigned) 4字节:int、long、float(不管是不是signed或unsigned) 8字节:double 如果等号是'='这种字符常量的话当然是1字节,如果是“=”这种字符串常量当然是2字节 |
struct结构体占用的大小是和编译器有关的,在VC和GCC中可能同一个结构体会有不同的大小。
以一个例子引入:
注意:struct 的{}后面要加上 ”;“
例子1
#include<stdio.h>
struct A
{
int a;
double b;
char c;
};
struct B
{
double b;
char c;
int a;
};
struct C
{
int a;
char c;
double b;
};
int main(void)
{
A aa;
B bb;
C cc;
printf("A = %d\n", sizeof(aa));//结果:A = 24
printf("B = %d\n", sizeof(bb));//结果:B = 16
printf("C = %d\n", sizeof(cc));//结果:C = 16
return 0;
}
int类型一般是占用四个字节,char类型一般占用一个字节,double类型一般占用8个字节。
1、结构体A首先给int a 分配四个字节,并且以4个字节对齐;然后给double b分配8个字节,发现以4个字节对齐不行,就以8个字节对齐,前面只有int a ,所以int a将占用8个字节;最后为了对齐,将给char c 也分配8给字节,所以结构体A占用了24个字节。
2、结构体B首先给double 分配8个字节,并且以8给字节对齐;然后给char c分配8给字节;最后给int a分配空间的时候发现,前面空有7个字节空间可以放下int a,int a 就和char c一起占用8个字节,所以结构体B占用了16个字节
而在GNU GCC编译器中,遵循的准则有些区别,对齐模数不是像上面所述的那样,根据最宽的基本数据类型来定。在GCC中,对齐模数的准则是:对齐模数最大只能是4,也就是说,即使结构体中有double类型,对齐模数还是4,所以对齐模数只能是1,2,4。而且在上述的三条中,第2条里,offset必须是成员大小的整数倍,如果这个成员大小小于等于4则按照上述准则进行,但是如果大于4了,则结构体每个成员相对于结构体首地址的偏移量(offset)只能按照是4的整数倍来进行判断是否添加填充。
看如下例子:
struct
{
};
那么在GCC下,sizeof(T)应该等于12个字节。
例子2
struct 大小,与pack的大小(在程序中显示设置#pragma pack(),vc6.0默认大小为8)、结构中最大占用有关
struct A
{
int a; 0-3
4-7 要填充(padding)以保证内存对齐的原则
double b; 8-15
char c[9]; 16-24
};
首先给a分配内存,因为int占四个字节<pack大小(8个字节),所以按照4个字节对齐,起始位值为0,0%4=0,a最后占的内存为0-3;
接着给b分配内存,double占8个字节,所以按照8个字节对齐,起始位为8(8%8=0),b为8-15;
最后char占一个字节,所以c为16-24;
因此结构体A的大小为8+8+9 = 25;有因为25不是结构体中最大占用内存类型double类型大小(8)的整数倍,所以A最后的大小是32;
例子3
struct B
{
int a;
double b;
double c;
char d;
};
同理,按上面的分析方法确定各个变量在内存中的位置:
a,0-3;
,4-7;
b,8-15;
c,16-23;
d,24;
TOTAL = 25
25 不是8的倍数,所以最后B大小是32;
参考出处: http://blog.163.com/l_c_2005/blog/static/73746124201122333833/