• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C语言、C++中的union用法总结

C语言、C++中的union用法总结

作者:果冻想 字体:[增加 减小] 来源:互联网 时间:2017-05-28

果冻想 通过本文主要向大家介绍了c语言中union用法,c语言union用法,c语言中union,c语言union,c语言typedef union等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

开始的话

已经好长时间没有更新了,对不起自己,更对不起我亲爱的读者,同时也对不起自己开办的这个博客平台。忙,太忙了,忙于找工作,找一份好工作,纠结于去大城市闯呢,还是回到本省的首府城市。大家都在纠结这个问题,也希望大家和我讨论讨论。别的先不说了,都工作这么长时间了,还回过头来总结union,确实有点过分,要是和大家说我一直从事于C++开发,还不懂union,大家可能还真的不信。我们每天都在总结那些看似高端的东西,什么设计模式(当然我也有总结了)、重构(后期我也会说的了)了,却忽略了那些最基础,最根本的知识点。今天别人问我,我蒙了,所以,就有了这篇文章。

什么是union?

翻译过来说,就是共用体,或者也叫联合体。说到了union,也就是共用体,就不得不说一下struct了,当我们有如下的struct的定义时:
struct student
{
     char mark;
     long num;
     float score;
};
</div>

关于struct的内存结构,将就会像下图所示这样(在x86机器上演示):

sizeof(struct student)的值为12bytes。但是,当我们定义如下的union时,

union test
{
     char mark;
     long num;
     float score;
};
</div>

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);
</div>

这种直接引用是错误的,由于a的存储区有好几种类型,分别占不同长度的存储区,仅写共用体变量名a,这样使编译器无法确定究竟输出的哪一个成员的值。所以,应该写成下面这样:

printf("%d", a.mark);
</div>
同时,在使用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;
}
</div>

所以,在使用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;
}
</div>

可以看到,没有问题;如果我们在再类CA中添加了构造函数,或者添加析构函数,我们就会发现程序就会出现错误。由于union里面的东西共享内存,所以不能定义静态、引用类型的变量。由于在union里也不允许存放带有构造函数、析构函数和复制构造函数等的类的对象,但是可以存放对应的类对象指针。编译器无法保证类的构造函数和析构函数得到正确的调用,由此,就可能出现内存泄漏。所以,我们在C++中使用union时,尽量保持C语言中使用union的风格,尽量不要让union带有对象。

结束的话

我们都在玩那些高大上的东西,猛回头,发现身后却又一个大坑。打开尘封了多年的《C语言程序设计》(谭浩强著),小心翼翼的拭去封面上的尘土,思绪立刻被拉回到大一。那些年,我那清纯的大一。对大学的憧憬,对计算机的好奇,对编程的未知,就是这本书,这本该死的《C语言程序

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C语言、C++中的union用法总结

相关文章

  • 2017-05-28C++实现广度优先搜索实例
  • 2017-05-28C/C++可变参数的使用
  • 2017-05-28基于C++中覆盖,重载,隐藏的一点重要说明
  • 2017-05-28Cocos2d-x UI开发之CCControlColourPicker控件类使用实例
  • 2017-05-28C++虚析构函数的使用分析
  • 2017-05-28c语言实现二叉查找树实例方法
  • 2017-05-28浅析C++中模板的那点事
  • 2017-05-28C++ 中lambda表达式的编译器实现原理
  • 2017-05-28C语言之字符串模糊查询方法的实现
  • 2017-05-28C++循环链表之约瑟夫环的实现方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C++ 双链表的基本操作(详解)
    • C语言基础 原码、反码、补码和移码详解
    • 浅析stl序列容器(map和set)的仿函数排序
    • C++实现:螺旋矩阵的实例代码
    • 深入分析C++中执行多个exe文件方法的批处理代码介绍
    • C++选择排序算法实例
    • VC++实现CStdioFile写入及读取文件并自动换行的方法
    • 详解C++中赋值和输入输出语句的用法
    • C++中的vector容器对象学习笔记
    • 使用OpenGL实现3D立体显示的程序代码

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有