[西门子] C语言中的内存覆盖技术:共同体的概念和操作

[复制链接]
查看112 | 回复0 | 2024-6-28 08:04:08 | 显示全部楼层 |阅读模式
>点击蓝字,关注我们






链表是C语言的魅力:5个你必须知道的链表的类型,格式,用法(二)
从零开始学习C语言的结构体,带你掌握结构体的概念,类型,格式,用法和用途(一)

01
本节重点
C语言共同体
共同体是一种特殊的数据类型,可以实现不同类型的数据共享同一段内存空间。共同体的英文单词是union,有时也被称为联合或联合体。共同体的定义和使用方式与结构体类似,但是它们之间有一个重要的区别:结构体的各个成员占用不同的内存空间,互不影响;而共同体的所有成员占用同一段内存空间,修改一个成员会影响其他成员。



共同体的定义:


为了定义一个共同体,我们需要使用union关键字,格式如下:





union 共同体名 {  成员列表;};

其中,共同体名是可选的,成员列表是由多个变量定义组成,可以是任意类型的数据,如int,float,char,数组,结构体等。例如,我们可以定义一个名为Data的共同体,它有三个成员:一个整数,一个浮点数,和一个字符串。






union Data {    int i;    float f;    char str[20];};为了方便操作,我们可以使用typedef关键字为共同体类型起一个别名,例如:
typedef union DataData;
这样,我们就可以用Data来代替unionData,简化代码的书写。


共同体的创建


为了创建一个共同体变量,我们可以使用共同体名或者别名,例如:



union Data data1; // 使用共同体名Data data2; // 使用别名

我们也可以在定义共同体的同时创建变量,例如:








union Data
{int i;float f;char str[20];} data3; // 创建一个变量data3

如果不再定义新的变量,我们也可以省略共同体名,例如:







union{int i;float f;char str[20];} data4; // 创建一个变量data4共同体的访问


为了访问共同体的成员,我们可以使用成员访问运算符(.),
格式如下:
共同体变量名.成员名


例如,我们可以给data1的各个成员赋值,然后输出它们的值,如下:







data1.i = 10;data1.f = 3.14;strcpy(data1.str, "Hello");printf("%d\n", data1.i);printf("%f\n", data1.f);printf("%s\n", data1.str);但是,这样的输出结果可能会让你感到惊讶,因为它们并不是你所期望的值,而是一些乱码或者错误的值。这是因为共同体的成员共享同一段内存空间,修改一个成员会影响其他成员。为了理解这一点,我们需要了解共同体的内存分布。
共同体的内存分布


共同体占用的内存空间等于最大的成员占用的内存空间。例如,上面的Data共同体中,最大的成员是str,它占用了20个字节,所以Data类型的变量也占用了20个字节的内存空间。我们可以用sizeof运算符来验证这一点,例如:


printf("%d\n", sizeof(data1)); // 输出20

共同体的各个成员在内存中的分布方式取决于机器的存储模式,一般有两种存储模式:大端模式和小端模式。大端模式是指数据的高位字节存储在低地址,低位字节存储在高地址;小端模式是指数据的高位字节存储在高地址,低位字节存储在低地址。大多数PC机采用小端模式,而一些单片机采用大端模式。我们以小端模式为例,来看看Data共同体的内存分布
共同体的各个成员在内存中“对齐”到一头,对str赋值修改的是全部字节,对f赋值修改的是前四个字节,对i赋值修改的是前一个字节。也就是说,i和f会影响到str的一部分数据,而str会影响到i和f的全部数据。这就解释了为什么上面的输出结果会出现乱码或者错误的值。












想要学习C语言的朋友可以自己购买下面推荐的c语言基础从入门到精通,内容包含c语言初始到最终实战,附赠视频教学,让你轻松学习C语言。




点赞加关注,学习不迷路
微信公众号|工控小新
EPLAN电气绘图、TIA博图基础 、CAD、C语言教学、单片机基础、三菱PLC ... 每日持续更新中




发现“分享”“赞”了吗,戳我看看吧


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则