C/C++中的联合体

利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。

当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union)。在C Programming Language 一书中对于联合体是这么描述的:

1)联合体是一个结构;

2)它的所有成员相对于基地址的偏移量都为0;

3)此结构空间要大到足够容纳最"宽"的成员;

4)其对齐方式要适合其中所有的成员;

演示代码如下:

#include<iostream>
using namespace std; union U1
{
int n;
char s[11];
double d;
}; union U2
{
int n;
char s[5];
double d;
}; int main()
{
U1 u1;
U2 u2;
cout<<sizeof(u1)<<'\t'<<sizeof(u2)<<endl;
cout<<"u1各数据地址:\n"<<&u1<<'\t'<<&u1.d<<'\t'<<&u1.s<<'\t'<<&u1.n<<endl;
cout<<"u1各数据地址:\n"<<&u2<<'\t'<<&u2.d<<'\t'<<&u2.s<<'\t'<<&u2.n<<endl;
}

上述代码中:

对于U1联合体,s占11字节,n占4字节,d占8字节,因此其至少需1字节的空间。然而其实际大小并不是11,用运算符sizeof测试其大小为16。这是因为这里存在字节对齐的问题,11既不能被4整除,也不能被8整除。因此补充字节到16,这样就符合所有成员的自身对齐了。从这里可以看出联合体所占的空间不仅取决于最宽成员,还跟所有成员有关系,即其大小必须满足两个条件:1)大小足够容纳最宽的成员;2)大小能被其包含的所有基本数据类型的大小所整除。

对于U2联合体,同理知道,用运算符sizeof测试其大小为8。

具体运行结果如下:



从结果图中还可以发现,联合体中的各数据的存储地址都是相同的。

上面提到了联合体中的数据是共享相同的存储空间。下面再研究具体每种类型数值都存储在哪里?

#include<iostream>
using namespace std; union U
{
unsigned int n;
unsigned char s[4];
}; int main()
{
U u;
u.n = 0xf1f2f3f4;
cout<<hex<<u.n<<'\t'<<&u.n<<endl;
cout<<hex<<(int)u.s[0]<<'\t'<<(void*)&u.s[0]<<endl;
cout<<hex<<(int)u.s[1]<<'\t'<<(void*)&u.s[1]<<endl;
cout<<hex<<(int)u.s[2]<<'\t'<<(void*)&u.s[2]<<endl;
cout<<hex<<(int)u.s[3]<<'\t'<<(void*)&u.s[3]<<endl;
}

上述代码中,联合体U中,n占4字节,s[4]也占4字节。故联合体共占4字节。

程序输出如下:

这说明,内存中数据低位字节存入低地址,高位字节存入高地址,而数据的地址采用它的低地址来表示。

C/C++中的联合体的更多相关文章

  1. 浅谈C语言中的联合体

    联合体union 当多个数据须要共享内存或者多个数据每次仅仅取其一时.能够利用联合体(union).在C Programming Language 一书中对于联合体是这么描写叙述的: 1)联合体是一个 ...

  2. C语言中的联合体union所占内存方式

     当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union).在C Programming Language 一书中对于联合体是这么描述的:      1)联合体是一个结构:    ...

  3. Qt开发中的实用笔记三--关于各种类的零碎知识点:

    1,QUuid()创建唯一标识码,在创建数据库实体ID和链接数据库QSqlDatabase时非常方便 2,QScrollArea与QScrollBar,如果是要在widget中添加窗口滑动QScrol ...

  4. 关于C中struct和union长度的详解

    这几天看<代码大全>中的第十三章---不常见的数据类型,里面讲解到了C语言中的struct以及对指针的解释,联想到以前看过相关的关于C语言中stuct长度的文章,只是现在有些淡忘了,因此今 ...

  5. [php-src]窥探Php内核中的变量

    内容均以php-5.6.14为例. 在看各种组合数据类型之前,有必要先熟悉下 Zend/zend_types.h 里面的自定义数据类型. #ifndef ZEND_TYPES_H // 防止多次 in ...

  6. C语言基础--结构体对齐,位域,联合体

    结构体对齐 1--结构体对齐的原因与意义 许多计算机系统对基本数据类型的可允许地址做出了一些限制,要求某种类型的对象的地址必须是某个值K(通常是2,4,8)的倍数,而这个k则被称为该数据类型的对齐模数 ...

  7. 4. C++11非受限联合体

    在C/C++中,联合体是一种构造类型的数据结构.在一个联合体内,我们可以定义多种不同的数据类型,这些数据类型共享相同的内存空间,可以达到节省内存空间的目的. 1. 取消数据类型的限制 在C++98中, ...

  8. Delphi记录record中的变体

    program Day4; {$APPTYPE CONSOLE} uses SysUtils, Util in 'Util.pas'; type TPerson = packed record ID ...

  9. C语言联合体

    C语言联合体Unions实例代码教程 - 联合是一种特殊的数据类型在C语言中,使您可以存储不同的数据类型相同的内存位置. 联合是一种特殊的数据类型在C语言中,使您可以存储不同的数据类型相同的内存位置. ...

随机推荐

  1. 所有事件event集锦

    'mousedown touchstart', 'mousemove touchmove', 'mouseup mouseleave touchend touchleave touchcancel', ...

  2. Mac下安装包管理平台Homebrew(Mac 10.12)

    在终端上输入: /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/maste ...

  3. python继承的实例

    class SchoolMember(object):#定义学校 member=0#默认成员为0个 amount=0#默认学费为0元 def __init__(self,name,age,sex):# ...

  4. 8、手把手教你Extjs5(八)自定义菜单2

    这一节来定义另外三种类型的菜单类.首先定义菜单按钮类.文件放于app/view/main/region目录下面,文件名为ButtonMainMenu.js. /** * 显示在顶部的按钮菜单,可以切换 ...

  5. Golang测试技术

    本篇文章内容来源于Golang核心开发组成员Andrew Gerrand在Google I/O 2014的一次主题分享“Testing Techniques”,即介绍使用Golang开发 时会使用到的 ...

  6. 编译时.test文件报错无法解决的方法,关闭test编译

    有几次遇到从网上下载到的iOS开源代码编译报错,报错位置为Test Target的源文件,我就挺奇怪我又没做测试为啥会编译Test Target的源文件,之前的暴力解决方法是把Test Target直 ...

  7. 试水mongodb er

    1)data ready var a = {"name":"zhekou","CharDate":"2015-12-01" ...

  8. 步进控件——UIStepper

    步进控件,可用于替换传统用于输入值的文本框.步进控件提供了“+”和“-”两个按钮,用来改变stepper内部value的增加或减少,调用的事件是UIControlEventValueChanged.由 ...

  9. 安卓selector

    定义styles.xml <?xml version="1.0" encoding="utf-8"?> <resources> < ...

  10. sqlite3API函数

    回顾: DDL 表的创建.修改.删除 create table 表名(字段名 字段类型 [约束],...); alter table 表名 {rename to 新名字 | add column 字段 ...