有时需要使几种不同类型的变量存放到同一段内存单元中。例如,可把一个整型变量、一个字符型变量、一个双精度型变量放在同一个地址开始的内存单元中(见图7.12)。
图7.12
以上3个变量在内存中占的字节数不同,但都从同一地址开始存放。也就是使用覆盖技术,几个变量互相覆盖。这种使几个不同的变量共占同一段内存的结构,称为共用体(union )类型的结构(有些书译为联合)。
声明共用体类型的一般形式为:
union 共用体类型名{成员表列};
定义共用体变量的一般形式为:
共用体类型名 共用体变量名;
当然也可在声明共用体类型的同时定义共用体变量,也可没有共用体类型名而直接定义共用体变量。例如可以看到,“共用体”与“结构体”的定义形式相似。但它们的含义是不同的。结构体变量所占内存长度是各成员占的内存长度之和。每个成员分别占有其自己的内存单元。共用体变量所占的内存长度等于最长的成员的长度。
共用体变量的访问方式
不能引用共用体变量,而只能引用共用体变量中的成员。例如,下面的引用方式是正确的:
a.i (引用共用体变量中的整型成员i)
a.ch (引用共用体变量中的字符型成员ch)
a.f (引用共用体变量中的双精度型成员d)
不能只引用共用体变量,例如
cout<<a;
是错误的,应该写成
cout<<a.i;
或
cout<<a.ch;
等。
共用体类型数据的特点
- 使用共用体变量的目的是希望用同一个内存段存放几种不同类型的数据。但请注意: 在每一瞬时只能存放其中一种,而不是同时存放几种。
- 能够访问的是共用体变量中最后一次被赋值的成员,在对一个新的成员赋值后原有的成员就失去作用。
- 共用体变量的地址和它的各成员的地址都是同一地址。
- 不能对共用体变量名赋值;不能企图引用变量名来得到一个值;不能在定义共用体变量时对它初始化;不能用共用体变量名作为函数参数。
【例7.7】设有若干个人员的数据,其中有学生和教师。学生的数据中包括: 姓名、号码、性别、职业、年级。教师的数据包括: 姓名、号码、性别、职业、职务。可以看出,学生和教师所包含的数据是不同的。
现要求把它们放在同一表格中,如果job项为s(学生),则第5项为grade(年级)。即Li是3年级的。如果job项是t(教师),则第5项为position(职务)。Wang是prof(教授)。显然对第5项可以用共用体来处理(将class和position放在同一段内存中)。要求输入人员的数据,然后再输出。为简化起见,只设两个人(一个学生、一个教师)。
程序如下:
- #include <iostream>
- #include <string>
- #include <iomanip>//因为在输出流中使用了控制符setw
- using namespace std;
- struct
- {
- int num;
- char name[10];
- char sex;
- char job;
- union P //声明共用体类型
- {
- int grade; //年级
- char position[10]; //职务
- }category; //成员category 为共用体变量
- }person[2]; //定义共用体数组person,含两个元素
- int main( )
- {
- int i;
- for(i=0;i<2;i++) //输入两个学生的数据
- {
- cin>>person[i].num>>person[i].name
- >>person[i].sex>>person[i].job;
- if(person[i].job==‘s‘)
- cin>>person[i].category.grade; //若是学生则输入年级
- else
- if (person[i].job==‘t‘)
- cin>>person[i].category.position; //若是教师则输入职务
- }
- cout<<endl<<"No. Name sex job grade/position"<<endl;
- for(i=0;i<2;i++)
- {
- if (person[i].job==‘s‘) cout<<person[i].num<<setw(6)
- <<person[i].name<<" "<<person[i].sex <<" "
- <<person[i].job<<setw(10)<<person[i].category.grade<<endl;
- else cout<<person[i].num<<setw(6)<<person[i].name
- <<" "<<person[i].sex <<" "<<person[i].job
- <<setw(10)<<person[i].category.position<<endl;
- }
- return 0;
- }
运行情况如下:
101 Li fs 3 (注意在输入的字母f和s之间无空格)
102 Wang mt prof (注意在输入的字母m和t之间无空格)
No. Name sex job grade/position 101 Li f s 3 102 Wang m t prof
为了使输出结果上下对齐,在cout语句中用了setw控制符和插入空格。往往需要试验多次。