`
soboer
  • 浏览: 1314169 次
文章分类
社区版块
存档分类
最新评论

C/C++联合(Union)浅谈

 
阅读更多

联合提供了一种方式,能够规避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;

}

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

分享到:
评论

相关推荐

    Dev-cpp5.4.0及API帮助文档 2018年蓝桥杯C语言/c++

    Dev-cpp5.4.0及API帮助文档 2018年蓝桥杯C语言/c++ 需要的同学可以下载使用

    C语言/C++集成开发环境 Dev-C++

    C语言/C++集成开发环境 Dev-C++。一款优秀的C/C++集成开发软件。

    C语言/C++ 烟花表白代码

    C语言/C++ 烟花表白代码 C语言/C++ 烟花表白代码 C语言/C++ 烟花表白代码 C语言/C++ 烟花表白代码

    C语言/C++基础之爱心源码

    C语言/C++基础之爱心源码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    Pro*C/C++ 编程

    Pro*C/C++ 编程 1 一、Pro*C/C++ 简介 1 1.1、Pro*C/C++ 是什么 1 1.2、Pro*C/C++ 处理流程 2 二、Pro*C/C++ GCC 环境配置 3 2.1、Pro*C/C++ 预编译环境 3 2.2、GCC 编译器 5 三、开始编写第一个Pro*C++代码 5 3.1、...

    c/c++中文帮助文档(API)

    c/c++中文帮助文档(API),包含c和c++所有的库函数

    C语言/C++基础之爱心程序源码

    C语言/C++基础之爱心程序源码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    二维码(QRcode)生成算法 C语言/C++源码

    #二维码(QRcode)生成算法 C语言/C++ 源码 1. 根据输入字符串识别编码模式; 2. 根据输入字符串长度选择合适的QRcode版本; 3. 将编码转换为二进制位流表示为数据码字; 4. 使用多项式生成纠错码; 5. 将数据码和...

    c语言/c++/qt图形界面

    c语言/c++/qt图形界面

    C语言/C++基础之冰墩墩源码

    C语言/C++基础之冰墩墩源码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    基于C语言/C++基础的跨年烟花代码

    C语言/C++基础之跨年烟花代码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    C/C++程序设计学习与实验系统 V2008.13.part1

    同时,为了便于C语言学习,加入C语言流程控制语句演示动画、C语言学习指导、可以方便地进行网络上和本机上的C/C++程序进行对照输入练习、入门程序实例、典型源程序、典型的函数算法,课程设计指导、课程设计源程序、...

    C语言/C++基础之跨年烟花代码

    C语言/C++基础之跨年烟花代码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    MATLAB Support for MinGW-w64 C/C++ Compiler.rar

    资源是笔者在MATLAB里面安装的MinGW-w64 C/C++编译器安装包,主要用于作为博文https://blog.csdn.net/jiqiren_dasheng/article/details/103759720的资源附件。(声明:上传时积分设置的1,如果数值后续变了,就是...

    C/C++中文文档(支持C++20和C18)和蓝桥杯C/C++组用的文档

    这个文档压缩包包含普通C/C++中文文档和蓝桥杯比赛时用的文档,C/C++中文文档是最新版,支持到C++20和C18,且包含以前版本的内容。蓝桥杯蓝桥杯C/C++组用的文档比正常文档更简略,但包含了ASCII码表。

    2021年最新 C/C++中文参考手册

    2021年最新 C/C++中文参考手册

    嵌入式C/C++语言开发精华文章集锦(嵌入式C/C++开发者必看,很有价值的文章)

    从两道经典试题谈 C/C++中联合体(union)的使用. 基于 ARM 的嵌入式Linux 移植真实体验 基于 ARM 的嵌入式Linux 移植真实体验(1)――基本概念 基于 ARM 的嵌入式Linux 移植真实体验(2)――BootLoader 基于 ARM...

    C语言/C++基础之圣诞树源码

    C语言/C++基础之圣诞树源码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

    C语言/C++基础之绘制图钉画源码

    C语言/C++基础之绘制图钉画源码,适合初学C语言/C++的小伙伴学习研究,博客中有对应的讲解和演示,避免走弯路,费时费力。也真心希望能够帮助正在苦学C语言/C++ 程序设计的小伙伴们,你们的成长是我最大的幸福

Global site tag (gtag.js) - Google Analytics