C/C++语言中union联合体存在的意义以及应用实例

C语言中union联合体存在的意义

共用体是什么?

 

如上图所示,共用体正如“共有”关键字所描述的一样,共用体所占的数据空间是共用体中最大的数据类型成员所占用的空间,这些成员并不是随意放置,而是用有相同的首地址。因此,我们在任意时刻只可以按照一个数据类型对共用体进行赋值,共用体中这些成员的关系是“或”,即“不是你死就是我活”。

其实我们可以这样说“共用体其实可以在任意时刻被当作其任意一个数据成员来赋值使用”。共用体的出现基本上实现了我们追求的“万能数据类型”。

共用体与结构体的区别

 

我们看到数据成员在结构体数据内存存储中是顺序排列的,因此结构体完成的是数据成员的“和”操作,相反我们看union联合体则是完成的是数据成员之间的“与“操作。

联合体应用实例

题目要求:我们要用链表来存储老师和学生的成员信息,当老师录入信息时,我们只需要老师的性别;而学生录入信息时,我们只需要学生的学号。

例程实现:

#include <iostream>  
#include <string>  
using namespace std;  
  
union sub_infor  // 可以作为char类型来使用,也可以作为int类型来使用
{  
    char sex;  
    int StudNum;  
};  
  
struct MumberInfor  
{  
    union sub_infor infor;  
    char Kind;  
    struct MumberInfor* M_infor;  
  
    friend istream& operator >> (istream& cin, MumberInfor& Object);  
    friend ostream& operator << (ostream& cout, MumberInfor& Object);  
};  
istream& operator >> (istream& cin, MumberInfor& Object)  
{  
    cout << "请输入成员类别(t:teacher;s:student):";  
    cin >> Object.Kind;  
      
    if (Object.Kind != 't' && Object.Kind != 's')  
    {  
        cout << "输入成员类别非法" << endl;  
        exit(-1); // 看见错误代码为-1就知道输入类别非法  
    }  
  
    if (Object.Kind == 't')  
    {  
        cout << "请输入老师性别(f:女;m:男):";  
        cin >> Object.infor.sex;  
  
        if (Object.infor.sex != 'f' && Object.infor.sex != 'm')  
        {  
            cout << "输入老师性别非法" << endl;  
            exit(-2); // 看见错误代码为-2就知道输入性别非法  
        }  
    }  
    else if (Object.Kind == 's')  
    {  
        cout << "请输入学生学号(整型变量):";  
        cin >> Object.infor.StudNum;  
    }  
    return cin;  
}  
ostream& operator << (ostream& cout, MumberInfor& Object)  
{  
    if (Object.Kind == 't')  
    {     
        cout << "老师的性别为" << (Object.infor.sex == 'f' ? "女" : "男");  
    }  
    else if (Object.Kind == 's')  
    {  
        cout << "学生的学号为" << Object.infor.StudNum;  
    }  
    return cout;  
}  
  
struct MumberInfor* DynamicApplySpace()  
{  
    MumberInfor *head, *current, *tail;  
    int i = 0;  
    head = new MumberInfor;  
    tail = head;  
  
    while (1)  
    {  
        current = new MumberInfor;  
        cin >> *current;  
        tail->M_infor = current;  
        tail = current;  
  
        cout << "是否停止录入(1:YES,0:NO):";  
        cin >> i;  
        if (i)  
        {  
            break;  
        }  
    }  
    tail->M_infor = NULL;  
    return head;  
}  
  
void Print_LinkedList(struct MumberInfor* head)  
{  
    struct MumberInfor* current = head;  
    cout << *head << endl;  
  
    while (current->M_infor != NULL)  
    {  
        current = current->M_infor;  
        cout << *current << endl;         
    }  
}  
  
void FreeHeapMemory(struct MumberInfor* head)  
{  
    struct MumberInfor *current = head, *next;  
  
    while (current->M_infor != NULL)  
    {  
        next = current->M_infor;  
        free(current);  
        current = next;  
    }  
}  
  
int main()  
{  
    struct MumberInfor* head;  
    head = DynamicApplySpace();  // 动态申请内存
    Print_LinkedList(head);  // 输出链表数据
    FreeHeapMemory(head);  // 释放堆区内存
}  

 

代码优化:

我们对代码做如下优化,自动判断输入数据的数据类型,然后指出应该输入的数据类型。

#include <iostream>  
#include <string>  
using namespace std;  
  
union sub_infor  
{  
    char sex;  
    int StudNum;  
};  
  
struct MumberInfor  
{  
    union sub_infor infor;  
    char Kind;  
    struct MumberInfor* M_infor;  
  
    friend istream& operator >> (istream& cin, MumberInfor& Object);  
    friend ostream& operator << (ostream& cout, MumberInfor& Object);  
};  
istream& operator >> (istream& cin, MumberInfor& Object)  
{  
    cout << "请输入成员类别(t:teacher;s:student):";  
    cin >> Object.Kind;  
      
    if (typeid(Object.Kind).name() == "char" && Object.Kind != 't' && Object.Kind != 's')  // 将输入数据类型的判断纳入非法检测当中
    {  
        cout << "输入成员类别非法" << endl;  
        exit(-1); // 看见错误代码为-1就知道输入类别非法  
    }  
  
    if (Object.Kind == 't')  
    {  
        cout << "请输入老师性别(f:女;m:男):";  
        cin >> Object.infor.sex;  
  
        if (typeid(Object.infor.sex).name() == "char" && Object.infor.sex != 'f' && Object.infor.sex != 'm')  // 将输入数据类型的判断纳入非法检测当中
        {  
            cout << "输入老师性别非法" << endl;  
            exit(-2); // 看见错误代码为-2就知道输入性别非法  
        }  
    }  
    else if (Object.Kind == 's')  
    {  
        cout << "请输入学生学号(整型变量):";  
        cin >> Object.infor.StudNum;  
    }  
    return cin;  
}  
ostream& operator << (ostream& cout, MumberInfor& Object)  
{  
    if (Object.Kind == 't')  
    {     
        cout << "老师的性别为" << (Object.infor.sex == 'f' ? "女" : "男");  
    }  
    else if (Object.Kind == 's')  
    {  
        cout << "学生的学号为" << Object.infor.StudNum;  
    }  
    return cout;  
}  
  
struct MumberInfor* DynamicApplySpace()  
{  
    MumberInfor *head, *current, *tail;  
    int i = 0;  
    head = new MumberInfor;  
    tail = head;  
  
    while (1)  
    {  
        current = new MumberInfor;  
        cin >> *current;  
        tail->M_infor = current;  
        tail = current;  
  
        cout << "是否停止录入(1:YES,0:NO):";  
        cin >> i;  
        if (i)  
        {  
            break;  
        }  
    }  
    tail->M_infor = NULL;  
    return head;  
}  
  
void Print_LinkedList(struct MumberInfor* head)  
{  
    struct MumberInfor* current = head;  
    cout << *head << endl;  
  
    while (current->M_infor != NULL)  
    {  
        current = current->M_infor;  
        cout << *current << endl;         
    }  
}  
  
void FreeHeapMemory(struct MumberInfor* head)  
{  
    struct MumberInfor *current = head, *next;  
  
    while (current->M_infor != NULL)  
    {  
        next = current->M_infor;  
        free(current);  
        current = next;  
    }  
}  
  
int main()  
{  
    struct MumberInfor* head;  
    head = DynamicApplySpace();  
    Print_LinkedList(head);  
    FreeHeapMemory(head);  
}  

 

联合体成员的访问方式

// 定义union联合体变量
union sub_infor  // 联合体定义
{  
    char sex;  
    int StudNum;  
};  
// 在使用联合体变量成员数据时,联合体成员访问方法
sub_infor.sex  
sub_infor.StudNum  

 

输入数据的类型检测

int i = 0;  // 定义变量
cin >> i;   // 输入变量
if(typeid(i).name() == "int") // typeid(var_name).name()返回的是字符串类型的常量,即”int”,”float”,”char”,”string”……等数据类型名
{  
    cout << "输入数据类型错误" << endl;  
}  

 

 

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C/C++语言参考(C/C++ Language Reference)是一本非常重要的编程参考手册,它通常以CHM(Compiled HTML Help)格式呈现。CHM是一种微软开发的专用电子帮助文件格式,结合了HTML页面、索引和内容搜索等特性,方便用户查阅。 C/C++语言参考CHM提供了C/C++编程语言的详细描述、语法规则和标准函数库的函数说明等内容。通过这本参考手册,程序员可以深入了解C/C++语言的各种特性和用法,从而更加高效地进行软件开发。 在C/C++语言参考CHM,通常包括以下部分: 1. 语言概述:介绍C/C++语言的起源、特点和发展历程等内容,帮助读者了解和掌握C/C++的基本概念。 2. 语法规则:详细描述了C/C++语言的语法规则,包括关键字、数据类型、运算符、控制语句等基本语法要素,帮助读者正确地编写C/C++程序。 3. 标准函数库:列举了C/C++语言标准函数库的各个函数及其用法,包括字符串操作、数学运算、文件操作等功能,方便程序员直接使用这些函数进行开发。 4. 示例代码:提供了一些常用的示例代码,展示了C/C++语言各种特性的实际应用,方便读者学习和参考。 C/C++语言参考CHM对于学习和使用C/C++编程语言的人来说是一本非常宝贵的工具,它可以帮助程序员快速查找语法和函数相关的信息,提高开发效率。无论是初学者还是有经验的开发者,都可以通过C/C++语言参考CHM来深入理解C/C++编程语言,并利用其强大的功能进行软件开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

肥肥胖胖是太阳

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

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

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

打赏作者

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

抵扣说明:

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

余额充值