结构体:
定义:
结构体就是一堆值的集合
初始化:
#include<stdio.h>
#include <stddef.h>
struct S
{char ch;int n;
};int main()
{struct S s1 { 'a', 5 };S s2{ 'b',6 };printf("s1 ch:%c , n:%d\n", s1.ch, s1.n);printf("s2 ch:%c , n:%d\n", s2.ch, s2.n);return 0;
}
大小:
结构体大小涉及到内存对齐问题:
内存对齐的规则:
ps:下文谈及的对齐数等于对应的数据类型大小
- 1.第一个成员在与结构体变量偏移量为0的地址处。
- 2.对齐基准:结构体的对齐数=min(默认对齐数),最大成员对齐数)
- 1.第一个成员在与结构体变量偏移量为0的地址处。
ps:默认对齐数根据编译器不同而不同,也可以自己设置 使用#pragma pack(n),设置n为默认对齐数
- 3.成员对齐:每个成员必须放在其类型大小整数倍的地址(偏移地址)上
- 4.结构体大小一定是结构体对齐数的整数倍
- 3.成员对齐:每个成员必须放在其类型大小整数倍的地址(偏移地址)上
求sizeof(结构体)的运行结果:
内存对齐的优点:
1.提高CPU访问内存的效率,大多数CPU都是几个字节访问、避免一个数据要访问两次内存
例如:
2.方便平台兼容:有些平台不允许访问单个字节的数据,有些平台可以
位段:
定义:
按照比特位分配空间的特殊结构体
初始化:
1、成员变量必须是 int、unsigned int 或signed int类型 。
2.位段的成员名后边有一个冒号和一个数字。
struct S
{int _a : 10;int _b : 30;
};
大小:
默认按照int大小(4字节==32比特)分配空间:
如果所有位段总位数 ≤ 32(4字节),则分配 4 字节。
如果总位数 > 32,则分配多个 int 单元。
如上图所示:S位段中总比特位为40,所以分配两个int单元
优缺点:
优点:
可以很好地节省空间,网络协议报头的制定就常常使用位段结构体
缺点:
不可跨平台,因为每个平台内存填充对齐规则不同
例如下图:
两种不同的填充对齐方案,一种是不要剩余空间,进行内存对齐更重要,一种是充分利用剩余空间,两种方案的不同导致,同一种CPU访问内存取数据的策略,可能取出的数据不同,所以导致位段的不可跨平台性
枚举:
定义:
常量的集合
初始化:
enum LOGLEVEL
{DEBUG=0,WARNING,ERROR,FATAL
};
常量的值默认从0开始,一次递增1,当然在定义的时候也可以赋初值
优点:
优点:
- 增加代码的可读性和可维护性
- 有类型检查(例如传参时),更严谨
ps:如果是宏定义常量,宏常量debug可以进入Func2,int类型的数据也能进入Func2,而用枚举定义的常量就会有类型检查,只能枚举的常量才能进入Func1函数中
- 通过封装,避免了命名污染问题
- 使用方便、一次性可以定义多个常量
联合体:
定义:
联合体是成员是共用同一块内存空间的特殊结构体类型
初始化:
union u
{char c;int n;
};
大小:
规则:
- 联合体的大小至少是最大成员的大小
- 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
对于union u来说最大成员大小是n的大小为4个字节,而且由上文结构体中谈及的内存对齐规则可知,4为最大对齐数,所以正好最大成员大小是最大对齐数的整数倍,所以u大小为4个字节;
对于union u2来说最大成员大小是c的大小为5个字节,而且由上文结构体中谈及的内存对齐规则可知,4为最大对齐数,所以正好最大成员大小不是最大对齐数的整数倍,所以要对齐到最大对齐数的整数倍,5就要对齐到8(4*2)
三、总结:
学会使用结构体、位段、枚举、联合体,了解他们的特点优势,可以增强项目工程代码的可读性、可维护性,掌握计算这些结构体的方法,恰当地分配结构体内存大小可以增强项目工程的效率,减少内存占用
还有一个简单的思维导图,方便大家复习巩固
结语:
以上就是我分享的C语言特殊类型的全部内容了,希望对大家有些帮助,也希望与一样喜欢编程的朋友们共进步
谢谢观看
如果觉得还阔以的话,三连一下,以后会持续更新的,我会加油的
祝大家早安午安晚安