摘要:本文主要介绍了C语言和C语言中联合用法的概述。本文解释了什么是联合,如何在C语言中使用联合,以及联合何时遇到对象等。有需要的朋友可以参考一下。
开始的话
好久没更新了。我对不起自己,更对不起亲爱的读者,对不起自己创办的博客平台。忙,太忙了,忙着找工作,找好工作,挣扎着去大城市,或者回本省省会城市。大家都在纠结这个问题,希望大家和我一起探讨。别的就不说了。工作了这么长时间,回去总结union有点过了。如果我告诉你我一直从事C开发,还不知道union,你可能不信。我们每天都在总结那些看似高端的东西,什么设计模式(当然我已经总结过了)、重构(后面会讲到),却忽略了最基础最根本的知识点。今天人家问我,我就蒙了,于是,就有了这篇文章。
什么是union?
翻译过来,就是一个共同体,或者说是一个联合体。说到union,也就是common body,就不得不说struct了。当我们对struct有如下定义时:
复制代码如下:
结构学生
{
字符标记;
长num
浮动分数;
};
struct的内存结构如下图所示(在x86机器上演示):
sizeof(struct student)的值是12字节。然而,当我们如下定义联合时,
复制代码如下:
联合测验
{
字符标记;
长num
浮动分数;
};
sizeof(联合测试)的值为4。这是为什么呢?这就是需要说的。有时,我们需要几个不同类型的变量存在于同一个内存空间中。就像上面一样,我们需要在内存单元中从同一个地址开始存储一个char类型的mark、一个long类型的num变量和一个float类型的score变量。以上三个变量,char类型和long类型,内存字节不同,但在union中,都是从同一个地址存储的,也就是使用的overlay技术。这三个变量相互叠加,这种使几个不同的变量共享同一个内存的结构称为“共生体”型结构。上面定义的联合类型的结构如下:
如上所述,sizeof(联合测试)的值是4。为什么是4?一般来说,结构struct占用的内存是每个成员占用内存的总和(当然也要考虑内存对齐)。对于union,谭浩强的《C语言程序设计》中说明了union变量占用的内存长度等于最长成员的内存长度。显然,这是不对的。对于union占用的内存大小,要考虑内存对齐。这就是为什么sizeof(联合测试)的值是4。
C中使用union
再好的话,再多的话,总会被用到。这里很好的讲一下在c中使用union,和struct一样,union只有先定义了才能引用一个公共变量。而且不能直接引用共享变量,只能引用共享变量中的成员。就像我上面定义的联合测试一样。我们不能直接引用union如下:
复制代码如下:
联合测试a;
printf('%d ',a);
这种直接引用是错误的,因为A的存储区域有几种类型,分别占用不同长度的存储区域,只写公共变量名A,编译器无法确定输出的是哪个成员的值。因此,应该这样写:
复制代码如下:
printf('%d ',a . mark);
同时,在使用union时,我们还需要注意以下几点:
1.同一个内存段可以用来存储几种不同类型的成员,但是每时每刻只能存在一种,而不是同时存储几种。也就是说,某个时刻只有一个成员在工作,而其他成员没有,也就是说,他们并不都同时存在和工作。
2.在公共变量中工作的成员是最后被存放的成员。新成员存入后,原成员失去功能。例如,下面的代码:
复制代码如下:
#包括iostream
使用命名空间std
联合测验
{
字符标记;
长num
浮动分数;
} a;
int main()
{
//coutaendl;//错误
a.mark=' b
couta.markendl//输出“b”
couta.numendl//98字符“b”的ACSII值
couta.scoreendl//输出错误值
a.num=10
couta.markendl//输出为空
couta.numendl//输出10
couta.scoreendl//输出错误值
a.score=10.0
couta.markendl//输出为空
couta.numendl//输出错误值
couta.scoreendl//输出10
返回0;
}
因此,使用union时要极其小心。
3.因为union中的所有成员都有相同的起始地址,所以a.mark、a.num和a.score的值都相同。
4.不能将联合变量作为函数参数,也不能将函数带回联合变量,但可以使用指向联合变量的指针。
5 .联合类型可以出现在结构类型定义中,也可以定义联合数组。相反,结构也可以出现在union类型定义中,数组也可以是union的成员。
可以说,总结到这里,关于C语言中的union就没什么好说的了。但是,有一个东西叫C,在这个C里面有一个东西叫类。
当union遇到对象
只是C中的union,上面的总结就够了,但是现在还有一个东西叫C;当union遇到C中的对象,一切又变得切割无序。上面总结的联合使用规则在C #中仍然适用.Union最初来自C语言。如果继续像C语言一样在C语言中使用union,就不会有问题。如果我们把一个类的对象放在union中会怎么样?会发生什么?例如,有以下代码:
复制代码如下:
#包括iostream
使用命名空间std
CA级
{
int m _ a;
};
联合测验
{
CA a;
双d;
};
int main()
{
返回0;
}
如你所见,没有问题;如果我们给重分类CA添加一个构造函数或者析构函数,我们会发现程序会有错误。因为union中的东西共享内存,所以不可能定义静态的引用类型的变量。因为带有构造函数、析构函数和复制构造函数的对象不允许存储在union中,所以可以存储相应的类对象指针。编译器不能保证正确调用类的构造函数和析构函数,所以可能会出现内存泄漏。所以我们在C中使用union的时候,尽量保持C语言使用union的风格,尽量不让union有对象。
结束的话
我们都在玩那些高大上的东西,一转身就发现身后又是一个大洞。打开尘封多年的《C语言程序设计》(作者谭浩强),小心翼翼地擦掉封面上的灰尘,思绪立刻被拉回到大一的时候。那些年,我清纯的大一。我对大学的向往,对计算机的好奇,对编程的无知,就是这本书,这该死的《C语言程序设计》,把我带到了“成”号上。说多了都是泪。当你看了我的文章,你就应该理解我了。CodeMonkey~~~,这条不归路,且行且珍惜。
===修改日志===
2014年9月11日,文章《不能把联合变量作为函数参数,或者把函数带回联合变量,但是可以用指向联合变量的指针》。非常感谢Cassie_Lcy对这个描述的修正,还在评论里附上了验证码。非常感谢;同时,我非常抱歉。我总结了这个未经验证的知识,给大家造成了一些误导,抱歉。我们必须注意学习的严谨性。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。