C++Union简析

本文探讨了C++中的Union特性,解释了什么是Union,如何定义、说明和使用它。Union通过让不同数据类型共享同一段内存来节省空间。尽管与Struct有相似之处,但它们在内存分配上存在本质区别。联合变量每次只能赋予一个成员值,其长度等于最长成员的长度。

联合(union)在C/C++里面见得并不多,但是在一些对内存要求特别严格的地方,联合又是频繁出现,那么究竟什么是联合、怎么去用、有什么需要注意的地方呢?就这些问题,我试着做一些简单的回答,里面肯定还有不当的地方,欢迎指出!


1、什么是联合?
“联合”是一种特殊的类,也是一种构造类型的数据结构。在一个“联合”内可以定义多种不同的数据类型, 一个被说明为该“联合”类型的变量中,允许装入该“联合”所定义的任何一种数据,这些数据共享同一段内存,已达到节省空间的目的(还有一个节省空间的类型:位域)。 这是一个非常特殊的地方,也是联合的特征。另外,同struct一样,联合默认访问权限也是公有的,并且,也具有成员函数。


2、联合与结构的区别?

“联合”与“结构”有一些相似之处。但两者有本质上的不同。在结构中各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和(空结构除外,同时不考虑边界调整)。而在“联合”中,各成员共享一段内存空间, 一个联合变量的长度等于各成员中最长的长度。应该说明的是, 这里所谓的共享不是指把多个成员同时装入一个联合变量内, 而是指该联合变量可被赋予任一成员值,但每次只能赋一种值, 赋入新值则冲去旧值。


#include <stdio.h>
void main()
{
	union number
	{ /*定义一个联合*/
		int i;
		struct
		{ /*在联合中定义一个结构*/
			char first;
			char second;
		}half;
	}num;
	num.i=0x4241; /*联合成员赋值*/
	printf("%c%c/n", num.half.first, num.half.second);
	num.half.first='a'; /*联合中结构成员赋值*/
	num.half.second='b';
	printf("%x/n", num.i);
	getchar();
}
输出结果为: 
AB 
6261

从上例结果可以看出: 当给i赋值后, 其低八位也就是first和second的值; 当给first和second赋字符后, 这两个字符的ASCII码也将作为i 的低八位和高八位。

3、如何定义?


例如:

union test
{
	int office;
	char teacher[5];
};
定义了一个名为test的联合类型,它含有两个成员,一个为整型,成员名office;另一个为字符数组,数组名为teacher。联合定义之后,即可进行联合变量说明,被说明为test类型的变量,可以存放整型量office或存放字符数组teacher。


4、如何说明?
联合变量的说明有三种形式:先定义再说明、定义同时说明和直接说明。


以test类型为例,说明如下:

union test
{
	int office;
	char teacher[5];
}; 
union test a,b; /*说明a,b为test类型*/

union test
{
	int office;
	char teacher[5];
} a,b;

<pre name="code" class="cpp">union 
{
	int office;
	char teacher[5];
} a,b;




说明后的a,b变量均为test类型。a,b变量的长度应等于test的成员中最长的长度,即等于teacher数组的长度,共5个字节。a,b变量如赋予整型值时,只使用了4个字节,而赋予字符数组时,可用5个字节。

 

5、如何使用?
对联合变量的赋值,使用都只能是对变量的成员进行。联合变量的成员表示为: 
联合变量名.成员名 
例如,a被说明为test类型的变量之后,可使用a.class、a.office 
不允许只用联合变量名作赋值或其它操作,也不允许对联合变量作初始化赋值,赋值只能在程序中进行。
还要再强调说明的是,一个联合变量,每次只能赋予一个成员值。换句话说,一个联合变量的值就是联合变员的某一个成员值。





常言道:团结就是力量。这里我们定义一个群体是“团结”的,如果这个群体中的任意两个人都是好朋友。并且,我们假定友谊是双向且可传递的,即:若 A 和 B 是朋友、B 和 C 是朋友,则 A 和 C 一定是朋友。下面给定一些人与人之间的关系,你的任务是用最少的努力将他们全部团结起来。 输入格式: 首先在第一行给出两个正整数 n 和 m(均不超过 10 5 ),分别为总人数和人与人之间的关系条数。接下来 m 行,每行描述了两个人之间的关系,格式为: P1 P2 力量值 其中 P1 和 P2 是两个人的编号(所有人从 1 到 n 编号),力量值 是区间 [−10 3 ,10 3 ] 内的一个非零整数,其为正数时,表示 P1 和 P2 是朋友,这个值是他们团结起来的力量;其为负数时,表示 P1 和 P2 还没有成为朋友,这个值的绝对值是团结他们所需要付出的力量。 此外,如果我们想要将 A 和 B 团结起来,但他们之间的关系并没有给出,则假设团结他们需要付出的力量是个常数 10 4 。 输出格式: 根据输入的人际关系,所有人可以被划分为几个朋友群。一个朋友群的“凝聚力”被定义为这个群中所有朋友间最小的力量值。首先必须在一行中按以下格式输出这些朋友群的信息: G1-S1 G2-S2 … 其中 Gi 是朋友群的编号,即该群成员的最小编号;Si 是该群的凝聚力。按凝聚力的非递增序输出。当凝聚力并列时,按群规模(即群成员人数)的非递增序输出。如果还是并列,则按群编号的增序输出。一对数据之间用1个空格分隔,行首尾不得有多余空格。 随后在下一行输出将所有人全部团结起来需要的最小力量值。 输入样例: 10 13 8 3 -5 8 6 3 2 5 2 1 8 -1 3 5 -7 7 9 4 9 4 5 7 3 -3 4 3 -4 6 1 2 8 2 -6 7 4 2 6 3 -2 输出样例: 1-2 4-2 2-2 3-0 10-0 10011 代码长度限制 16 KB Java (javac) 时间限制 800 ms 内存限制 128 MB Python (python3) 时间限制 800 ms 内存限制 64 MB 其他编译器 时间限制 400 ms 内存限制 64 MB 栈限制 8192 KB C++ (clang++) 1 测试用例 无提交记录 提交本题作答 概览 题目列表 提交列表 排名 2025
最新发布
12-03
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值