【进阶C语言】自定义类型——结构体+枚举+联合体

news2024/11/27 11:46:35

文章目录

  • 一.结构体
    • 1.内存对齐
      • 存在的原因
      • 规则
      • 举例
    • 2.位段
  • 二.枚举
    • 定义
    • 枚举的优点
  • 三.联合体
    • 定义
    • 特点
    • 内存计算

一.结构体

1.内存对齐

存在的原因

  1. 平台原因(移植原因):
    不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

比如:在某些硬件上整形变量只能在四的倍数处的地址进行访问,double类型必须在八的倍数处的地址进行访问。如果不对齐则可能导致硬件异常。

  1. 性能原因:
    数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
    举例:
struct
{
  char i;
  int n;
};

在32位的机器上,读取此结构体,一次读取32个比特位也就是四个字节,那么想要在内存边界上读取到i变量的内存,先要把第一次读取的三个字节拿出来,再把第二次读取的1个字节拿出来,这样省了空间但是浪费了时间,所以为了更快的读取成员变量出现了对齐,这样虽然浪费了空间,但是大大省略了时间,总体来说还是比较赚的。

规则

  1. 第一个成员在与结构体变量偏移量为0的地址处。

  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。

  3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

注意:
1.这里的最大对齐数包含嵌套结构体成员的对齐数
2.VS中默认的值为8,gcc无默认对齐数
3.#pragma pack()可设置默认对齐数,一般设置偶数,不设置奇数,我认为是按照数据类型一般都为偶数个字节。
4.偏移量:指的是与开辟的结构体的起始位置的地址进行比较,偏移的字节个数就是偏移量,我们可以当做下标进行处理。
5.数组的对齐数为其元素的大小

举例

1.成员变量相同开辟的顺序不同

struct S1
{
	char c1;
	int i;
	char c2;
};

图解:
在这里插入图片描述

struct S2
{
	char c1;
	char c2;
	int i;
};

在这里插入图片描述

2.位段

定义:
 C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或称“位域”( bit field) 。利用位段能够用较少的位数存储数据。

1.位段的成员必须是 int、unsigned int 或signed int 或char。
2.位段的成员名后边有一个冒号和一个数字。(数字指的是开辟的内存个数)
3.位段的数字范围是不能超过变量的比特个数,并且大于0.
4.位段是只能在结构体里面出现的。
5.位段变量在开辟时,如果剩余的空间够用,继续使用剩余空间,若不够,则再开辟一个数据类型的变量,继续使用。

举例:

struct A
{
	int a : 2;
	int b : 5;
	int c : 10;
	int d : 30
};

在这里插入图片描述
优点:能够很好的节省空间
缺点:

1.位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。(比如开辟时是从右边还是从左边在不同的平台上可能不同)
2… int 位段被当成有符号数还是无符号数是不确定的。
3. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。
4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

二.枚举

定义

一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。
简单来说,就是一个集合的有限个可能列了出来。

enum Color//颜色
{
RED,//默认是0
GREEN,//默认是1
BLUE//默认是2
};
int main()
{
	enum Color c = RED;//创建一个枚举变量
	return 0;
}

注意
1.枚举类型在定义时,可以进行赋初始值,这个值是整形类型,但是使这个元素是枚举类型,具有值属性(后面的元素如果没有赋初始值则会以上一个元素的值自增一),又因为它可以进行类型的定义,又具有类型的属性,但在变量的定义时整形跟枚举类型是两种类型,所以不能用默认的值(整形),来给枚举变量赋值,而应该用创建的具有实际意义的枚举变量的元素。

枚举的优点

  1. 增加代码的可读性和可维护性(相当于放在了一个集合内部,便于整理)
  2. 和#define定义的标识符比较枚举有类型检查,更加严谨(类型属性)。
  3. 防止了命名污染(封装,)
  4. 便于调试(具有类型属性不会在预编译阶段被改,而define会将其定义的值进行替换)
  5. 使用方便,一次可以定义多个常量(不用一直写define,直接一个大括号就搞定)

三.联合体

定义

在进行某些算法的C语言编程的时候,需要使几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构,简称共用体,也叫联合体。

特点

1.联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。
2.联合体的成员的地址都相同,都是从起始位置读取该类型大小的值
3.联合体的空间是公用的,这也就是说在改变一个变量的值,就可能改变所有成员的值。

内存计算

规则:
1.联合的大小至少是最大成员的大小。
2.当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍

举例:

union Un
{
	int i;
	struct
	{
		short c;
		short d;
	};
};
int main()
{
	union Un c = {0};
	c.i = 0x11223344;
	printf("%x ", c.c);
	printf("%x ", c.d);
	return 0;
}

这里的最大元素为4个字节,最大对齐数为4,因此为联合体大小为四个字节
小端存储:
在这里插入图片描述
如果结构体读c则拿到的是 44 33(十六进制)读d拿到的是22 11(十六进制)
大端存储:
11 22 33 44
读取c拿到:11 22(十六进制)
读取d拿到: 33 44 (十六进制)
由此我们可以得到一个结论在大端存储和小端存储拿到的值可能不一样但是会相反。

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

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

相关文章

【PHPWord】使用PHPWord自动生成TOC根据内容的目录完整示例 | table of contents (TOC)

目录 一、什么是Word中的目录二、目录的生成在Word中是如何操作的三、PHPWord中目录的生成1. 插入目录2.添加页码3.修改目录的字体样式4.修改目录的目录样式5.修改生成目录的标题等级四、完整示例代码和效果图一、什么是Word中的目录 在我们日常使用中,经常需要在文档中插入目…

微信小程序项目实例——心情记事本

微信小程序项目实例——心情记事本 文章目录微信小程序项目实例——心情记事本一、项目展示二、首页三、效果图文末项目代码见文字底部,点赞关注有惊喜 一、项目展示 心情记事本是一款可以记录当前心情和生活的记事本 用户可以选择当前的心情(开心、平淡…

自己写一个简单的工作流引擎V1

1.需求 市面上常见的工作流组件一般都是前端通过拖拉拽配置流程图,后端流程引擎解析流程配置,这里我们手写一个简单的流程引擎,先实现串行流程,例如下: 小明提交了一个申请单,然后经过经理审批&#xff0…

【学习】Meta Learning、

文章目录一、Meta Learning什么是元学习?元学习–第1步元学习–第2步元学习–步骤3架构ML和Meta回顾GD学习好的初始化参数学习学习率NAS寻找网络结构data augmentationSample ReweightingFew-shot Image Classification元学习与自我监督学习元学习和知识蒸馏元学习和…

语音识别综述

语音识别的基本单位 Phoneme: 音位,音素 a unit of sound 是声音的最基本单位**,每个词语token的声音由多个 phoneme 组成** Grapheme(字位) smallest unot of a writing system 每个单词书写最基本的单位&#xff…

Vue初识系之Webpack

文章目录一 Webpack简介二 Webpack的安装和使用2.1 安装Webpack2.2 配置参数初识2.3 使用webpack一 Webpack简介 webpack本质上是一个现代JavaScript应用程序的静态模块打包器(modulebundler)。当webpack处理应用程序时,它会递归地构建一个依…

LeetCode(String)2194. Cells in a Range on an Excel Sheet

1.问题 A cell (r, c) of an excel sheet is represented as a string “” where: denotes the column number c of the cell. It is represented by alphabetical letters. For example, the 1st column is denoted by A, the 2nd by B, the 3rd by C, and so on. is the ro…

Java抽象类:概述

1.抽象类 在Java中abstract是抽象的意思,可以修饰类、成员方法。 abstract修饰类:这个类就是抽象类。 abstract修饰方法:这个方法就是抽象方法。 修饰符 abstract class 类名{修饰符 abstract 返回值类型 方法名(形参列表); } public ab…

助力旅游业复苏,IPIDEA让旅游资源聚合更简单

目前我国疫情防控政策的优化,极大的简化了出境手续,对于深受疫情影响的旅游业来说,这无疑是一个好消息。随着旅游消费需求持续的增长,旅游业将会逐渐进入全面复苏的新进程,焕发新的活力。 全球旅游市场都在关注着中国…

ABAP 内表的定义,与PERFORM传值的定义<转载>

很早之前就想总结一下内表和定义和perform的传值定义,结果要么没时间,要么有时间忘了。 今天在网上看到一个博文写的还比较清楚,故读书人窃来一用 ^ - ^ 原文链接:https://blog.csdn.net/lmf496891416/article/details/117702217 …

5 UML views and the 9+4 UML Diagrams 关系

Refer:UML2.5图概述-Lib教程 UML旨在通过的建模图形Diagram,可视化 5 种不同的视图View。 这五个视图是: 一、Users View : 用户视图 1. Use case Diagram:用例图性 二、Structural Views : 结构视图 2. Class Diagrams&#xf…

数码钢琴行业市场运行态势及投资战略规划分析

2023-2029年中国数码钢琴行业市场运行态势及投资战略规划报告 报告编号:1691312 免费目录下载:http://www.cninfo360.com/yjbg/jdhy/sxjd/20230109/1691312.html 本报告著作权归博研咨询所有,未经书面许可,任何组织和个人不得以…

C语言进阶(5)——内存操作函数的解析

1.memcpy函数 void * memcpy ( void * destination, const void * source, size_t num ); 用途:各种数据类型,从源数组拷贝num个字节到指定目标空间里面。 要点: (1)函数memcpy从source的位置开始向后复制num个字节的数…

【虹科案例】虹科数字化仪在超声波中的应用以及如何选择合适的数字化仪

图 1:虹科M4i.4451-x8——用于采集超声波信号的 PCIe 4 通道 14 位 500 MS/s 数字化仪 超声波是一种频率大于人类听觉范围上限的声学声压波。超声波设备的工作频率从 20 kHz 到几千兆赫兹。表 1 总结了一系列常见的超声波应用的特性。 每个应用中使用的频率范围反映…

JSP SSM 仓库租赁管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 JSP SSM 仓库租赁管理系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采…

C语言进阶——字符串函数和内存函数

目录 一. strlen 二. strcpy 三. strcat 四. strcmp 五. strncpy 六. strncat 七. strncmp 八. strstr 九. strtok 一. strlen 字符串以 \0 作为结束标志,strlen函数返回的是在字符串中 \0 前面出现的字符个数(不包 含 \0 …

TCP/IP网络编程(1)——理解网络编程和套接字编程

文章目录一、理解网络编程和套接字编程1.1 socket套接字1.1.1 一个例子来表示TCP的网络连接1.1.2 程序实现1.2 文件操作1.2.1 文件描述符一、理解网络编程和套接字编程 1.1 socket套接字 网络编程又称为套接字编程,为什么要用套接字?我们把插头插到插座…

Linux常用命令——ngrep命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) ngrep 方便的数据包匹配和显示工具 补充说明 ngrep命令是grep命令的网络版,他力求更多的grep特征,用于搜寻指定的数据包。正由于安装ngrep需用到libpcap库, 所以支持大量的操…

【Java】面向对象笔记

开篇 主线 类及类的成员 属性、方法、构造器; 代码块,内部类 面向对象三大特征 继承、封装、多态 其他关键字 this,super,static,final,abstract,interface等 面向对象的两个要素 一、是什么 类:对一类事物的描述,是抽象的…

Java综合练习

Java综合练习一、涉及到的知识点二、卖飞机票三、找质数四、开发验证码五、数组元素的复制六、评委打分七、数字加密八、数字解密九、抢红包方法一:判断是否被抽取方法二:打乱数组十、模拟双色球土、二维数组一、涉及到的知识点 变量、数组运算符程序流…