结构体的概念
- 由一系列具有相同类型或不同类型的数据构成的数据集合, 叫做结构
- struct是一种复合数据类型, 结构类型
- 在C语言中, 结构体(struct)是复合数据类型的一种, 同时也是一些元素的集合, 这些元素称为结构体的成员, 且这些成员可以为不同的类型, 成员一般用名字访问, 结构体可以被声明为变量/指针或数组等, 用以实现较复杂的数据结构
- 在C语言中, 结构体不能包含函数
- 在C++中, 考虑到C语言到C++语言过渡的连续性, 对结构体进行了扩展, C++的结构体可以包含函数, 在面向对象的程序设计中, 对象具有状态(属性)和行为, 状态保存在成员变量中, 行为通过成员方法(函数)来实现。C语言中的结构体只能描述一个对象的状态, 不能描述一个对象的行为, 与class不同的是, 结构体包含的函数默认为public, 而不是private
- 在C++中, 结构体可以包含函数
- 在C++中struct与class的区
- class中默认的成员访问权限是private的, 而struct中则是public的
- class继承默认是private继承, 而从struct继承默认是public继承
结构体的作用
- 由于C语言内部程序比较简单, 研发人员通常使用结构体创造新的”属性”, 其目的是简化运算
- 结构体在函数中的作用不是简便, 最主要的作用就是封装, 封装的好处就是可以再次利用, 让使用者不必关心这个是什么, 只要根据定义使用就可以了
结构体大小与内存对齐
变量的字节对齐
一个变量占用n个字节, 则该变量的起始地址必须是n的整数倍
结构体字节对齐
- 实际对齐单位, 三者取最小
- CPU周期(位/8)
- Windows VS默认8字节对齐
- Linux 32位默认4字节对齐
- Linux 64位默认8字节对齐
- 结构体最大成员(基本数据类型变量)
- 预编译指令#pragma pack(n)手动设置, n只能填1/2/4/8/16
- 除结构体的第一个成员外, 其它所有的成员的起始地址是实际对齐单位的整数倍
栗子
1 2 3 4 5 6
| struct s { char a1; char a2; double b; int c; };
|
- 先为a1和a2分配空间, 占用2字节, 与最大宽度对齐, 实际占用4字节
- 接下来为b分配空间, 最大宽度, 占用8字节
- 接下来为c分配空间, 占用4字节, 与最大宽度对齐, 实际占用8字节
总结
可以合理安排数据类型的先顺序以减少内存占用
占用8字节
1 2 3 4 5
| struct S1 { char c1; char c2; int i; };
|
占用12字节
1 2 3 4 5
| struct S2 { char c1; int i; char c2; };
|
可以屏蔽掉变量默认的对齐方式, 自己来设定变量的对齐方式
1 2 3 4 5 6 7 8
| #pragma pack(push) #pragma pack(4) struct test { char m1; double m4; int m3; }; #pragma pack(pop)
|