C++学习之旅-{共用体一游}

来源:互联网 发布:隐藏软件工具 编辑:程序博客网 时间:2024/06/06 12:39

C++学习之旅-{共用体一游}

一开始学C语言的时候(初学),对于共用体的概念和用法都很模糊,因为很少去用也没有细细的研究。之后深入学习才揭开共用体的面纱。(相信很多人也和我有相同的经历)


共用体(union)它是一种数据格式,直白的讲它能够存储不同的数据类型,但是只能同时存储其中的一种类型。

//结构struct online{    int num;    long phone;    double price;};//联合union online{    int num;    long phone;    double price;}

类比结构,我们会发现结构可以同时存储 int、long、double等不同数据类型,但是我们的共用体(联合)只能每次存储其成员中的一个int 或 long 或double。共用体的句法与结构相似但是含义不同。
就比如这个例子:

union online{    int num;    long phone;    double price;    double stm;};

我们可以使用online来存储int num、long phone 或者 double price,条件是我们要在不同的时间进行。

online pail;pail.num = 15;cout << "pail.num = " << pail.num << endl;pail.phone = 123456789;cout << "pail.phone = " << pail.phone << endl;pail.price = 123.345436;cout << "pail.price = " << pail.price << endl;cout << "pail.stm = " << pail.stm << endl;cout << "pail.num = " << pail.num << endl;cout << "pail.phone = " << pail.phone << endl;

在我的机器上运行结果如下:
这里写图片描述

我们可以很清晰的看到,共用体对于不同类型的变量的存储都是可以的,但是每次只能存储一个。及时pail.stm我们没有给它赋值。但是却还是可以打印出和price一样的值。至于pail.num和pail.phone打印出错。是因为double类型的price将共用体的空间占据,然后通过int和long类型的变量对于共用空间进行访问,由于类型的长度等都不同所以访问打印的值也是垃圾值。可以类比price和stm这样同类型的访问。


总结:pail有时可以是int变量,而有时又可以是double变量,成员名称标识了变量的容量。由于共用体每次只能存储一个值,因此它必须有足够的空间来存放最大的成员,所以,共用体的长度取决于其最大成员的长度

#include <iostream>union online{    int num;    long phone;    double price;    double stm;};int main(){    using namespace std;    cout << "union online size = " << sizeof(online) << endl;    return 0;}

打印结果
这里写图片描述
这里的8是8个字节,因为double是这个共用体中最长的数据类型。如果换成结构体这里可能测得的大小就是24(linux、Uinx)22(windows)至于为什么大家应该都知道。嘿嘿


共用体能够用来做什么?举个例子,当数据项需要两种或者更多的格式(但不会同时使用)时,使用共用体可以节省空间。比如,超市里有管理商品的目录,有的商品id是整数,而有的商名ID是字符串。在这种情况下。我们可以这样做

struct widget{    char brand[20];    int type;    union id    {        long id_num;        char id_char[20];    }id_val;};...widget prize;.../* 根据标志位判断使用何种id。此处id共用可节省空间 */if (prize.type == 1)  {    cin >> prize.id_val.id_num;}else{    cin >> prize.id_val.id_char;}

匿名共用体
所谓匿名共用体就是没有名称的共用体。其成员将成为位于相同地址处的变量。显然,每次只有一个成员是当前的成员
同样是上面那个例子

struct widget{    char brand[20];    int type;    //匿名共用体    union      {        long id_num;        char id_char[20];    };};...widget prize;.../* 根据标志位判断使用何种id。此处id共用可节省空间 */if (prize.type == 1)  {    cin >> prize.id_num;}else{    cin >> prize.id_char;}

由于共用体是匿名的,因此id_num和id_char被视为prize的两个成员,它们的地址相同,所以不需要用中间标识符id_val.程序负责确定当前哪个成员是活动的。

1 0