C++共用体的介绍

有时需要使几种不同类型的变量存放到同一段内存单元中。例如,可把一个整型变量、一个字符型变量、一个双精度型变量放在同一个地址开始的内存单元中(见图7.12)。

技术分享
图7.12

以上3个变量在内存中占的字节数不同,但都从同一地址开始存放。也就是使用覆盖技术,几个变量互相覆盖。这种使几个不同的变量共占同一段内存的结构,称为共用体(union )类型的结构(有些书译为联合)。

声明共用体类型的一般形式为:
    union 共用体类型名{成员表列};

定义共用体变量的一般形式为:
    共用体类型名 共用体变量名;

当然也可在声明共用体类型的同时定义共用体变量,也可没有共用体类型名而直接定义共用体变量。例如可以看到,“共用体”与“结构体”的定义形式相似。但它们的含义是不同的。结构体变量所占内存长度是各成员占的内存长度之和。每个成员分别占有其自己的内存单元。共用体变量所占的内存长度等于最长的成员的长度。

共用体变量的访问方式

不能引用共用体变量,而只能引用共用体变量中的成员。例如,下面的引用方式是正确的:
    a.i  (引用共用体变量中的整型成员i)
    a.ch  (引用共用体变量中的字符型成员ch)
    a.f  (引用共用体变量中的双精度型成员d)

不能只引用共用体变量,例如
    cout<<a;
是错误的,应该写成
    cout<<a.i;

    cout<<a.ch;
等。

共用体类型数据的特点

  1. 使用共用体变量的目的是希望用同一个内存段存放几种不同类型的数据。但请注意: 在每一瞬时只能存放其中一种,而不是同时存放几种。
  2. 能够访问的是共用体变量中最后一次被赋值的成员,在对一个新的成员赋值后原有的成员就失去作用。
  3. 共用体变量的地址和它的各成员的地址都是同一地址。
  4. 不能对共用体变量名赋值;不能企图引用变量名来得到一个值;不能在定义共用体变量时对它初始化;不能用共用体变量名作为函数参数。

【例7.7】设有若干个人员的数据,其中有学生和教师。学生的数据中包括: 姓名、号码、性别、职业、年级。教师的数据包括: 姓名、号码、性别、职业、职务。可以看出,学生和教师所包含的数据是不同的。

现要求把它们放在同一表格中,如果job项为s(学生),则第5项为grade(年级)。即Li是3年级的。如果job项是t(教师),则第5项为position(职务)。Wang是prof(教授)。显然对第5项可以用共用体来处理(将class和position放在同一段内存中)。要求输入人员的数据,然后再输出。为简化起见,只设两个人(一个学生、一个教师)。

程序如下:
  1. #include <iostream>
  2. #include <string>
  3. #include <iomanip>//因为在输出流中使用了控制符setw
  4. using namespace std;
  5. struct
  6. {
  7. int num;
  8. char name[10];
  9. char sex;
  10. char job;
  11. union P //声明共用体类型
  12. {
  13. int grade; //年级
  14. char position[10]; //职务
  15. }category; //成员category 为共用体变量
  16. }person[2]; //定义共用体数组person,含两个元素
  17. int main( )
  18. {
  19. int i;
  20. for(i=0;i<2;i++) //输入两个学生的数据
  21. {
  22. cin>>person[i].num>>person[i].name
  23. >>person[i].sex>>person[i].job;
  24. if(person[i].job==‘s‘)
  25. cin>>person[i].category.grade; //若是学生则输入年级
  26. else
  27. if (person[i].job==‘t‘)
  28. cin>>person[i].category.position; //若是教师则输入职务
  29. }
  30. cout<<endl<<"No. Name sex job grade/position"<<endl;
  31. for(i=0;i<2;i++)
  32. {
  33. if (person[i].job==‘s‘) cout<<person[i].num<<setw(6)
  34. <<person[i].name<<" "<<person[i].sex <<" "
  35. <<person[i].job<<setw(10)<<person[i].category.grade<<endl;
  36. else cout<<person[i].num<<setw(6)<<person[i].name
  37. <<" "<<person[i].sex <<" "<<person[i].job
  38. <<setw(10)<<person[i].category.position<<endl;
  39. }
  40. return 0;
  41. }
运行情况如下:
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控制符和插入空格。往往需要试验多次。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。