泉州双阳中学入取分数:关于struct的疑问?

来源:百度文库 编辑:中科新闻网 时间:2024/04/28 15:37:20
自然对界的情况下:
struct
{
char a;
char b;
int x;
}str_1;
struct
{
char a;
int x;
char b;
}str_2;
问:
为什么sizeof(str_1)和sizeof(str_2)的结果为什么不一样?

PS:
恳请详细回答,谢谢!
More More More ...

#include <iostream>

struct
{
char a;
char b;
int x;
}str_1,*p1;
struct
{
char a;
int x;
char b;
}str_2,*p2;

int main()
{
p1 = &str_1;
p2 = &str_2;
std::cout<<"sizeof(str_1)="<<sizeof(str_1)<<std::endl;
std::cout<<"sizeof(str_2)="<<sizeof(str_2)<<std::endl;
std::cout<<"(long)&p1->a="<<(long)&p1->a<<std::endl;
std::cout<<"(long)&p1->b="<<(long)&p1->b<<std::endl;
std::cout<<"(long)&p1->x="<<(long)&p1->x<<std::endl;
std::cout<<"(long)&p2->a="<<(long)&p2->a<<std::endl;
std::cout<<"(long)&p2->x="<<(long)&p2->x<<std::endl;
std::cout<<"(long)&p2->b="<<(long)&p2->b<<std::endl;
return 0;

}

//输出结果:
sizeof(str_1)=8
sizeof(str_2)=12
(long)&p1->a=4293004
(long)&p1->b=4293005
(long)&p1->x=4293008
(long)&p2->a=4292988
(long)&p2->x=4292992
(long)&p2->b=4292996

//可见:
char str_1->a 占1个字节 ■
char str_1->b 占1个字节 ■
补上2个空字节 □□
int str_1->x 占4个字节 ■■■■

char str_2->a 占1个字节 ■
补上3个空字节 □□□
int str_1->x 占1个字节 ■■■■
char str_2->b 占1个字节 ■
补上3个空字节 □□□

其实,这是C++对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理。在默认情况下,C++规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。下面列出常用类型的对齐方式
类型
对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)
Char
偏移量必须为sizeof(char)即1的倍数

int
偏移量必须为sizeof(int)即4的倍数

float
偏移量必须为sizeof(float)即4的倍数

double
偏移量必须为sizeof(double)即8的倍数

Short
偏移量必须为sizeof(short)即2的倍数

各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节C++会自动填充。同时C++为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。

因为编译器优化执行速度,所以结果不一样。

因为cpu访问内存数据时,如果地址不是字对齐,则访问速度要慢2倍,所以编译器要把结构体成员的开是地址放到字对齐位置上,这样速度最快。

缺省情况下,编译器按照奔腾CPU优化,所有成员地址都能被8整除, a,b,x三个成员的首地址都能被8整除,这样,str_1就要在a后面加上7字节,b后面加上7字节,一共20字节

str_2中,a后加入7字节,x后加入4字节,一共17字节