#include <iostream>
#include <cstdio>
#include <cstdlib>
/*sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示。*/
using namespace std;
//1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
//2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
//3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)
struct ss{
char a; //size=1 + 对界偏移+7
double b; //size=8
int c; //size=4
char d; //size=1
}; //根据第三条规则(sizeof(ss)应为8的整数倍):对界偏移+3,所以总大小1+7+8+4+1+3=24;
//union sizeof计算规则:sizeof(union)=最宽基本成员变量的字节数
union uu{
int i;
char c;
long l;
};
int main()
{
cout << "Hello world!" << endl;
int i; cout<<"sizeof(int)="<<sizeof(i)<<endl;
int8_t i8; cout<<"sizeof(int8_t)="<<sizeof(i8)<<endl;
int16_t i16; cout<<"sizeof(int16_t)="<<sizeof(i16)<<endl;
int32_t i32; cout<<"sizeof(int32_t)="<<sizeof(i32)<<endl;
int64_t i64; cout<<"sizeof(int64_t)="<<sizeof(i64)<<endl;
short st; cout<<"sizeof(short)="<<sizeof(st)<<endl;
double d; cout<<"sizeof(double)="<<sizeof(d)<<endl;
long l; cout<<"sizeof(long)="<<sizeof(l)<<endl;
long long ll; cout<<"sizeof(long long)="<<sizeof(ll)<<endl;
char c; cout<<"sizeof(char)="<<sizeof(c)<<endl;
struct ss s; cout<<"sizeof(struct_int_char_long)="<<sizeof(s)<<endl;
union uu u; cout<<"sizeof(union_char_double_int_char)="<<sizeof(u)<<endl;
return 0;
}
输出结果:
Hello world!
sizeof(int)=4
sizeof(int8_t)=1
sizeof(int16_t)=2
sizeof(int32_t)=4
sizeof(int64_t)=8
sizeof(short)=2
sizeof(double)=8
sizeof(long)=8
sizeof(long long)=8
sizeof(char)=1
sizeof(struct_int_char_long)=24
sizeof(union_char_double_int_char)=8
上面可以看到C++中常见的数据类型的sizeof大小,只有1,2,4,8 总共4中情况所以还是比较好记的
下面说一下计算结构体大小的方法:
结构体大小的计算需要满足下面3条规则:
//1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
//2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
//3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)
看来比较抽象是吧,结合程序来看就容易一些了
根据规则1,定义结构体时可以将结构体变量的首地址都看成是0。就算在结构体的定义的前面还有代码,导致结构体变量的首地址不是0,其也不会影响结构体的size。
结构体定义的初始偏移是0,char占用一个字节
第二个成员变量是一个double,占8个字节
根据规则2,b的偏移地址应是8的整数倍,所以应该在a的后面加上7个空字节(也叫对界),这样b的偏移就是8,满足了规则2
第三个成员变量是一个int,占4个字节
变量c的偏移是16,满足规则2,不用进行对界了
第三个成员变量是一个char,占1个字节
此时变量d的偏移是20,char占1个字节,20也是1的倍数,所以不用对界
现在结构体占用21个字节,但是程序显示的结果是24,原因就是用到了规则3
结构体ss中的最宽基本类型是double,8个字节
所以结构体ss的大小应该是8的整数倍,需要进行对界操作,填充3个空字节
所以最后结构体ss的大小是24字节!!
Tips:因为结构体涉及复杂的对界操作,所以结构体中的成员变量发生变化,结构体的大小也会发生变化。
计算union的大小就很容易了,因为union的成员变量占用最宽成员变量的字节长度
共用体uu中的最宽成员变量是long,占8个字节,所以共用体uu的大小就是8个字节!!