C语言:自定义类型进阶(结构体、联合体、枚举)

news2024/9/24 7:25:20

自定义类型(结构体、联合体、枚举)

一、结构体

(一)结构体的内存对齐

1、结构体内存对齐规则

(1)引子

结构体占多少内存呢,是不是各个变量的内存之和呢,先用一段代码来验证我们的猜想吧。下面代码中,如果我们猜想正确,那么打印结果就应该是三个变量的字节数之和,答案为6.
在这里插入图片描述
在这里插入图片描述

(2)offsetof 宏函数
offsetof (type,member)   返回成员变量number距离结构体首地址的偏移量(单位是字节)

我们对结构体S的a, b, c,分别查看他们的偏移量。
在这里插入图片描述
在这里插入图片描述
根据这个结果,我们可以画出下面的内存图解。

在这里插入图片描述

(3)内存对齐原理

1、结构体的第一个成员变量对齐到和结构体首地址偏移量为0的地址处

2、其它成员变量要对齐到对齐数的整数地址处。
对齐数 = 编译器的默认对齐数该结构体成员变量的大小 中的较小值

3、结构体大小为最大对齐数的整数倍。

4、如果结构体嵌套结构体,嵌套的结构体变量要对齐到自己成员变量中最大对齐数整数倍的地址处。结构体大小就是所有成员(包含结构体中的成员)中最大对齐数的整数倍。

求下面代码的输出结果。

struct S1 {
	double a;
	char b;
	int c;
};

struct S2 {
	char a;
	struct S1 b;
	double c;
};

int main() {
	printf("%zd", sizeof(S2));
	return 0;
}

要求结构体S2的大小,我们首先要求结构体S1的大小,分析如下。
在这里插入图片描述
接着再求结构体S2的大小
在这里插入图片描述
分析结果为32和我们预料的一致。
在这里插入图片描述

(4)自定义默认对齐数

使用 #pragma pack(int val)可以设置默认对齐数。
例如:

 	#pragma pack(1)//将默认对齐数设置为1
 struct S {
 	char c1;
 	int n;
 	char c2;
}
	#pragma pack() //重置默认对齐数

2、为什么要内存对齐

所以说不仅步骤麻烦,还消耗了内存,为什么还要内存对齐呢。用空间换时间

(1)性能原因

为了访问未对齐的数据,处理器需要访问多次,而处理对齐的数据,处理器访问次数减少。

struct S {
	char a;
	int b;
};

在32位平台中,我们一次可以访问四个字节。下面我们访问变量 b 并用内存对齐和非内存对齐来对比
内存对齐
在这里插入图片描述
**加粗样式**
非内存对齐
通过非内存对齐,发现我们起码要通过两次才能拿到 int 成员变量。
在这里插入图片描述

(2) 平台原因

不是所有平台都能访问任意地址上的任一数据。

(二)结构体实现位段

1、位段的定义

位段中的位指的是二进制位,和结构体类似,有两点不同
1、位段的类型只能是 int 、signed int、unsigned int 或者是char(整形家族),C99中引入了其它类型。

2、位段后面比较加冒号和数字,表示为该变量分配多少个比特位的空间。
如下:

struct S {
	int a : 2;
	int b : 6;
	int c : 4;
	int c : 4;
};

2、位段的储存

位段也有自己的储存方式,我们分析下面一段代码进行体会

struct S {
	int a : 3;
	int b : 4;
	int c : 5;
	int d : 4;
};

int main() {
	printf("%d", sizeof(struct S));
	return 0;
}

在这里插入图片描述
注意:
位段在初始化变量时候不可以用scanf,因为&符号是以一个字节为单位,显然如果一个字节里面有多个变量的话,会引发错误。

3、位段的不可跨平台性

1、数据类型解释的不确定性:

有符号与无符号:位段中的int类型成员是否被当作有符号数还是无符号数,在不同的编译器和平台上可能存在差异。

位数限制:位段中成员的最大位数在不同的编译器和平台上可能有所不同。例如,在16位机器上,位段的最大位数可能为16,而在32位机器上可能为32。

2、内存分配方式的不确定性:

分配方向:位段成员在内存中的分配方向(从左到右或从右到左)在C语言标准中并未明确定义,这可能导致在不同的编译器和平台上出现不同的内存布局。

空间利用:当一个结构体包含多个位段成员,且后一个成员无法完全容纳在前一个成员剩余的位中时,是舍弃剩余位还是尝试利用这些位,也是不确定的。

4、位段的应用

网络协议中用来包装IP数据报(就好像外卖一样,需要填写目的地的信息),而位段进行封装就会使得包裹更加便捷。

二、枚举

(一)枚举的定义

我们可以把生活中一些事物所对应的情况一一列举处来,就是枚举。
如下,其中enum就是枚举类型,{}里的内容就是枚举常量。
在这里插入图片描述
变量中的枚举常量默认赋初始值为0 1 2 3 … 也可以自定义赋值。自定义赋值时,可以选择性赋值,没有赋值的会序列化自动赋值。

(二)枚举的优点

在这里插入图片描述
枚举的优点用以下代码可以充分体现。

enum Option
{
	EXIT,//0
	ADD,//1
	SUB,
	MUL,
	DIV
};

void menu()
{
	printf("**********************************\n");
	printf("****** 1. add    2. sub     ******\n");
	printf("****** 3. mul    4. div     ******\n");
	printf("****** 0. exit              ******\n");
	printf("**********************************\n");
}

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case SUB://
			break;
		case ADD:
			break;
		case MUL:
			break;
		case DIV:
			break;
		case EXIT:
			printf("退出\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);

	return 0;
}

三、联合体

(一)联合体的储存

我们直接将联合体的储存是因为他和结构体上面就一个本质差别:联合体成员公用同一块空间(所以联合也叫共用体)。
规则:
1、联合的大小至少是最大成员的大小。
2、当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
在这里插入图片描述
在这里插入图片描述

(二)联合体的应用

联合体和结构体嵌套使用,可以节省很多内存:
在这里插入图片描述
例如我们需要使用该结构体,如果前面三个公共属性必选,而特征属性非必选,我们可以设置下面的代码来减少结构体的内存:

在这里插入图片描述

四、结束语

到此这篇文章就告一段落了,小编还会继续用心对待每一篇文章,与大家一起进步,非常有幸能得到大家的支持!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1966403.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【HM】DevEco Studio提供Hot Reload(热重载)能力确实好用!帮助开发者更快速进行调试。但要注意以下几点?

​​ 仅支持开发者在真机上运行/调试运行: 1、运行时,选择带H标识的entry; 2、运行设备选择已连接的真机; 3、运行中修改了文件后,点击H标识,在真机即刻可见效果。 注意约束条件: 只支持真…

硬盘信息,电脑硬盘查看工具

硬盘信息,电脑硬盘查看工具 硬盘信息,电脑硬盘查看工具

FPGA开发——状态机的使用

一、概述 我们在使用FPGA进行开发的过程当中,实现一个东西用得最多的实现方法就是状态机的实现方法,用一句话总结就是万物皆可状态机,这和我们在学习Linux时常说的在Linux中万物都是文件差不多,这里就主要就是突出状态机的应用范…

Moretl 文件同步工具 1.1.0.3

永久免费: 前往Gitee最新版本 更新内容 Winform全部切换到.Net Framework 4.0. 更符合大部分的自动化设备. Web提供.Net Framework 4.0的运行时环境安装包 Web打开时,若当前IP为设备,直接显示设备信息 介绍 用途: 定时全量或增量 采集工控机,办公电脑文件以及日志.(SCADA,I…

Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件

​​ jmeter性能测试 1. Jmeter简介 Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件。相比Loadrunner而言,JMeter小巧轻便且免费,逐渐成为了主流的性能测试工具,是每个测试人员都必须要掌握的工具之一。 本文为JMeter…

进口不锈钢309S螺栓的应用优势

进口不锈钢309S螺栓因其优异的性能和广泛的应用范围而在许多行业中备受青睐。309S不锈钢是一种含硫的易切削不锈钢,具有良好的耐高温和耐腐蚀性能,使其成为高温环境下理想的选择。下面我们就来详细探讨一下进口不锈钢309S螺栓的应用优势。 一、309S不锈钢…

请你谈谈:spring拦截器的应用-preHandle postHandle afterCompletion执行顺序问题的讨论?

首先我们,给出一个demo来看下拦截器方法执行顺序: import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.…

第一百八十五节 Java XML教程 - Java DOM简介

Java XML教程 - Java DOM简介 DOM是标准的树结构,其中每个节点包含来自XML结构的一个组件。 XML文档中两种最常见的节点类型是元素节点和文本节点。 使用Java DOM API,我们可以创建节点,删除节点,更改其内容,并遍历节…

TypeScript 定义不同的类型(详细示例)

还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,ech…

抖音评论爬虫数据采集|抖音评论抓取工具|代码|源码

抖音评论提取软件使用说明 抖音视频评论提取到的内容:1:视频名称 2:视频作者 3:作者地址 4:视频地址 5:评论人昵称。6:评论人主页地址。7:评论内容 8:评论日期 软件支持…

我是客服新手,打字很慢,怎么办?

作为客服新手,打字速度缓慢可能影响工作效率,本文介绍了提高打字速度,以及使用聊天宝快捷回复工具等提效的诀窍 前言 我是客服新手,打字速度缓慢可能影响工作效率。本文将分享如何提高客服打字速度,包括使用聊天宝快捷…

协助我们进行论文写作的ChatGPT们究竟是如何工作的?

学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 大型语言模型(LLMs)正在彻底改变我们与人工智能的互动方式,特别是在写作和创作领域。这些先进的人工智能系统不仅在改变作家和创作者的格局&#xff…

<数据集>遥感航拍飞机识别数据集<目标检测>

数据集格式:VOCYOLO格式 图片数量:2398张 标注数量(xml文件个数):2398 标注数量(txt文件个数):2398 标注类别数:1 标注类别名称:[plane] 序号类别名称图片数框数1plane239815178 使用标注工具&#…

多微信管理不再难:聚合聊天神器助你轻松应对!

在当今社交媒体高度发达的时代,很多人都在使用多个微信账号来管理个人与工作联系。面对如此众多的信息沟通,如何高效管理成了一个难题。 幸运的是,聚合聊天神器的出现,彻底改变了这一局面,让我们轻松应对多微信账号的…

Flutter+Android/ios 桌面小组件

FlutterAndroid/ios 桌面组件 总结: Android和iOS 桌面小组件 需要原生去绘制小组件和更新数据,Flutter层 可以使用 MethodChannel 与原生 通信 来控制 更新数据,app无法主动控制 小组件的添加 和 删除, 只能是用户手动操作 。小…

利率虽降,贷款依旧难?政策暖风下的融资冷思考

​朋友们,最近听到不少人在吐槽贷款难的问题,咱们就来聊聊这背后的故事。你们知道吗?深圳的朱先生可是为这事儿头疼不已。他的公司急需一笔钱来结清货物尾款,可前一年的经营状况不佳,备用金早就见底了。朱先生四处求人…

随机化快速排序 python C C++ 图解 代码 及解析

一,概念及其介绍 快速排序由 C. A. R. Hoare 在 1960 年提出。 随机化快速排序基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别…

真假公主:一场容貌相似引发的宫廷阴谋

真假公主:一场容貌相似引发的宫廷阴谋 从古至今,每个人的心思都不相同,正如他们的面貌各不相同一样。即使人们的外貌没有明显的差异,但他们的内心和性格却是难以改变的。 话说人的面貌是最为独特的,因为每个人都是由不…

LNMP黄金架构搭建部署论坛网站

哈哈哈哈哈我终于部署出来了一个属于自己的论坛,虽然不怎么懂 部署Linux环境 关闭防火墙Systemctl stop firewalldSystemctl disable firewalld关闭selinuxSetence 0查看selinuxGeteforce 部署nginx环境 Yum i install httpd过滤apache的端口号看是否有80端口N…

移动自组织网络(MANET)与互联网连接的网关选择方案文献综述

以下内容节选自这篇综述论文《Gateway Selection Scheme for MANET to Internet Connectivity: A Survey》由Ritu Singh和Jay Prakash撰写,主要探讨了移动自组织网络(MANET)与互联网连接的网关选择方案。 在接下来的部分中,我们对…