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

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
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zxnsirius

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值