结构体

  • 结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员(Member)
    struct stu{
    char *name; //姓名
    int num; //学号
    int age; //年龄
    char group; //所在学习小组
    float score; //成绩
    };(注意分号)
  1. 可直接在结构体之后分号之前定义变量
  2. 可直接用stu定义变量
  3. 可省略stu结构体名称,采用第1条命名方式,不过之后就不能再用第2条定义新的变量了
  4. 结构体变量赋值给指针时必须加&符号

    位域

  • 在结构体定义时,我们可以指定某个成员变量所占用的二进制位数(Bit),这就是位域
  • 当相邻成员的类型相同时,如果它们的位宽之和小于类型的 sizeof 大小,那么后面的成员紧邻前一个成员存储,直到不能容纳为止;
    如果它们的位宽之和大于类型的 sizeof 大小,那么后面的成员将从新的存储单元开始,其偏移量为类型大小的整数倍。
  • 当相邻成员的类型不同时,不同的编译器有不同的实现方案,GCC 会压缩存储,而 VC/VS 不会
  • 如果成员之间穿插着非位域成员,那么不会进行压缩。
  • 无名位域:没有名称,只给出数据类型和位宽。一般用来作填充或者调整成员位置,不能使用

枚举

  • 枚举和宏其实非常类似:宏在预处理阶段将名字替换成对应的值,枚举在编译阶段将名字替换成对应的值。我们可以将枚举理解为编译阶段的宏。
  1. 可在定义枚举的同时定义变量
  2. 枚举列表中的标识符的作用范围是全局的(严格来说是 main() 函数内部),不能再定义与它们名字相同的变量。
  3. 枚举列表中的标识符都是常量,不能对它们赋值,只能将它们的值赋给其他的变量。
  4. 这意味着,枚举列表中的标识符都不是变量,它们不占用数据区(常量区、全局数据区、栈区和堆区)的内存,而是直接被编译到命令里面,放到代码区,
    所以不能用&取得它们的地址。这就是枚举的本质。

共用体(联合体)

  • 结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。
  • 结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,
    同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。
  • 要注意内存大小端的问题
posted on 2021-03-29 23:43  逆流而上の鱼  阅读(444)  评论(0)    收藏  举报