学习目标:
学习并了解C语言自定义类型
目录
●结构体的声明
●结构体的引用
●结构体的定义和初始化
●结构体的内存对齐
●结构体的传参
●结构体的位段(位段的可填充和可移植性)
●枚举的定义
●枚举的优点
●枚举的使用
●联合的定义
●联合的特点
●联合的计算
一、结构体
结构体的声明:
struct s { int age; char name[20]; int id; }; //这就是一个结构体的声明,他含有三个成员,年龄,名字,ID 结构体还可以匿名声明 struct { int age; char name[20]; int ID; }x; //这就是一个匿名类
结构体的自引用:
//结构体的自引用 struct S { int age; char name[20]; struct S* next; };
结构体的定义和初始化:
//结构体的定义和初始化 struct s { int age; char name[20]; int id; }s2 = { 34,"lisi",3432 };//可以在结构体后面定义一个结构体变量并初始化 struct s s3 = { 23,"wangeu",87883 }; //在main函数外定义的变量为全局变量 int main() { //而在main函数里面定义的结构体变量为局部变量,初始化时,用大括号时要对应结构体中的量 struct s s1 = { 12,"zhangsan",123 }; struct s s2; return 0; }
结构体的内存对齐:
我们先计算一个结构体的大小:
对于才接触结构体的,一看结果应该是6,为什么是12.
这就要讲到结构体的内存对齐规则;
结构体的第一个成员变量放在结构体地址偏移量的0位置处。
接下来的成员变量放在自己类型的整数倍的位置处;
结构体的总体大小为成员变量中最大对齐数的整数倍接近数。
对齐数:成员的类型大小与编译器的默认对齐数相比较取较小对齐数。
如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
至于为什么存在最大对齐数:
对齐存储后便于使用时取出来
同时也是提升性能
总体来说:
结构体的内存对齐是拿空间来换取时间的做法。
同时,默认对齐数是可以修改的
用到#pragma(8),就是将默认对齐数改为8
结构体的传参:
如果传参时传结构体过去将会增加内存,浪费空间。且会占用很大的栈区;
结构体的位段:
1.位段的成员必须是 int、unsigned int 或signed int 。
2.位段的成员名后边有一个冒号和一个数字。
这个位段的大小是8的原因:
我们要知道位段在内存中的存储规则
1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
所以上面的代码:
先开辟4个字节的空间,_a使用2个字节,还剩2个字节。但是_b要用3个,不够。内存又开辟4个字节。放完_b的3个字节后,还剩1个字节,刚好放_c的一个字节。
所以总大小就是8字节。
位段一般不推荐使用,她的不确定性很大。
二、枚举
枚举顾名思义就是列举;
将可能的值一一列举出来:
如一星期的取值有:星期一,星期二,星期三,星期四,星期五,星期六,星期七。
enum month{ Mon, Turs, Wend };
以上定义的 enum month 都是枚举类型。
{}中的内容是枚举类型的可能取值,也叫 枚举常量 。
这些可能取值都是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值。
枚举的优点:
1. 增加代码的可读性和可维护性
2. 和#define定义的标识符比较枚举有类型检查,更加严谨。
3. 防止了命名污染(封装)
4. 便于调试
5. 使用方便,一次可以定义多个常量
三、联合
联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。
因为是公用一块空间,所以 a和c共用4个字节的空间
内存开辟的空间至少是最大类型的空间大小
联合体的大小:
联合的大小至少是最大成员的大小。
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
最大对齐数为4
char arr的大小为5字节
总大小为4的2倍——8;
学习时间:
二零二二年十月九日
学习产出:
- 技术笔记 1 遍
- CSDN 技术博客 1 篇
- 习的 vlog 视频 1 个