本章重点
结构体
- 结构体类型的声明
- 结构的自引用
- 结构体变量的定义和初始化
- 结构体内存对齐
- 结构体传参
- 结构体实现位段(位段的填充&可移植性)
枚举
- 枚举类型的定义
- 枚举的优点
- 枚举的使用
联合(共用体)
- 联合类型的定义
- 联合的特点
- 联合大小的计算
结构的基础知识:结构是一些值的集合,这些值称为成员变量,结构的每个成员可以是不同类型的变量。
#include// 声明一个结构体类型,名字叫stu // 里面的内容叫做结构体成员变量 struct stu { char name[20]; // 名字 int age; // 年龄 char sex[5]; // 性别 char id[20]; // 学号 }s3,s4,s5; // 分号不能少,s3,s4,s5为全局的结构体变量,与下面的声明相同 // 创建结构体变量,全局变量,在函数内部叫做局部变量 struct stu s1; struct stu s2; int main(){ struct stu s6; // 局部变量 return 0; }
特殊声明:不常用
// 匿名结构体 struct { int a; char b; float c; }x; // 通过x.的方式进行调用结构体成员变量1.2 结构体的自引用
struct Node { int date; struct Node *next; };1.3 结构体变量的定义和初始化
// 结构体变量重定义 typedef struct node { int data; } Node; int main() { struct node n1; Node n2; return 0; }
struct S{ char c; int a; double d; char arr[]; }; struct S s = {'A',10,3.14,"world"};1.4 结构体传参
结构体传参,采用传地址的方式,效率更高
函数传参的时候,参数是需要压栈的,会有时间和空间上的系统开销。如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。
#include1.5 结构体位段struct S { int a; char c; double d; }; void init(struct S *temp) { temp->a = 100; temp->c = 'a'; temp->d = 3.14; } void print1(struct S temp) { printf("%fn", temp.d); } void print2(struct S *temp) { printf("%fn", temp->d); } int main() { struct S s; init(&s); // 给结构体传参 print1(s); // 调用结构体参数进行计算 print2(&s); // 调用结构体参数进行计算,常用方法2 return 0; }
位段的声明和结构是类似的,有两个不同:
- 位段的成员必须是int、unsigned int 或 signed int,只要整型即可,char也是整型
- 位段的成员名后边有一个冒号和一个数字
位段:二进制位,位段用来节省空间
位段内存的分配:
- 位段的成员可以是int unsigned int signed int或者是char(属于整型家族)类型
- 位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的‘
- 位段涉及很多不确定因素,位段是不跨平台的,注意可移植的程序应该避免使用位段
#include2 枚举struct S { int a : 2; // 给a 2个比特位 int b : 5; // 给b 5个比特位 int c : 10; int d : 30; }; // 共47个bit位,换算成字节,6个字节即可满足 int main() { struct S s; printf("%dn", sizeof(s)); // 8个字节 }
枚举顾名思义就是列举,把可能的取值进行列举。
枚举类型的定义:
enum Color { RED, // 默认为0,可以赋初始值,例RED = 1 YELLOW, // 1 BLUE // 2 }; int main(){ enum Color r = RED; // 赋其他值会报错 return 0; }
枚举的优点:可以使用#define定义常量,为什么非要使用枚举?
- 增加代码的可读性和可维护性
- 和#define定义的标识符比较,枚举有类型检查,更加严谨
- 防止命名污染(封装)
- 便于调试
- 使用方便,一次可以定义多个常量
枚举的使用:
3 联合(共用体)- 联合类型的定义:联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。
- 联合的特点:共用同一块内存空间,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)
// 联合类型的声明 union un { char c; int i; }; int main() { union un u; printf("%dn", sizeof(u)); //结果为4 return 0; }
联合大小的计算:
- 联合的大小至少是最大成员的大小
- 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍