10.1、共用体
共用体是一种数据格式,它能够存储不同的数据类型,但只能同时存储其中的一种类型。比如说:结构可以同时存储int、long、和double,而共用体只能存储int、long、或double。共用体的句式与结构相似,但含义不同。例如:
union one4all
{int int_val;long long_val;double double_val;
};
可以使用one4all变量存储int、long或double,条件是在不同的时间进行:
one4all pail;
pail.int_val=15;
cout<<pail.int _val;
pail.double_val=1.89;
cout<<pail.double_val;
pail有时可以是int变量,有时也可以是double变量。成员名称标识了变量的容量。由于共用体内次只能存储一个值,因此它必须有足够的空间来存储最大的成员,所以共用体的长度为其最大成员的长度。
共用体的用途之一是,当数据项使用两种或更多种格式(但不会同时使用时),可节省空间。如:
sturct widget
{char brand[20];int type;union id{long id_num;char id_char[20];}id_val;
};
…
widget prize;
…
if (prize.type == 1)
cin >> prize.id_val.id_num;
else
cin >> prize.id_val.id_char;
匿名共用体没有名称,其成员将成为位于相同地址处的变量。
sturct widget
{char brand[20];int type;union id{long id_num;char id_char[20];};
};
…
widget prize;
…
if (prize.type == 1)
cin >> prize.id_num;
else
cin >> prize.id_char;
由于共用体是匿名的,因此id_num和id_char被视为prize的两个成员,它们的地址相同,所以不需要中间标识符id_val。
共用体常用于节省空间,对于某些应用程序来说内存非常宝贵,共用体能发挥很好的作用。
10.2、枚举
C++的enum工具提供了另一种创建符号常量的方式,这种方式可以用来代替const。它还允许定义新类型,但必须按严格的限制进行。使用enum的句法与使用结构相似。如:
enum spectrum{red,orange,yellow,green,blue,violet,indigo,ultraviolet};
这条语句完成两项任务:
(1)让spectrum成为新类型的名称:spectrum被称为枚举,就像struct变量被称为结构一样。
(2)将red、orange、yellow等作为符号常量,它们对应整数值0~7。这种常量叫作枚举量。
在默认情况下,将整数值赋给枚举量,第一个枚举量是0,第二个枚举量是1,以此类推。
可以用枚举名来声明这些类型的变量:
spectrum band;
枚举变量有以下特殊性质:
(1)在不进行强制类型转化的情况下,只能将定义枚举时使用的枚举量赋给这种枚举的变量,
如:可以band=blue;而不能band=2000;。因此spectrum变量受到限制,只有8个可能的值,编译器会将非enum的值赋给enum变量视为错误。
(2)对于枚举,只定义了赋值运算符。例如上面给band赋值,但是加减法之类的运算不能进行。
(3)枚举量是整型,可以被提升为int类型,但int类型不能自动转换为枚举类型:
你可以int color=blue;以及color=3+red;。表达式的3+red中的加法并非为枚举量定义,但red被转换位int类型,因此结果的;类型也是int。
10.2.1、设置枚举量的值
可以使用赋值运算符来显示地设置枚举量的值:
enum bits{onr=1,two=2,four=4,eight=8};
指定的值必须是整数,也可以显示地定义其中一些枚举量的值:
enum bigstep={first,second=100,third};
这里first默认设置为0,后面没有初始化的枚举量的值将比前面的枚举量大1,因此third的值为101。
你也可以创建多个相同值的枚举量:
enum {zero,null=0,one,numero_uno=1};
其中zero和null都为0,noe和numero_uno都为1.
10.2.2、枚举的取值范围
C++现在通过强制类型转换,增加了可赋给枚举变量的合法值。每个枚举都有取值范围,通过强制转换,可以将取值范围中的任何整数值赋给枚举变量,即使这个值不是枚举值。例如:
enum bits{one=1,two=2,four=4,eight=8};
bits myflag;
下面的代码将是合法的:
myflag=bits(6);
6不是枚举值,但是它位于枚举定义的取值范围内。
取值范围的定义:需要知道枚举量的最大值,找到大于这个最大值的、最小值的2的幂,将它减去1,得到的就是取值范围的上限。比如前面的101值,在2的幂里比这个数大的最小值是128,所以上限为127。关于下限,最小值大于0则为0,否则方法与上限一致。