1.结构体(struct)
- 结构体类型的声明
- 结构体变量的定义和初始化
- 结构体自引用
- 结构体传参
- 结构体内存对齐
结构体的声明:结构体是不同类型数据的一个集合。例如描述一本书
1. struct Book 2. { 3. char name[20];//用字符数组存放书名 4. char author[10];//用字符数组存放作者名 5. int price;//用int存放价格 6. };//结构体后面的分号不可省略
这就是一个简单的结构体。 结构体的的所有声明是这样的
1. struct tag 2. { 3. member-list;//成员变量 4. }variable-list;//快速创建结构体变量
特殊的声明:匿名结构体
1. struct 2. { 3. int a; 4. char b; 5. float c; 6. }x;
结构体的定义和初始化:
有了结构体类型,那如何定义变量,其实很简单
1. struct Point 2. { 3. int x; 4. int y; 5. }p1;//声明类型的同时定义变量p1 6. 7. struct Point p2;//定义结构体变量p2
初始化也简单
1. struct Stu //类型声明 2. { 3. char name[15];//名字 4. int age;//年龄 5. }; 6. struct Stu s = {"zhangsan",20};//初始化
结构体自引用
1. struct Node 2. { 3. int data; 4. struct Node* next; 5. };
结构体传参
结构传参和函数中的传值调用和传址调用类似,传结构体本身(print1)相当于在函数内部重新开辟了一块内存空间struct S s,是原来结构体变量s的一份临时拷贝,出函数后就会自动销毁,无法找到真正的结构体变量s。而传地址(print2)就可以直接找到结构体s本身,而且更加节省空间。
1. #include<stdio.h> 2. struct S 3. { 4. int data[1000]; 5. int num; 6. }; 7. struct S s = { {1,2,3,4}, 1000 }; 8. //结构体传参 9. void print1(struct S s) 10. { 11. printf("%d\n", s.num); 12. } 13. //结构体地址传参 14. void print2(struct S* ps) 15. { 16. printf("%d\n", ps->num); 17. } 18. int main() 19. { 20. print1(s); //传结构体 21. print2(&s); //传地址 22. return 0; 23. }
结构体内存对齐(往期博客有详细介绍)
2.枚举(enum)
- 枚举类型的定义
- 枚举的优点
- 枚举的使用
枚举的定义
枚举的定义和结构体的定义类似,只不过枚举内部是一系列的枚举常量
1. enum Day//星期 2. { 3. //枚举常量 4. Mon, 5. Tues, 6. Wed, 7. Thur, 8. Fri, 9. Sat, 10. Sun 11. };
枚举常量是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值。由此看来,上述代码等同于这样
1. #define Mon 0 2. #define Tues 1 3. #define Wed 2 4. #define Thur 3 5. #define Fri 4 6. #define Sat 5 7. #define Sun 6
但是为什么还要有枚举类型呢?
枚举的优点
1. 增加代码的可读性和可维护性
2. 和#define定义的标识符比较枚举有类型检查,更加严谨
3. 防止了命名污染(封装)
4. 便于调试
5. 使用方便,一次可以定义多个常量
枚举的使用
1. enum sex 2. { 3. male, 4. female, 5. secret, 6. }; 7. enum sex s=male;
3.联合体(union)
- 联合类型的定义
- 联合的特点
- 联合大小的计算
联合类型的定义
联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)
1. union Un 2. { 3. int i; 4. char c; 5. }; 6. union Un un;
联合的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联 合至少得有能力保存最大的那个成员)
所以
//sizeof(un) 4
联合大小的计算
联合的大小至少是最大成员的大小。 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
1. union Un1 2. { 3. char c[5]; 4. int i; 5. }; 6. union Un2 7. { 8. short c[7]; 9. int i; 10. }; 11. //下面输出的结果是什么? 12. printf("%d\n", sizeof(union Un1));//8 13. printf("%d\n", sizeof(union Un2));//16