C进阶 自定义类型

目录

前言

一  结构体 

二  结构体的存储

三  位段

 四  枚举

五  联合体

总结


前言

我们之前学习的int  char  double ......都是内置类型,但是我们今天所学习的是自定义类型,比如联合体,结构体,枚举


一  结构体 

结构体是一些值的集合,这些值统称为成员变量,每个成员都是可以用不同的的基本数据类型

结构体的使用场景:

结构体的意义在于可以进行封装一个整体的所有变量,这个是十分便捷的,这样就可以不用重复的操作进行重复的定义相同的东西,比如我们要统计一个班级的学生的学号,姓名,成绩,那么我们就可以使用结构变量,下面这个是使用结构体和不使用结构体的例子

struct student {int number;char name[5];int score;
};
int main() {//不使用结构体int xiaomingnumber;char xiaomingname[5];int xiaomingscore;int xiaowangnumber;char xiaowangname[5];int xiaowangscore;//使用结构体struct student xiaoming, xiaowang;
}

结构体的基本形式:

struct inflatable{char name[20]; float volume; double price;
};

结构体的匿名形式

struct{int a;int b;
}x,b;

结构体需要注意的点
1  每个变量之间以分号隔开
2  最后要加上分号,因为这个是结构体的声明
3  匿名结构体只可以创建的时候定义变量


定义结构后,便可以创建这种类型的变量了


struct inflatable hat;            // hat is a structure variable of type inflatable 
struct inflatable woopie_cushion; // type inflatable variable 
struct inflatable mainframe;      // type inflatable variable

由于 hat 的类型为 inflatable,因此可以使用成员运算符(.)来访问各个成员。例如, hat.volume 指的 是结构的volume 成员, hat.price 指的是 price 成员,当然在C++里面是可以把前面的struct省掉


初始化方式

inflatable guest = {"Glorious Gloria", // name value 1 .88,             // vol ume value 29.99              // price value 
}

和数组一样,使用由逗号分隔值列表,并将这些值用花括号括起

结构数组
inflatable 结构包含一个数组 (name)。也可以创建元素为结构的数组,方法和创建基本类型数组完全相同。例如,要创建一个包含 100个inflatable 结构的数组,可以这样做:

 inflatable gifts[100]; / / array of 100 inflatable structures

接下来的赋值操作也就是跟数组一样

结构中的位字段
创建与某个硬件设备上的寄存器对 应的数据结构非常方便。字段的类型应为整型或枚举(稍后将介绍),接下来是冒号,冒号后面是一个数字, 它指定了使用的位数。可以使用没有名称的字段来提供间距。每个成员都被称为位字段 (bit field)。下面 是一个例子:

struct student {int number : 4;char xing  : 1;};

就是规定这个变量占用多少的字节,这个占用字节数是自己规定的

二  结构体的存储


结构体的对齐规则
1 第一个成员在与结构体变量的偏移量为0
2 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处
3 结构体的总大小为最大对齐数的整数倍


我们以下面这个结构体为例子来讲解

struct  student{ char c2;int number;char c1;
};

1  第一个成员在与结构体变量的偏移量为0

这个就是这个变量i前面没有偏移量直接占用0这个各自

2  其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处
我们以其他的变量来讲解这个东西

我们可以看到这个空白的,这个就是偏移量,然后偏移到(对齐数)的整数倍,一般都是4,然后我们就可以得到这个是8了

3  结构体的总大小为最大对齐数的整数倍
我们最后到了这一步之后就是4的整数倍,里面最大的对齐数为4,所以为8
 

为什么会有对齐原则


1  平台原因
不是所有的硬件平台都可以任意的访问任意地址的数据的,某些平台只可以在某些地址处去某些特定的数字,否则会抛出异常

2  性能原因
1  在现在的CPU里面,访问内存是按照快的标准执行的,一个典型的块的大小为4字节,8字节甚至更大,这与CPU的数据总线宽度有关,32位通常是4字节,64通常是8字节


2  数据总线宽度
CPU一次性传输可以处理多少的数据的字节数
宽度越大,CPU每次处理的数据量就越大
32位数据总线宽度意味着32条并行通道,这样CPU一个时间周期可传输32位数据

由于CPU是以快为主,所以就会牺牲空间提高性能
 

三  位段


位段的声明和结构体的声明是类似的,有两个不同
1,成员必须为整形家族的        2,位段的成员后面都带有一个冒号和数字

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

这个就是说a占用2个字节     b占用3个字节     c占用4个字节    d占用5个字节,运用这个就是压榨内存,因为内存是一个非常昂贵的资源

内存分配
原则
1  位段的成员都是整形家族
2  空间按照需以4字节或者1字节的方式来开辟
3  位段涉及很多不确定因素,位段考虑跨平台和可移植性应避免使用位段
以上面为例子:2+3+4+5=14,但是真的是这样吗?

首先线开出1字节,看够不够用,不够用就再开辟一个字节,继续存储,中间那个空白的就是浪费的
所以他的分配方式就是:不断地开辟一字节,看是否够用,不够的话就再继续开辟,直到所有的都满就好

位段在跨平台编程中存在诸多问题,主要体现在以下几个方面:

1. 位段的符号性不确定

  • int 类型的位段在某些平台上可能被解释为有符号数,而在另一些平台上可能被解释为无符号数。

2. 位段的最大位数不确定

  • 不同平台的位段最大位数可能不同。例如,16位机器上最大为16位,32位机器上最大为32位。如果定义的位数超过目标平台的最大限制,会导致编译错误。

3. 内存分配顺序不确定

  • 位段成员在内存中的分配顺序(从左到右还是从右到左)在标准中未明确定义,不同编译器可能有不同的实现。

4. 位段的存储布局不确定

  • 当一个位段的剩余空间不足以容纳下一个位段时,编译器可能会选择丢弃剩余空间或利用剩余空间,这种行为在不同平台上是不确定的。

5. 编译器差异

  • 不同编译器对位段的实现和优化方式可能不同,这也会导致跨平台时的行为差异。

 四  枚举

enum sex{MALE;FEMALE;SECRTX;};

作用:是提高代码的可读性和在进行项目编写的时候,提高规范性
计算机会根据你的放置进行推算,但是是从0开始
如上述就是MALE为0……
枚举里面输入数字的话会更加的清晰

五  联合体


联合体的格式

uion un{int a;char i;
};

联合体就是一起公用一个空间,最妙的放法就是用a不用i,用i不用a,一定程度地减少空间地消耗

联合体地大小 
1  联合体的大小为成员里面最大类型的大小
2  当最大成员不是最大对齐树的整数倍的时候,就要对齐到最大成员的整数倍数
我们来举个例子

union Un{char arr[5];int a;
};

5和4字节放到了一起,但是要对齐到最大对齐数的整数倍数,我们就开到了8 

剩下的空白是不用的,开辟不用
char arr[5]和5个char类型的变量是不一样的
第一个是开辟了5个,第二个是开辟了1个,共用一个 


总结

结构体
初始化,定义,存储
位段
初始化,定义存储
枚举
定义,用处
联合体
定义存储

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32的HAL库开发---ADC采集内部温度传感器

一、STM32内部温度传感器简介 二、温度计算方法 F1系列: 从数据手册中可以找到V25和Avg_Slope F4、F7、H7系列只是标准值不同,自行查阅手册 三、实验简要 1、功能描述 通过ADC1通道16采集芯片内部温度传感器的电压,将电压值换算成温度后&…

【PyQt5】python可视化开发:PyQt5介绍,开发环境搭建快速入门

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

Android 串口通信

引言 在iot项目中,Android 端总会有和硬件通信。 通信这里:串口通信,蓝牙通信或者局域网通信。 这里讲一下串口通信。 什么是串口? “串口”(Serial Port)通常是指一种用于与外部设备进行串行通信的接口。…

跟据spring boot版本,查看对应的tomcat,并查看可支持的tomcat的版本范围

一 查看springboot自带的tomcat版本: 可直接在项目中找到Maven Dependencies中找到tomcat版本 二、查看SpringBoot内置tomcat版本的支持范围 我这边是跟据maven仓库查看的 首先跟据链接打开maven仓库:https://mvnrepository.com/ 然后搜索&#xff1a…

磐维数据库双中心容灾流复制集群搭建

1. 架构 磐维数据库PanWeiDB V2.0.0基于gs_sdr工具,在不借助额外存储介质的情况下实现跨Region的异地容灾。提供流式容灾搭建,容灾升主,计划内主备切换,容灾解除、容灾状态监控等功能。 2. 部署双中心磐维集群 2.1. 主集群 角色…

Spring事务原理 二

在上一篇博文《Spring事务原理 一》中,我们熟悉了Spring声明式事务的AOP原理,以及事务执行的大体流程。 本文中,介绍了Spring事务的核心组件、传播行为的源码实现。下一篇中,我们将结合案例,来讲解实战中有关事务的易…

【机器学习】【KMeans聚类分析实战】用户分群聚类详解——SSE、CH 指数、SC全解析,实战电信客户分群案例

1.引言 在实际数据分析中,聚类算法常用于客户分群、图像分割等场景。如何确定聚类数 k 是聚类分析中的关键问题之一。本文将以“用户分群”为例,展示如何通过 KMeans 聚类,利用 SSE(误差平方和,也称 Inertia&#xff…

20-R 绘图 - 饼图

R 绘图 - 饼图 R 语言提供来大量的库来实现绘图功能。 饼图,或称饼状图,是一个划分为几个扇形的圆形统计图表,用于描述量、频率或百分比之间的相对关系。 R 语言使用 pie() 函数来实现饼图,语法格式如下: pie(x, l…

搭建 Hadoop 3.3.6 伪分布式

搭建 Hadoop 3.3.6 伪分布式 IP 192.168.157.132 初始化操作 更改yum源 # 1_1.安装Wget yum install wget# 1_2.备份CentOS-Base.repo文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo_bak# 2.下载阿里yum源配置 wget -O /etc/yum.repos.d/Cen…

python电影数据分析及可视化系统建设

博主介绍:✌程序猿徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

手机壁纸设计中,金属质感字体可以为壁纸增添独特的视觉效果和高端感

在手机壁纸设计中,金属质感字体可以为壁纸增添独特的视觉效果和高端感。以下是一些关于金属质感字体在手机壁纸设计中的应用建议和案例分析: 1. 金属质感字体的特点 视觉冲击力强:金属质感字体具有独特的光泽和质感,能够在视觉上…

使用ezuikit-js封装一个对接摄像头的组件

ezuikit-js 是一个基于 JavaScript 的视频播放库,主要用于在网页中嵌入实时视频流播放功能。它通常用于与支持 RTSP、RTMP、HLS 等协议的摄像头或视频流服务器进行交互,提供流畅的视频播放体验。 主要功能 多协议支持:支持 RTSP、RTMP、HLS …

PHP post 数据丢失问题

max_input_vars是PHP配置选项之一,用于设置一个请求中允许的最大输入变量数。它指定了在处理POST请求或者通过URL传递的参数时,PHP脚本能够接收和处理的最大变量数量。 max_input_vars的默认值是1000,意味着一个请求中最多可以包含1000个输入…

jenkins docker容器中安装python3.9环境

在运维过程中,不过避免的需要使用到python,在jenkins 的docker容器中,是没有python环境的,需要我们自己手动安装一下。 查看是否有工具apt-get 直接输入apt-get 然后回车,出现以下内容,表示支持apt-get命令…

《Spring实战》(第6版) 保护Spring

第1部分 Spring基础 第4章 使用非关系型数据 关系型数据库一直是首选,近年来"NoSQL"数据库提供了数据存储的不同概念和结构。 SpringData为很多NoSQL数据库提供了支持,包括MongoDB、Cassandra、Couchbase、Neo4j、Redis等,无论选…

SQLMesh 系列教程7- 详解 seed 模型

SQLMesh 是一个强大的数据建模和管道管理工具,允许用户通过 SQL 语句定义数据模型并进行版本控制。Seed 模型是 SQLMesh 中的一种特殊模型,主要用于初始化和填充基础数据集。它通常包含静态数据,如参考数据和配置数据,旨在为后续的…

【JavaEE】-- 多线程(初阶)2

文章目录 3.线程的状态3.1观察线程的所有状态3.2线程状态和状态转移的意义 4.多线程带来的的风险-线程安全 (重点)4.1观察线程不安全4.2 线程不安全的原因4.2.1 线程调度是随机的4.2.2 修改共享数据4.2.3 原子性4.2.4 内存可见性4.2.5 指令重排序 4.3解决之前的线程不安全问题 …

安卓系统远程控制电脑方法,手机远控教程,ToDesk工具

不知道大家有没有觉得手机、平板虽然很好用,却也仍存在有很多替代不了电脑的地方。就比如说撰写文档、做数据报表啥的就不如PC端操作般方便,就跟别说PS修图、AE视频剪辑等需高性能设备来带动才易用的了。 好在也是有对策可解决,装个ToDesk远程…

机器学习(李宏毅)——RL(强化学习)

一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记,感谢台湾大学李宏毅教授的课程,respect!!! 二、大纲 What is RL?Three steps in MLPolicy GradientActor-CriticReward Shaping 三、What …

【Go】Go wire 依赖注入

1. wire 简介 wire 是一个 Golang 的依赖注入框架(类比 Spring 框架提供的依赖注入功能) ⭐ 官方文档:https://github.com/google/wire 这里关乎到编程世界当中一条好用的设计原则:A用到了B,那么B一定是通过依赖注入的…