当前位置:网站首页>C语言进阶篇 四.自定义类型详解
C语言进阶篇 四.自定义类型详解
2022-07-24 05:16:00 【且随疾风前行->】
目录
结构体
结构体类型的声明
结构体的各种数据类型的集合,这些数据被称为结构体成员。创建结构体变量时,每个成员各自占有空间。
声明格式:
结构的自引用
结构体变量的定义和初始化
定义结构体变量有多种方式,例如
结构体内存对齐
在计算结构体大小是需要考虑结构体内存对齐,结构体内存对齐存在的原因如下:
1.平台原因:某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2.性能原因:在访问未对齐的内存,处理器需要访问两次,而对齐的内存只要访问一次
故数据结构(栈)应该尽可能在自然边界上对齐。
内存对齐规则:
1.第一个成员对齐到与结构体变量偏移为0的位置
2.其他成员对齐到各自对齐数的整数倍(对齐数是编译器默认对齐数与成员大小(字节数)的较小值)
3.结构体总大小为各个成员最大对齐数的整数倍
4.如果嵌套结构体,嵌套结构体对齐到自己成员最大对齐数的整数倍,结构体总大小是所有成员最大对齐数(含嵌套结构体的成员)的整数倍
VS2022编译器默认的对齐数是8,用#pragma pack(4)可以修改编译器的默认对齐数为4
结构体传参
结构体传参通常传结构体的地址,即结构体指针,这样做节省内存的开销,因为结构体传参参数需要压栈,结构体较大时系统时间和空间开销大。
结构体实现位段(位段的填充&可移植性)
位段是结构体中的一种特殊的类型,(位段不具跨平台性,注重可移植程序避免使用)位段声明规则如下:
struct S {
char a:3;
char b:4;
char c:5;
char d:4;
};
struct S s = {0};
s.a = 5; s.b = 12; s.c = 3; s.d = 4;在VS下,在内存中布局如下(图有点草,c=3上面是00011打错了):
可见位段在字节中是从右向左开辟,不够位段成员大小则重新在更高地址开辟一个字节

在编译器下查看结构体s的内存内容发现确实如此:
注意:位段的跨平台问题(基于以下原因,位段不支持跨平台性)
枚举
枚举是指将可能取值一一列举的类型,例如
枚举的优点
相比define定义的常量,枚举有类型检查更加的严谨。
定义枚举类型一次定义多个常量快捷方便,枚举的常量有各自的名称且是同一个类型,增加了代码的可读性便于维护。
枚举的使用
enum Color//颜色
{
RED=1,
GREEN=2,
BLUE=4
};
enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异
像clr=4;这样赋值是不合理的因为enum color类型和int 类型不同。虽然enum Color和int类型不同,但编译器却能正常运作,求枚举类型的变量的大小发现是4个字节

联合
联合类型的定义
联合大小的计算
因为联合的成员是共用同一块内存空间的,这样一个联合体类型变量的大小,至少是最大成员的大小,但这不是联合体类型变量的最终大小,因为联合体也存在内存对齐
规则是,联合体大小至少是最大成员的大小;若其不是联合体成员最大对齐数的整数倍,则还要对齐到整数倍。(数组对齐数是数组成员类型的对齐数)
例如:

首先VS2022下编译器的默认对齐数是8,c的对齐数是1,i的对齐数是4,数组a的对齐数是1,
这样联合un的大小至少是5,然后对齐到4的整数倍8
为什么至少是5而不是4呢,数组a算一个成员还是数组中各个成员都算做联合体的一个成员?
下面的例子说明了:

可见整个数组a是联合体的成员,否则结果就是8而不是12了。
联合的特点
因为联合体成员公用一块空间,联合的特点自然是内存的存储上与结构体有所不同。
例如:

i的大小刚好是整个联合体的大小,c则是一部分,
故i=0x22334455(4字节)时,c就等于0x55(1字节),从内存中也很好理解。
边栏推荐
- C primer plus learning notes - 6. Arrays and pointers
- Use of fiddler packet capturing tool
- NumPy 统计相关函数示例教程
- In his early 30s, he became a doctoral director of Fudan University. Chen Siming: I want to write both codes and poems
- Read the summary of "machine learning - Zhou Zhihua"
- 使用d2l包和相关环境配置的一些血泪心得
- C primer plus learning notes - 5. Pointer
- PPPoE gateway simulation environment setup
- [Huang ah code] Introduction to MySQL - 3. I use select *, and the boss directly rushed me home by train, but I still bought a station ticket
- MySQL深入了解
猜你喜欢

Teach you how to weld CAD design board bottom (for beginners) graphic tutorial

jdbc封装一个父类减少代码重复

Using a* heuristic search to solve maze routing problem

反射的介绍

酒店IPTV数字电视系统解决方案

Use of fiddler packet capturing tool

1. Pedestrian recognition based on incremental occlusion generation and confrontation suppression

Introduction to reflection

Theoretical basis of machine learning

T 6-10
随机推荐
JSP+Dao整合
Bear market bottoming Guide
CentOS 7安装Mysql5.6.37
跟李沐学ai 线性回归 从零开始的代码实现超详解
ssm的整合
1、基于增量式生成遮挡与对抗抑制的行人再识别
[deep learning] (III) image classification
【NumPy】
Accuracy of% connections. Now it is planned to meet the demand. The number of enterprises is enough
The difference between compiled language and interpreted language
Web development
Token of space renewable energy
T 11-20
Jsp+dao integration
NFS shared services
Drools development decision table
Embedded system transplantation [2] - Construction of cross development environment
Add, delete, modify and check JDBC
泛型和注解
c2-随机产生函数种子seed、numpy.random.seed()、tf.random.set_seed学习+转载整理