C++联合类型

联合类型(又称共同体类型),一种能够表示多种数据(类型可以相同可以不同,变量名字不同就行)的数据类型。

1. 联合类型的定义

union {};

与结构类型类似,只是把struct 换成了 union.

在语义上,联合类型和结构类型的区别是,联合类型的所有成员占用同一块内存空间,该内存的空间大小是其最大成员的内存空间大小。

2. 操作

在程序运行的不同时刻,可以把联合类型的变量当做不同类型的变量来使用。(如果成员有三种类型,就可以当做三种类型来使用。)

联合类型的复制是按占有的整个内存空间中的内容进行复制,而不是按某个成员来赋值。

3. 联合类型除了可以实现用一种类型表示多种类型的数据外,还可以实现多个数据共享内存空间,从而节省了内存空间。所以,当一些大型的数组变量,当它们的使用分布在程序的各个阶段时(不是同时使用),就可以使用联系类型来描述。

————————————————

c++的联合(union)与类的对比

与结构(struct)一样,c++的联合申明定义了一种特殊类型的类。这意味着保持了封装的原则。

使用c++联合时,必须遵守几个限制条件:

第一、联合不能继承任何其他类型的类。

第二、联合不能是基类,不能含有虚成员函数。静态变量不能是联合的成员;不能使用引用成员。联合不能有任何作为成员的重载“=”运算符的对象。

最后、如果一个对象有明确的构造函数或析构函数,那么他就不能成为联合的成员。

————————————————

联合提供了一种方式,能够规避C的类型系统,允许以多种类型来引用一个对象。联合声明的语法和结构体的语法一样,只不过语义相差很大。它们不是用不同的域来引用不同的存储器块,而是引用同一块存储块。

下面我们来举几个例子:

struct STest

{

char c;

int i[ 2 ];

double var;

};

union UTest

{

char c;

int i[ 2 ];

double var;

};

我们可以查看内存里面的分布:

类型 c i var 大小

STest 0 4 12 20

UTest 0 0 0 8

上面的数据表示距离首地址的存储器块偏移。假如我们定义了UTest* pU; 我们分别察看p->c; p->i[ 0 ]; p->var; 它们所引用的都是数据结构的起始位置。当然求sizeof的话。UTest的大小将是它的最大类型的数据成员的大小。

联合的用处很多,这里举一个怎么用它来节省空间:

假设我们有一个二叉树的数据结构,每个叶子节点都有一个double的数据值,而每个内部节点都有指向孩子节点的指针,但是没有数据(因为是叶子节点)。如果我们像这样声明:

struct NODE

{

struct NODE* pLeft;

struct NODE* pRight;

double data;

};

我们可以知道这样一个结构体需要16个字节,每个叶子节点都会浪费一半的字节。相反,如果我们用联合来声明一个节点:

union NODE

{

struct

{

union NODE* pLeft;

union NODE* pRight;

}inter;

double data;

};

这样一来,每个节点就只需要8个字节。如果pNode是一个指向union NODE类型的指针,我们用pNode->data来引用叶子节点的数据。而pNode->inter.pLeft和pNode->inter.pRight来引用内部节点的孩子。

这样可能出现一种情况,就是无法确定是哪种节点(内部节点或叶子节点)。我们可以引用一个标志域。

struct NODE

{

BOOL isLeaf;

union

{

struct

{

union NODE* pLeft;

union NODE* pRight;

}inter;

double data;

}info;

}

不过对于这样小的节省而导致代码的可读性变得差了一些。在这里联合带来的好处可以忽略。对于较多域的数据结构,这样的节省会更加吸引人一些。

还有一个用法就是用来访问不同数据类型的位。如:

UINT floatToBits( float fVar )

{

union

{

float fV;

UINT uI;

}temp;

temp.fV = fVar;

return temp.uI;

}

我们看看汇编代码:

mov eax,dword ptr [ fVar ]

mov dword ptr [ temp ],eax

它跟下面的函数产生回汇编代码是一样的:

UINT floatToBits( UINT var )

{

return var;

}

这就证明汇编代码里面缺乏信息,无论是什么类型都相对于EBP偏移固定的值。过程只是简单的拷贝,并没有修改任何位。

再举个例子吧:

double bitToDouble( UINT uParam1, UINT uParam2 )

{

union

{

double d;

UINT u[ 2 ];

}temp;

temp.u[ 0 ] = uParam1;

temp.u[ 1 ] = uParam2;

return temp.d;

}

好了,更多的用法大家在慢慢体会吧,这里就抛砖引玉了- -

————————————————

通过分享实用的计算机编程语言干货,推动中国编程到2025年基本实现普及化,使编程变得全民皆知,最终实现中国编程之崛起,这里是中国编程2025,感谢大家的支持。

原文链接:https://blog.csdn.net/haitaolang/article/details/70156438

原文链接:https://blog.csdn.net/masefee/article/details/4160211

struct类型重定义 不同的基类型_C++学习大纲:联合类型相关推荐

  1. struct类型重定义 不同的基类型_汇总贴:STEP7的复杂数据类型有哪些?

    复杂数据类型是由基本数据类型通过一定的规则,有机结合在一起,形成的新的.复杂数据类型,STEP7中定义了以下几种复合数据类型: 一.数组ARRAY ARRAY表示由一个相同数据类型的数据组合在一起,形 ...

  2. struct类型重定义 不同的基类型_C++构造数据类型

    结构体(struct) 定义: 结构体是一个数据类型,是由多个不同类型的数据组成的数据集合.关键字为:struct . 优点: 大大减少程序代码的离散性,使程序代码阅读更加符合逻辑. 语法: stru ...

  3. error C2011: “Font”:“struct”类型重定义

    error C2011: "Font":"struct"类型重定义 在VS2008里添加在VC6.0里形成的OFFICE库文件的类 excel.h.excel. ...

  4. VS2010 error C299: “Font”:“struct”类型重定义

    在VS2010里添加了在VC6.0里形成的OFFICE库文件的类 excel9.h,excel9.cpp,就是我在VC6里做操作OFFICE的表格时候添加的库文件,然后把它们( excel9.h,ex ...

  5. 类型重定义 头文件预编译设置

    这是一个比较常用的C/C++杂注,只要在头文件的最开始加入这条杂注,就能够保证头文件只被编译一次.在编写头文件的时候,如果没有加上这一句,编译器可能会编译多次这个头文件.VS编译器会报出这个头文件 里 ...

  6. sockaddr类型重定义

    这时说的sockaddr类型重定义错误, 实际上包括一大堆: sockaddr, ;sockaddr_in等等. 这是由于windows.h和winsock2.h包含的顺序而造成的错误: 正确的顺序是 ...

  7. error C2011: “XXX”:“class”类型重定义

    以前在学习C的时候,老师总是说,为了防止头文件被多次重复调用,一定要添加保护,一直以来编写的文件不多,没有进行复杂的多次调用,也没有出错,久而久之,竟忘了.前些天在做项目时,没有主意这个问题,结果嘛, ...

  8. 嵌入式软件开发培训笔记——C高级 预处理类型重定义

    (1)#include (2)#define (3)#if,#else,#elif,#endif 理解c语言中if,else,elseif,但不要忘记在条件编译时要加上endif (4)#ifdef, ...

  9. linux sysinfo结构体,编译BusyBox出现错误: struct sysinfo 重定义 该如何解决?

    Busybox 1.13.3和其他的1.16版本都是如此     arm-linux-gcc  version=4.3.3 ====================================== ...

最新文章

  1. clojurescript_为什么ClojureScript在NPM上如此出色
  2. 互联网协议 — 使用 Wireshark 调试 HTTPS 及 HTTP/2 流量
  3. 对软连接进行cp,rm
  4. 程序员的10个快乐瞬间!
  5. 2020牛客国庆集训派对day3 Points
  6. jmeter利用influxdb和grafana实现数据可视化
  7. epoll在ET和LT模式下读写
  8. mac 10.13 配置 php,MacOS10.13.6 升级后 PHP7.3配置
  9. 数据操作语言DML及数据定义语言DDL的区别
  10. 演示Eclipse插件实现代码提示和补全
  11. RHEL6.4下一键安装 Redmine
  12. SQL2005下载版本之区别
  13. 集线器、交换机、路由器、网桥、网关之间的区别
  14. HOW2J.CN - 学习笔记(类和对象)
  15. 方舟生存显示都是外国服务器,方舟生存进化:在新服的国人,都是如何跟外国人交流的?...
  16. GB28181设备接入实现web无插件多屏直播
  17. 如画的水乡,如画的同里58
  18. 韩国通关号免费查询系统,韩国清关码校验
  19. 疫情防控之外来人员登记表模板
  20. 基于安卓AndroidStudio在线订餐app设计

热门文章

  1. 计算机实验报告14,计算机14实验报告模板.doc
  2. dispay的flex属性
  3. 蔬菜大棚原理_天津大棚报价大棚的造价、温室大棚
  4. react dispatch_梳理下redux、mobx 在react的应用
  5. wireshark linux远程,如何在SSH连接Linux的环境下使用wireshark抓包云边端架构?
  6. 计算机网络实验报告3-tcp,计算机网络实验报告3-TCP.doc
  7. 计算机网络是一个 系统,计算机网络是一个什么系统
  8. 如何安装html网站模板,网站模板安装说明
  9. Java编码规范注意
  10. 文件存储demo,直接存储内容到本地中。