关于UNION
来源:互联网 发布:页游服务端源码 编辑:程序博客网 时间:2024/06/03 17:14
什么是union?
翻译过来说,就是共用体,或者也叫联合体。说到了union,也就是共用体,就不得不说一下struct了,当我们有如下的struct的定义时:
struct student{ char mark; long num; float score;};
关于struct的内存结构,将就会像下图所示这样(在x86机器上演示):
sizeof(struct student)的值为12bytes。但是,当我们定义如下的union时,
union test{ char mark; long num; float score;};
sizeof(union test)的值为4。这为什么呢?这就是需要说的。 有的时候,我们需要几种不同类型的变量存在在同一段的内存空间中,就像上面的,我们需要将一个char类型的mark、一个long类型的num变量和一个float类型的score变量存放在同一个地址开始的内存单元中。上面的三个变量,char类型和long类型所占的内存字节数是不一样的,但是在union中,它们都是从同一个地址存放的,也就是使用的覆盖技术,这三个变量互相覆盖,而这种使几个不同的变量共占同一段内存的结构,称为“共用体”类型的结构。上面定义的union类型的结构如下:
上面也说了,sizeof(union test)的值为4。那为什么是4呢?大体上来说,结构体struct所占用的内存为各个成员的占用的内存之和(当然也需要考虑内存对齐的问题了)。而对于union来说,在谭浩强的《C语言程序设计》中这么说:union变量所占用的内存长度等于最长的成员的内存长度。很显然,这是不对的,对于union所占用的内存大小,需要考虑内存对齐的问题。这就是为什么sizeof(union test)的值为4啦。
C中使用union
说的再好,再多,终归都是要在使用的,下面就好好的说说C中使用union。和struct一样,union只有先定义了共用体变量才能引用它。而且不能直接引用共用体变量,而只能引用共用体变量中的成员。就像我上面定义的union test。我们不能像下面这样直接引用union:
union test a;printf("%d", a);
这种直接引用是错误的,由于a的存储区有好几种类型,分别占不同长度的存储区,仅写共用体变量名a,这样使编译器无法确定究竟输出的哪一个成员的值。所以,应该写成下面这样:
printf("%d", a.mark);
同时,在使用union的时候,我们还需要注意以下的几点:
1.同一个内存段可以用来存放几种不同类型的成员,但在每一个时刻只能存在其中一种,而不是同时存放几种。也就是说,每一瞬间只有一个成员起作用,其它的成员不起作用,即不是同时都存在和起作用。
2.共用体变量中起作用的成员是最后一个存放的成员,在存入一个新的成员后,原有的成员就失去作用。比如以下的代码:
#include <iostream>using namespace std;union test{ char mark; long num; float score;}a;int main(){ // cout<<a<<endl; // wrong a.mark = 'b'; cout<<a.mark<<endl; // 输出'b' cout<<a.num<<endl; // 98 字符'b'的ACSII值 cout<<a.score<<endl; // 输出错误值 a.num = 10; cout<<a.mark<<endl; // 输出空 cout<<a.num<<endl; // 输出10 cout<<a.score<<endl; // 输出错误值 a.score = 10.0; cout<<a.mark<<endl; // 输出空 cout<<a.num<<endl; // 输出错误值 cout<<a.score<<endl; // 输出10 return 0;}
所以,在使用union的时候,要十二分的小心的。
3.由于union中的所有成员起始地址都是一样的,所以&a.mark、&a.num和&a.score的值都是一样的。
4.不能把union变量作为函数参数,也不能使函数带回union变量,但可以使用指向union变量的指针。
5.union类型可以出现在结构体类型定义中,也可以定义union数组,反之,结构体也可以出现在union类型定义中,数组也可以作为union的成员。
按理说,总结到这里,C语言中的union也就没什么更多的要说了。但是,有一种东西叫做C++,在这个C++中有一种东西叫做类。
当union遇到对象
就单单C中的union,上面的总结已经够用了,但是,现在偏偏又有一个叫做C++的东西;当union遇到了C++中的对象时,一切又变得剪不断,理还乱。上面总结的union使用法则,在C++中依然适用。本来union本就是从C语言中的,如果我们在C++中继续按照C语言的那种方式使用union,那是没有问题的。如果我们在union中放一个类的对象呢?结果会怎么样?比如有以下代码:
#include <iostream>using namespace std;class CA{ int m_a;};union Test{ CA a; double d;};int main(){ return 0;}
可以看到,没有问题;如果我们在再类CA中添加了构造函数,或者添加析构函数,我们就会发现程序就会出现错误。由于union里面的东西共享内存,所以不能定义静态、引用类型的变量。由于在union里也不允许存放带有构造函数、析构函数和复制构造函数等的类的对象,但是可以存放对应的类对象指针。编译器无法保证类的构造函数和析构函数得到正确的调用,由此,就可能出现内存泄漏。所以,我们在C++中使用union时,尽量保持C语言中使用union的风格,尽量不要让union带有对象。
- 关于union
- 关于union
- 关于union
- 关于union
- 关于UNION
- 关于C中的 Union
- 关于oracle的union
- 关于共用体--union
- 关于Union 联合体
- 关于UNION联合体
- 关于C++中的Union
- C语言关于union
- 关于union 和 union all 理解
- SAP HANA关于UNION和UNION ALL
- 关于union的order by
- 关于union all 的优化
- 关于Union和Struct对齐
- 关于Union类型的讨论
- linux内存占用问题调查——slab
- ajax-跨域
- Centos 6.5 安装tomcat6
- angular数据通讯
- 基本数据结构定义
- 关于UNION
- 173. Binary Search Tree Iterator
- 大牛教你如何用 TensorFlow 亲手搭建一套图像识别模块
- String、StringBuffer、StringBuilder、StringTokenizer总结!
- 【PHP】无限分类
- Druid单机的安装和测试
- 汇编--学习笔记(一)-寄存器(二)
- 面向对象及组件开发(一)面向对象简介
- 针对win10系统运行内存不足的解决方案