版权声明:本文为博主原创文章,未经博主同意不得用于不论什么商业用途,转载请注明出处。 https://blog.csdn.net/luoweifu/article/details/33342965

你是否记得union这个东西,在上大学的时候我们用的是潭浩强的《C语言程序设计》,里面把它译作是共用体。“共用体”。尽管翻译得特别别扭,但却正好说明了它的特性和用途。

联合union。也有翻译成共用体的是一种特殊的结构(或说类)。

一个union能够有多个数据成员,可是在随意时刻仅仅有一个成员有值。

Union具有下面几个特点:

1.一个union能够有多个不同类型的数据成员。 但在某一时刻仅仅有一个成员有值(即仅仅有一个成员是有效的)

 给union的某个成员赋值后,该union的其他成员就成没有定义的状态了。例如以下演示样例:

// 測试1
union Token
{
char cVal; //char 类型
int nVal; //int类型
double dVal; //double类型
}; void PrintToken(const Token& t)
{
cout << "char: " << t.cVal << endl;
cout << "int: " << t.nVal << endl;
cout << "double: " << t.dVal << endl;
} void TestUnion1()
{
cout << "Print first:"<< endl;
Token t;
t.cVal = 'k';
PrintToken(t); cout << endl << "Print second:"<< endl;
t.nVal = 5;
PrintToken(t);
cout << endl; cout << endl << "Print third:"<< endl;
t.dVal = 10.2;
PrintToken(t);
}

结果例如以下:

2.分配给一个union对象的存储空间,至少要能容纳它的最大的数据成员(即一个union的存储空间至少要为其各个成员的数据类型中占字节数最大的一个成员的字节大小)。

例如以下演示样例:

//測试2
union Token
{
char cVal; //char 类型。 1 个字节
int nVal; //int类型。 4个字节
double dVal; //double类型, 8个字节
}; union Token2
{
short snVal; //2个字节
int nVal; //4个字节
}; union Token3
{
int nVal; //4个字节
float fVal; //4个字节
long lVal; //4个字节
char arr[20]; //20个字节
}; void TestUnion2()
{
cout << "size of Token: " << sizeof(Token) << endl;
cout << "size of Token2:" << sizeof(Token2) << endl;
cout << "size of Token3:" << sizeof(Token3) << endl;
}

结果例如以下:

3.假设一个union结构中有多个同样类型的数据成员,则这些数据成员会有同样的值。

union应该是依据成员占用的内存最大的数据类型的大小分配一段内存空间。无论你使用的是那个成员变量,内存空间地址和大小都同样。当然以上就是依据測试的样例个人进行的判断,在这个样例中char的空间首地址输出有问题,可能跟操作系统有关系。我用的是Ubuntu的Linux操作系统,例如以下演示样例:

//測试3
union Token4
{
unsigned char cVal1;
unsigned char cVal2;
short int snVal;
int nVal;
long lVal;
long long llVal;
double dVal;
double dVal2;
}; void PrintToken4(const Token4& t)
{
cout << "char1: " << t.cVal1 << "\t\t\t" << &t.cVal1 << endl;
cout << "char2: " << t.cVal2 << "\t\t\t" << &t.cVal2 << endl;
cout << "short int:" << t.snVal << "\t\t\t" << &t.snVal << endl;
cout << "int: " << t.nVal << "\t\t" << &t.nVal << endl;
cout << "long: " << t.lVal << "\t\t" << &t.lVal << endl;
cout << "long long:" << t.llVal << "\t" << &t.llVal << endl;
cout << "double1: " << t.dVal << "\t\t" << &t.dVal << endl;
cout << "double2: " << t.dVal2 << "\t\t" << &t.dVal2 << endl;
} void TestUnion4()
{
cout << "Print first:"<< endl;
Token4 t;
t.cVal1 = 'A';
PrintToken4(t); cout << endl << "Print second:"<< endl;
t.nVal = 255;
PrintToken4(t);
cout << endl; cout << endl << "Print third:"<< endl;
t.dVal = 10.2;
PrintToken4(t);
}

结果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHVvd2VpZnU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

4.C++的早期版本号中(C++11标准之前)。union不能含有定义了拷贝构造函数或拷贝控制成员的类类型成员。但在C++11标准之后取消了这一限制。能够含有类的成员,如string及自定义的类。含有拷贝构造函数或拷贝控制成员的类类型成员的union比較复杂,能够去參考C++11标准的相关文档。

从Java到C++——union的使用方法的更多相关文章

  1. java.lang.String.getBytes(String charsetName)方法实例

    java.lang.String.getBytes(String charsetName) 方法编码将此String使用指定的字符集的字节序列,并将结果存储到一个新的字节数组. 声明 以下是java. ...

  2. java解析xml的三种方法

    java解析XML的三种方法 1.SAX事件解析 package com.wzh.sax; import org.xml.sax.Attributes; import org.xml.sax.SAXE ...

  3. Java并发编程基础--基本线程方法详解

    什么是线程 线程是操作系统调度的最小单位,一个进程中可以有多个线程,这些线程可以各自的计数器,栈,局部变量,并且能够访问共享的内存变量.多线程的优势是可以提高响应时间和吞吐量. 使用多线程 一个进程正 ...

  4. [java] 更好的书写equals方法-汇率换算器的实现(4)

    [java] 更好的书写equals方法-汇率换算器的实现(4) // */ // ]]>   [java] 更好的书写equals方法-汇率换算器的实现(4) Table of Content ...

  5. js,java,浮点数运算错误及应对方法

    js,java浮点数运算错误及应对方法 一,浮点数为什么会有运算错误 IEEE 754 标准规定了计算机程序设计环境中的二进制和十进制的浮点数自述的交换.算术格式以及方法. 现有存储介质都是2进制.2 ...

  6. Java小知识--length,length(),size()方法详细介绍

    Java中length,length(),size()区别 length属性:用于获取数组长度. eg: int ar[] = new int{1,2,3} /** * 数组用length属性取得长度 ...

  7. Java 静态变量,常量和方法

    static 关键字 例如:在球类中使用PI这个常量,可能除了本类需要这个常量之外,在另外一个圆类中也需要使用这个常量.这时没有必要 在两个类中同时创建PI这个常量,因为这样系统会将这两个不在同一个类 ...

  8. java内省机制及PropertyUtils使用方法

    背景 一般情况下,在Java中你可以通过get方法轻松获取beans中的属性值.但是,当你事先不知道beans的类型或者将要访问或修改的属性名时,该怎么办?Java语言中提供了一些像java.bean ...

  9. java中String对象的split方法

    在java.lang包中有String.split()方法,返回是一个String[]数组,今天碰到一个自己没注意的问题: 1.特殊分隔符 String str1 = "123|456|78 ...

随机推荐

  1. 平衡树模板【splay的实现】

    [平衡树splay实现] 无注释代码 #include<bits/stdc++.h> using namespace std; typedef long long LL; ,MAXN=1e ...

  2. swoole是如何实现任务定时自动化调度的?

    https://www.muzilong.cn/article/117 开发环境 环境:lnmp下进行试验. 框架:laravel5 问题描述 这几天做银行对帐接口时,踩了一个坑,具体需求大致描述一下 ...

  3. hibernate 映射总结

    单向一对多实体配置:在一的实体中设置多的一方SET集合配置文件:在一的一方用set 设置 one to many表配置:多方表的外键指向一方表的主键; 双向一对多实体配置:在一的实体中设置多的一方SE ...

  4. Hibernate O/R 映射

    O/R 映射 目前为止我们已经通过应用 Hibernate 见识过十分基础的 O/R 映射了,但是还有三个更加重要的有关映射的话题需要我们更详细的探讨.这三个话题是集合的映射,实体类之间的关联映射以及 ...

  5. 基于SpringBoot的开源微信开发平台,Jeewx-Boot 1.0 版本发布

    项目介绍 JeewxBoot 是一款基于SpringBoot的免费微信开发平台.支持微信公众号.小程序官网.微信抽奖活动. Jeewx-Boot实现了微信公众号管理.小程序CMS.微信抽奖活动等基础功 ...

  6. spring boot 监听容器启动

    /** * 在容器启动的时候 加载没问完成的消息重发 * @author zhangyukun * */ @Component @Slf4j public class LoadMessageListe ...

  7. codeforces 1136E-Nastya Hasn't Written a Legend

    传送门:QAQQAQ 题意:有一个数组a和一个数组k,数组a一直保持一个性质:a[i + 1] >= a[i] + k[i].有两种操作:1,给某个元素加上x,但是加上之后要保持数组a的性质.比 ...

  8. 老师的blog整理 .网络编程部分 .网络编程部分 前端部分 django基础部分

    老师的blog整理 .网络编程部分 .网络编程部分 前端部分 django基础部分   老师的blog整理 python基础部分: 宝哥blog: https://www.cnblogs.com/gu ...

  9. 引用不了XXservice,怎么办?

    1.tEdasArchiveLogService = (TEdasArchiveLogService) SpringContextHolder.getBean("TEdasArchiveLo ...

  10. 一次读懂mybatis中的缓存机制

    缓存功能针对于查询(没听说果UPDATE,INSERT语句要缓存什么,都是直接执行的) 默认情况下,mybatis会启用一级缓存. 如果使用同一个session对象调用了相同的SELECT语句,则直接 ...