C语言笔记 | Struct结构体
发表于:2022-06-08 | 分类: C语言笔记

结构体的概念

  • 由一系列具有相同类型或不同类型的数据构成的数据集合, 叫做结构
  • struct是一种复合数据类型, 结构类型
  • 在C语言中, 结构体(struct)是复合数据类型的一种, 同时也是一些元素的集合, 这些元素称为结构体的成员, 且这些成员可以为不同的类型, 成员一般用名字访问, 结构体可以被声明为变量/指针或数组等, 用以实现较复杂的数据结构
  • 在C语言中, 结构体不能包含函数
  • 在C++中, 考虑到C语言到C++语言过渡的连续性, 对结构体进行了扩展, C++的结构体可以包含函数, 在面向对象的程序设计中, 对象具有状态(属性)和行为, 状态保存在成员变量中, 行为通过成员方法(函数)来实现。C语言中的结构体只能描述一个对象的状态, 不能描述一个对象的行为, 与class不同的是, 结构体包含的函数默认为public, 而不是private
    • 在C++中, 结构体可以包含函数
    • 在C++中struct与class的区
      1. class中默认的成员访问权限是private的, 而struct中则是public的
      2. class继承默认是private继承, 而从struct继承默认是public继承

结构体的作用

  • 由于C语言内部程序比较简单, 研发人员通常使用结构体创造新的”属性”, 其目的是简化运算
  • 结构体在函数中的作用不是简便, 最主要的作用就是封装, 封装的好处就是可以再次利用, 让使用者不必关心这个是什么, 只要根据定义使用就可以了

结构体大小与内存对齐

变量的字节对齐

一个变量占用n个字节, 则该变量的起始地址必须是n的整数倍

结构体字节对齐

  1. 实际对齐单位, 三者取最小
    1. CPU周期(位/8)
      • Windows VS默认8字节对齐
      • Linux 32位默认4字节对齐
      • Linux 64位默认8字节对齐
    2. 结构体最大成员(基本数据类型变量)
    3. 预编译指令#pragma pack(n)手动设置, n只能填1/2/4/8/16
  2. 除结构体的第一个成员外, 其它所有的成员的起始地址是实际对齐单位的整数倍

栗子

1
2
3
4
5
6
struct s {
char a1;
char a2;
double b;
int c;
};
  1. 先为a1和a2分配空间, 占用2字节, 与最大宽度对齐, 实际占用4字节
  2. 接下来为b分配空间, 最大宽度, 占用8字节
  3. 接下来为c分配空间, 占用4字节, 与最大宽度对齐, 实际占用8字节
  • 总占用24字节

总结

可以合理安排数据类型的先顺序以减少内存占用

占用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)//设定为4字节对齐
struct test {
char m1;
double m4;
int m3;
};
#pragma pack(pop)//恢复对齐状态
上一篇:
C语言笔记 | C与汇编
下一篇:
C语言笔记 | 函数调用协议