【C语言进阶 14 】结构体详解、位段、枚举、联合体

前言:

这个系列记录了我这两个月从零开始学习C语言的完整过程,可以当作笔记使用。

每篇文章都包含可运行的代码示例和常见错误分析,尤其适合没有编程经验的读者。学习时建议准备好编译器(如Dev-C++或VS 2022之类的),随时尝试修改示例代码。

一,结构体

1,结构体创建:

结构体变量也可以通过结构体类型创建,如:struct tag S={"zhangsan","12"};

匿名结构体类型:

2,结构体的自引用(链表的实现):

3,结构体指针两种重命名的方式

4,求结构体的空间大小:

例子:

struct Person {
    char name[20];   // 对齐数1
    int age;         // 对齐数4
    char gender;     // 对齐数1
    float height;    // 对齐数4
    float weight;    // 对齐数4
};
 
  1. name[20]占用20字节(0-19)
  2. age需要4字节对齐,从偏移量20开始(20-23)
  3. gender占用1字节(24)
  4. 编译器插入3字节填充(25-27)
  5. height从偏移量28开始(28-31)
  6. weight紧随其后(32-35)

因为最大对齐数为4,0--35占36个字节,满足最大对齐数的整数倍,故结构体空间为36字节。

计算结构体空间的步骤:

  1. 算:先算对齐数(数组看类型得对齐数,不看数组空间大小)。
  2. 放:第一个成员从偏移量为0开始,其他成员所放位置的偏移量为对齐数的倍数。
  3. 补:总大小为结构体最大对数的倍数,不够则补。

5,默认对齐数(对成员的对齐数进行限制)的修改:

6,offsetof()宏     用来计算对于成员的偏移量,头文件:<stddef.h> 

二,位段:

位段的声明和结构类似,有两个不同:

1. 位段的成员必须是 intunsigned int 或 signed int。(一些编译器char类型也可以)

2. 位段的成员名后边有一个冒号和一个数字。

// 位段结构体:按“位”分配成员分配成员空间,节省内存
struct StudentStatus {
    // 成绩等级:A(0)/B(1)/C(2)/D(3),仅需分配2位比特位存储即可
    unsigned int grade : 2;
    // 出勤状态:缺勤(0)/出勤(1),仅需分配1位比特位存储即可
    unsigned int attend : 1;
};
 

以上表示存数据所开辟的比特位数量,可以用来节省空间。

位段的内存分配 :

1. 位段的成员可以是 int、unsigned int、signed int 或者是 char(属于整型家族)类型。

2. 位段的空间上是按照需要以 4 个字节(int)或者 1 个字节(char)的方式来开辟的。

3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

三,枚举:

   

四,联合(共用体)

 1,联合类型的定义

联合也是一种特殊的自定义类型。
这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。

2 联合的特点

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。

3 联合大小的计算

  • 联合的大小至少是最大成员的大小。
  • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值