C语言----联合体

        不知道大家是否听说过联合体这个名词。但其实大家不用觉得联合体有多特殊,大家可以想象结构体是一栋楼,里面有很多房间,住了形形色色的住户(不用或者相同的数据)。但联合体只有一个房间,所有的住户都挤在这个房间里面。但是这个房间的大小是以最大数据类型来决定的。比如说我们创建了一个联合体,里面放置了int类型和char类型。那么这个联合体大小计算int类型的大小了。

联合体声明

        上面我们也说过了,联合体与结构体一样都是多个成员构成的,这些成员可以不同的型。但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。所
以联合体也叫:共⽤体。但是给联合体最大⼀个成员赋值,那么联合体会至少将最大的成员赋值处理,有多余空间在处理其他的成员,这也是与结构体的一个区别。那么大家看一下下面的照片,就知道

       大家看到了吧,联合体是用union+名字。联合体的内容与结构体是一样写的。然后联合体的初始化与结构体也是一样的。但是结构体是给内容分别赋值的。但联合体是定义一个全部都定义的了。 当然在创建联合体的时候可以同时定义。当然我们也可以像结构体一样省略联合体名:

       但是嘞,省略联合体名虽然看起来更加简洁了,但是因为没有了名字,后面就不能用该联合体定义新的变量。然后我们使用typedf将联合体改个名字如:

       使用看了上面的资料大家应该差不多了解了,联合体声明方法了吧。

验证联合体的特点

       大家知道,我在上面写了联合体是将所有的类型装在一个房子里面,并且会保证联合体最大的大小。那么我们看下面的两个代码。首先我们来确定所以类型是住在最大的那个房间里面的(就是类型最大的空间)

         这样大家可以看到打印的地址都是一样的。那么接下来验证这个房间是最大的那个类型:

      这里大家可以看到,我们明明是先个i赋的0x11223344。然后给c赋的0x55.然后我们打印i确实0x11223355。这就是联合体的另外一个特点。最少会保证最大联合体成员,然后有空间再处理其他的。那我们看一个示意图来辅助理解

联合体与结构体内存对比

        当然我们看了联合体内存分布那么我们直接与结构体内存分布对比,这样的话,可以加深我们对两种结构体的内存分布的印象。我们都将两种初始化且赋为0。

        计算联合体的大小

         我们在前面说过联合体与结构体有差异,但也有相同之处。如也可以使用#pragma pack(value) ,来修改对齐数。但当没有定义 #pragma pack(value) 这种指定 value 字节进行对齐时,它的计算规则是:联合体中最大成员所占内存的大小且必须为最大类型所占字节的最小倍数。举例如下:

      首先我们看第一个联合体。我们创建的联合体成员中char a[5]是最大的那么应该首先是5个字节,但是因为int类型是4个字节那么5不是4的倍数,并且5超过4了,那么只有8是复合计算规则的,使用计算的第一个联合体大小是8。

      第二个代码,我们可以看到short数组有7的元素,那么就是14个字节。但是int是4个字节呀。4>2,并且14最接近且大于14的41的倍数,只有16了。那么第二个联合体的大小就是16了。这样普通的联合体大小大家应该就可以计算了吧。

    接下来我我们看一下结构体嵌套联合体的大小是如何计算的。当然结构体嵌套联合体计算大小肯定也是有计算规则的,毕竟无规矩不成方圆嘛。那么嵌套的话规则是什么样的嘞:它的计算规则是,联合体按照最大成员所占字节且为最大数据类型所对应的字节的最小整数倍的原则进行计算,它所占的字节数与结构体中其他成员所占字节的总和应为结构体中最大数据类型所对应的字节的最小倍数。那我们如何理解嘞,我们来看一下下面的代码:

 

       先计算联合体中,最大char a[10]占10字节,但又要为8的最小倍数,因此联合体占16字节。
然后结构体中其余5+4+8=17 字节,不是结构体中最大数据类型 double 所对应的字节数 8的最小倍数,补齐到24字节。所以,综合起来整个结构体大小:16(联合体所占字节)+ 24字节=40字节。

      那当我们定义了对其数的话会稍微改变一点:

        联合体最大占10字节,且为2的最小倍数,因此联合体占10字节,然后10+5+4+8=27字节,但不是 2的最小倍数,因此如需满足上述规则,该结构体的大小应为:10(联合体所占字节) +5+1(空字节)+4+8=28 字节。

联合体使用举例

        大家看到上面后,可能会想,讲这么多,联合体的实际使用方法来个呗,我也好有个心理预期。将来联合体怎么用。那好我们就来个比较简单的联合体使用方法。大家还记得我们前段时间讲过的大小端问题嘛。并且看了上面的知识后我们知道,联合体的存储是优先最大的。那么如果我给最大的赋值1,然后打印最大,那么如果是0这就是大端,如果是1的话那么就是小端了。

      这样大家应该清楚利用联合体来计算我们需要的数据了吧。

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

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

相关文章

lv21 QT对话框3

1 内置对话框 标准对话框样式 内置对话框基类 QColorDialog, QErrorMessage QFileDialog QFontDialog QInputDialog QMessageBox QProgressDialogQDialog Class帮助文档 示例:各按钮激发对话框实现基类提供的各效果 第一步:实现组件布局&…

通过elementUI学习vue

<template><el-radio v-model"radio" label"1">备选项</el-radio><el-radio v-model"radio" label"2">备选项</el-radio> </template><script>export default {data () {return {radio: 1}…

spring boot整合cache使用memcached

之前讲了 spring boot 整合 cache 做 simple redis Ehcache 三种工具的缓存 上文 windows系统下载安装 memcached 我们装了memcached 但spring boot没有将它的整合纳入进来 那么 我们就要自己来处理客户端 java历史上 有过三种客户端 那么 我们用肯定是用最好的 Xmemcached …

mongo之常用数据库操作

目录 一、准备环境 二、日常记录及执行示范 连接数据库查询版本查询表总数模糊查询(使用正则)查询文档中数据条数排序大于等于查询有哪些库时间查询不在条件内的查询复制数据更新字段名称删除数据库 四、高阶查询 五、备份迁移数据库 总结 一、准备环境 借鉴&#xff1a;…

Vue的生命周期函数

今天我们来讲一讲Vue中的生命周期函数 每个Vue实例在其生命周期中都会经历多个关键阶段&#xff0c;这些阶段包括数据监听设置、模板编译、实例DOM挂载以及数据变化时的DOM更新等。同时&#xff0c;Vue提供了一系列生命周期钩子函数&#xff0c;允许开发者在这些重要阶段插入自…

leetcode:135.分发糖果

解题思路&#xff1a;分发糖果时&#xff0c;既要考虑左面&#xff0c;又要考虑右面&#xff0c;如果同时考虑&#xff0c;就会顾此失彼&#xff0c;所以我们可以先考虑右边&#xff0c;再考虑左边&#xff0c;分别正序、逆序进行遍历。逆序遍历时相当于重置candy数组。 运用贪…

Python + Google AI 自动修复 Sonar Bug 实践

前言 在工作中总会遇到种种不期而至的需求&#xff0c;比如前段时间突然要修复所有 Sonar Bug&#xff0c;涉及各种琐碎的代码风格问题&#xff0c;包括但不限于语法不规范、废弃注释等问题。这些项目都已经持续开发几年了&#xff0c;Sonar 上的问题层出不穷&#xff0c;各种…

《汇编语言》- 读书笔记 - 第13章-int 指令

《汇编语言》- 读书笔记 - 第13章-int 指令 13.1 int 指令13.2 编写供应用程序调用的中断例程中断例程&#xff1a;求一 word 型数据的平方主程序中断处理程序执行效果 中断例程&#xff1a;将一个全是字母&#xff0c;以0结尾的字符串&#xff0c;转化为大写主程序中断处理程序…

【Oracle】玩转Oracle数据库(七):RMAN恢复管理器

前言 嘿&#xff0c;数据库大魔法师们&#xff01;准备好迎接新的技术大招了吗&#xff1f;今天我们要探索的是Oracle数据库中的神奇利器——RMAN恢复管理器&#xff01;&#x1f6e1;️&#x1f4be; 在这篇博文【Oracle】玩转Oracle数据库&#xff08;七&#xff09;&#xf…

实验笔记之——Ubuntu20.04配置nvidia以及cuda并测试3DGS与SIBR_viewers

之前博文测试3DGS的时候一直用服务器进行开发&#xff0c;没有用过笔记本&#xff0c;本博文记录下用笔记本ubuntu20.04配置过程&#xff5e; 学习笔记之——3D Gaussian Splatting源码解读_3dgs运行代码-CSDN博客文章浏览阅读3.2k次&#xff0c;点赞34次&#xff0c;收藏62次…

5.WEB渗透测试-前置基础知识-常用的dos命令

内容参考于&#xff1a; 易锦网校会员专享课 上一篇内容&#xff1a;4.WEB渗透测试-前置基础知识-快速搭建渗透环境&#xff08;下&#xff09;-CSDN博客 常用的100个CMD指令 1.gpedit.msc—–组策略 2. sndrec32——-录音机 3. Nslookup——-IP地址侦测器 &#xff0c;是一个…

★【递归】【链表】Leetcode 21. 合并两个有序链表

★【递归】【链表】Leetcode 21. 合并两个有序链表 解法1 &#xff1a;递归链表 简直是好题啊好题多做做 ---------------&#x1f388;&#x1f388;题目链接&#x1f388;&#x1f388;------------------- 解法1 &#xff1a;递归链表 简直是好题啊好题多做做 >>>…