【C语言】结构体与位段

一、前言

  • 我们之前学习过定义一个整型类型的变量又或者定义一个浮点型类型的变量...,这些变量可以描述一个整数又或者描述一个小数...,可无论是整数还是小数...,它们也只是简单对象。
  • 如果我们想要描述像一本书,一个人这种复杂对象,用我们之前学习过的类型去描述是完全不够的。一本书包含着很多信息,如书名、价钱、作者、出版时期...。
  • 我们会发现书的其中一个信息的表示我们是学过的,我们也能将其描述出来,如书名啊,作者啊,可以用字符数组,价钱啊,可以用整型...。
  • C语言为我们提供了一种自定义类型结构体,并我们提供了一个声明结构体类型的关键字:struct。

二、如何正确使用结构体?

1.结构体的使用(声明+创建变量+初始化)
  • 小结:创建变量的同时,给成员 ’赋值‘ 的同时,才叫初始化,且可以对全部成员进行’赋值‘;而赋值不可以同时操作结构体的全部成员。
2.匿名结构体
  • 匿名结构体:省去结构体标签的结构体类型叫做匿名结构体
  • 小结:由上面两张代码截图可知,匿名结构体若不被关键字typedef重定义,则只能使用一次(在声明的同时,也进行变量的创建)。
3.结构体自引用
  • 在声明结构体类型时候,包含一个类型为自身的成员,可不可以?
  • 下面我将拿将对上面的People类型的结构体,增加一个成员,让它用来描述伴侣;
  • 第一个代码例子,类型于我们平常所说的无限套娃——结构体包含结构体,而这种做法,导致的是结构体的内存无限大,无法计算结构体的内存,所以这点,C语言是明令禁止的。
  • 第二个代码例子,我用一个结构体指针,若有伴侣了,我让它指向下一个结构体的地址,若无伴侣,则就填NULL;而指针类型的大小只与平台有关,64位平台8个字节,32位平台4个字节。
  • 所以第二代码例子,则是正确的自引用方式——包含自身结构体的指针。
4.结构体的两个操作符
  • 那我们又该如何逐一去访问该结构体的成员呢?其实C语言为我们提供了两个操作符(.)/(->);
  • 当我们知道了结构体的变量的时候,用操作符(.)
  • 当我们知道了指针结构体地址的指针变量的时候,用操作符(->)
  • 小结:(*xcf.girl).name   <----->  xcf.girl->name

三、结构体的内存对齐

1.什么是内存对齐?
  • 结构体占内存中占据的字节并非是简单的内存成员类型大小的标量和,而是存在内存对齐这一规则。
  • 1.结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处;
  • 2.其余的成员对齐到,(某个数字)对齐数,的整数倍处;
  • 对⻬数 = 编译器默认的⼀个对⻬数与该成员变量⼤⼩的较⼩值
  • VS默认对齐数为8;
  • Linux中gcc没有默认对齐数,对齐数就是成员自身的类型大小。
  • 3.若存在嵌套结构体的情况,则结构体成员对齐到,自己成员中最大对齐数的,整数倍处;
  • 4.结构体最终内存的大小,是结构体中最大对齐数的整数倍。
  • 结构体中每一个成员都有对应的对齐数,对齐数最大的则为最大对齐数。
2.为什么存在内存对齐?
  • 平台原因(移植原因):
  • 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
  • 性能原因:
  • 数据结构(尤其是栈)应该尽可能地在⾃然边界上对⻬。原因在于,为了访问未对⻬的内存,处理器需要作两次内存访问;⽽对⻬的内存访问仅需要⼀次访问。假设⼀个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对⻬成8的倍数,那么就可以⽤⼀个内存操作来读或者写值了。否则,我们可能需要执⾏两次内存访问,因为对象可能被分放在两个8字节内存块中。
  • 小结:内存对齐是牺牲时间换空间的一种做法
3.修改默认对齐数

四、位段

1.位段的概念
  • 当我们学习完结构体后,就不得不了解下位段这一概念,何为位段?
  • 结构体的声明与位段的声明是相似的,换而言之,位段的实现是建立在结构体的概念上面的。
  • 位段与结构体有两点不同:
  • 位段的成员类型只能是整型;(如int,unsigned int,signed int,short,char等);
  • 位段的成员变量后面加上冒号与数字;(是位段与结构体最主要的区别),其中数字代表该变量在内存中所占据多少比特位。
  • 注:位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使⽤位段。
  • 下面代码就是位段的声明举例,至于创建变量和初始化,和结构体一样
2.位段的内存分配
  • 位段一次性开辟内存的大小是按照所需要,开辟char、short、int大小的字节。
  • 位段最终的内存大小,是最大对齐数的整数倍。
  • 不同平台上,位段的内存分配不同,也就导致了相同位段,不同平台的内存大小不同;
3.位段的跨平台问题
  • 不同平台上,int是无符号整型,还是有符号整型是不确定的——VS上面int是由符号整型
  • 一次性开辟的内存空间是从左向右使用(从低地址->高地址),还是从右向左使用是不确定的——VS上面内存空间的使用是从右向左的;
  • 剩下的内存空间不够下一个位段成员的填充,是否浪费是不确定的——VS上面是选择浪费的
  • 下面是三个例子:(是我查找各种资源+咨询+寻找典型的例子,才得到的结果)
4.位段的注意事项
  • 由上面三组代码的三个内存布局的研究,我们可以知道,位段成员的起始位置不是某个字节的地址,而是莫个bite位的地址。
  • 我们在指针篇了解到地址是内存单元的编号,也就是一个字节的地址,而一个bite位是没有地址的。
  • 所以位段的成员是没有地址的,也就不能&操作,进行scanf输入。所以我们只能通过临时变量去赋值给位段成员。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在国企做软件测试工程师是一种什么样的体验:每天过的像打仗一样

工作越来越卷&#xff0c;下班越来越晚。每到本该下班的时间&#xff0c;总有一批双目无神的打工人坐在工位上&#xff0c;生无可恋地继续加班...... 如今的职场&#xff0c;加班似乎已成为一种普遍化的现象。有人说&#xff1a;在高薪的背后&#xff0c;都是一群玩命工作的身影…

H3C技术大全复现之高级路由交换技术 1

华子目录 VLAN 基本技术VLANIEEE 802.1Q交换机端口类型MVRP协议实验测试 VLAN扩展技术Super VLAN产生背景Super vlan&#xff08;相当于vlanif接口&#xff0c;也属于虚拟接口&#xff0c;可以充当网关&#xff09;Sub vlan&#xff08;普通vlan&#xff09;关于代理ARP普通代理…

芒果YOLOv8改进:提升篇:从零开始训练 YOLOv8最新稳定8.1版本教程说明,适用Mac、Windows、Linux端

从零开始训练 YOLOv8 - 最新8.1版本教程说明 本文适用Windows/Linux/Mac&#xff1a;从零开始使用Windows/Linux/Mac训练 YOLOv8 算法项目 《芒果 YOLOv8 目标检测算法 改进》 适用于芒果专栏改进 YOLOv8 算法 文章目录 官方 YOLOv8 算法第一步 配置环境1.1 系列配置1.2 代码…

火星文:一种特殊的文字编码

title: 火星文&#xff1a;一种特殊的文字编码 date: 2024/3/25 13:26:20 updated: 2024/3/25 13:26:20 tags: 火星文文字变种网络流行解码阅读社交趣味艺术创新未来符号 定义 火星文是一种特殊的文字编码&#xff0c;也称为奇文&#xff0c;其特点是将常见的文字进行特殊的变…

Linux收到一个网络包是怎么处理的?

目录 摘要 ​编辑 1 从网卡开始 2 硬中断&#xff0c;有点短 2.1 Game Over 3 接力——软中断 3.1 NET_RX_SOFTIRQ 软中断的开始 3.2 数据包到了协议栈 3.3 网络层处理 3.4 传输层处理 4 应用层的处理 5 总结 摘要 一个网络包的接收始于网卡&#xff0c;经层层协议栈…

苍穹外卖项目笔记

软件开发流程 需求分析&#xff1a;说明书和原型 设计&#xff1a;UI&#xff0c;数据库&#xff0c;接口设计 编码&#xff1a;项目代码&#xff0c;单元测试 测试&#xff1a;测试用例&#xff0c;测试报告 上线运维&#xff1a;软件环境安装&#xff0c;配置 软件环境…

ClickHouse03-小白如何快速搭建ClickHouse集群

普通测试通常使用ClickHouse单节点就可以了&#xff0c;但是生产环境不免需要考虑多活、负载等高可用问题&#xff0c;集群就成了基础需求 ClickHouse在集群的选择上&#xff0c;作者已知的有两种&#xff1a; 使用ZooKeeper作为节点协调的组件&#xff0c;使用ClickHouse-Kee…

Java实现JDBC编程

1 数据库编程的必备条件 编程语言&#xff0c;如Java&#xff0c;C、C、Python等 数据库&#xff0c;如Oracle&#xff0c;MySQL&#xff0c;SQL Server等 数据库驱动包&#xff1a;不同的数据库&#xff0c;对应不同的编程语言提供了不同的数据库驱动包&#xff0c;如&#x…

day44 动态规划part6

完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 完全背包和01背包问题唯一不同…

vue3怎么读取本地json数据

在Vue 3中&#xff0c;可以使用fetch API或其他HTTP客户端来读取本地JSON数据。以下是一个使用fetch的示例&#xff1a; <template><div><h1>本地JSON数据</h1><div v-if"data">{{ data }}</div></div> </template>…

MP4如何把视频转MOV格式? MP4视频转MOV格式的技巧

在现代的数字媒体时代&#xff0c;视频格式转换成为了许多用户必须掌握的技能。特别是将MP4视频转换为MOV格式&#xff0c;这对于需要在Apple设备上播放或编辑视频的用户来说尤为重要。本文将详细介绍如何将MP4视频转换为MOV格式&#xff0c;帮助读者轻松应对不同设备和平台的需…

利用云手机高效运营多个海外社媒账户

随着全球化进程的不断推进&#xff0c;中国出海企业和B2B外贸企业日益重视海外社媒营销&#xff0c;将其视为抢占市场份额的关键策略。在海外社媒营销中&#xff0c;企业通常会在多个平台上批量开通账户&#xff0c;搭建自己的社媒内容矩阵。本文将会介绍如何用云手机高效运营多…

平价开放式耳机哪些品牌好用?五款高质量测评入手不后悔 !

现在耳机主要分为入耳式和开放式&#xff0c;而且入耳式耳机对外界声音隔绝太严重&#xff0c;走路的时候听不到脚步声喇叭声音也不利于安全&#xff0c;甚至戴耳机和别人说话沟通也很困难。所以现在的年轻人开始追求舒适、安全、健康的听歌产品&#xff0c;开放式耳机也逐渐成…

牛客网python练习题库记录

python格式化输出 python 读入整数数字并且换行输出 python规范输出小数点后几位 afloat(input()) format_a{.2f}.format(a) print(format_a) 小数化整数 afloat(input()) bint(a) print(b) 为整数增加小数点 input_integer int(input()) float_number float(input…

Spring中的IOC和AOP

Spring两大核心机制&#xff1a;IOC和AOP 一、IOC&#xff1a;控制反转 传统开发中&#xff0c;需要调用对象的时候&#xff0c;需要调用者手动来创建被调用者的实例&#xff0c;即对象是由调用者new出来的&#xff1b; 但在Spring框架中&#xff0c;创建对象的工作不再由调用…

基于springboot+vue的家政服务平台

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

代码随想录阅读笔记-栈与队列【逆波兰表达式求值】

题目 根据 逆波兰表示法&#xff0c;求表达式的值。 有效的运算符包括 , - , * , / 。每个运算对象可以是整数&#xff0c;也可以是另一个逆波兰表达式。 说明&#xff1a; 整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说&#xff0c;表达式总会得出有…

力扣669 修剪二叉搜索树 Java版本

文章目录 题目描述代码 题目描述 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即&#xff0c;如果没有被移除&#xff0…

Linux--动静态库的原理和使用详解

本文介绍了Linux系统中动态库与静态库的概念、原理以及使用方法。通过深入讲解动态库与静态库的区别和优劣势&#xff0c;帮助读者更好地理解并选择合适的库类型来进行软件开发。 动态库和静态库的概念 动态库&#xff08;Dynamic Link Library&#xff0c;简称DLL&#xff09…

加速新能源汽车产品迭代:融合前沿科技的重要性

新能源汽车新质生产力提升咨询方案 一、新能源汽车企业行业目前发展现状及特点&#xff1a; 1、快速增长 2、技术迭代快 3、竞争加剧 二、新能源汽车企业发展新质生产力面临的痛点&#xff1a; 1、技术创新压力巨大 2、市场竞争激烈 3、供应链稳定性欠缺 4、成本控制压…