C语言——共用体(Union)

本文详细介绍了C语言中共用体(Union)的概念、特点及其应用实例。通过对比结构体,展示了共用体如何避免不同数据类型的重复存储,节省内存空间。并通过一个具体案例,演示了如何使用共用体来高效管理不同类型的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

共用体(Union)

前言:看一个实际需求:

image-20221101190542338

传统方式解决:

//定义结构体,根据人员的职业,使用对应的成员变量
struct Person{
char name[20];
int num;
char sex;
char profession;
float score;	//学生使用score
char course[20];//老师使用course
};

**传统方式的问题分析:**会造成空间的浪费,比如学生只使用score,但是也占用了course成员20个字节

解决方案:

(1)做struct Stu 和 struct Teacher[但是如果职业很多,就会对应多个结构体类型,不利于管理]

(2)这里因此提出了共用体

1.共用体基本介绍

(1)共用体属于构造类型,它可以包含多个类型不同的成员。和结构体类似,但是也有不同的地方

(2)共用体有时也被称为联合或联合体,定义格式为

union 共用体名{
	成员列表
}

(3)结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响,而共用体的的所有成员占用一段内存,修改一个成员会影响其余所有成员

2.快速入门

(1)定义共用体类型和共用体变量的三种方式(和结构体一样)

image-20221101192423029

image-20221101204215288

为什么上述的运行结果和我们想象的不同?

3.说明代码的内存布局:

image-20221101204355162

4.共用体内存布局分析

image-20221101204521715

5.最终实践

image-20221101225832133

分析:

f 和 m 分别表示女性和男性,s 表示学生,t 表示教师。可以看出,学生和教师所包含的数据是不同的(score/course)。现在要求把这些信息放在同一个表格中,并设计程序输入人员信息然后输出。

如果把每个人的信息都看作一个结构体变量的话,那么教师和学生的前 4 个成员变量是一样的,第 5 个成员变量可能是 score 或者 course。当第 4 个成员变量的值是 s 的时候,第 5 个成员变量就是 score;当第 4 个成员变量的值是 t 的时候,第 5 个成员变量就是 course。

代码:

#include <stdio.h>
#include <stdlib.h>
#define TOTAL 2  //人员总数
struct{
    char name[20];
    int num;
    char sex;
    char profession;
    union{
        float score;
        char course[20];
    } sc;
} bodys[TOTAL];
int main(){
    int i;
    //输入人员信息
    for(i=0; i<TOTAL; i++){
        printf("Input info: ");
        scanf("%s %d %c %c", bodys[i].name, &(bodys[i].num), &(bodys[i].sex), &(bodys[i].profession));
        if(bodys[i].profession == 's'){  //如果是学生
            scanf("%f", &bodys[i].sc.score);
        }else{  //如果是老师
            scanf("%s", bodys[i].sc.course);
        }
        fflush(stdin);
    }
    //输出人员信息
    printf("\nName\t\tNum\tSex\tProfession\tScore / Course\n");
    for(i=0; i<TOTAL; i++){
        if(bodys[i].profession == 's'){  //如果是学生
            printf("%s\t%d\t%c\t%c\t\t%f\n", bodys[i].name, bodys[i].num, bodys[i].sex, bodys[i].profession, bodys[i].sc.score);
        }else{  //如果是老师
            printf("%s\t%d\t%c\t%c\t\t%s\n", bodys[i].name, bodys[i].num, bodys[i].sex, bodys[i].profession, bodys[i].sc.course);
        }
    }
    return 0;
}

运行结果:

image-20221101231147853

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值