C语言共用体(C语言union用法)详解

article/2025/10/7 16:36:02

转载重点:共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。图形分析影响过程

 

通过前面的讲解,我们知道结构体(Struct)是一种构造类型或复杂类型,它可以包含多个类型不同的成员。在C语言中,还有另外一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为:

union 共用体名{成员列表
};
共用体有时也被称为联合或者联合体,这也是 Union 这个单词的本意。

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

结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。

共用体也是一种自定义类型,可以通过它来创建变量,例如:

union data{
int n;
char ch;
double f;
};
union data a, b, c;

上面是先定义共用体,再创建变量,也可以在定义共用体的同时创建变量:

union data{
int n;
char ch;
double f;
} a, b, c;

如果不再定义新的变量,也可以将共用体的名字省略:

union{
int n;
char ch;
double f;
} a, b, c;

共用体 data 中,成员 f 占用的内存最多,为 8 个字节,所以 data 类型的变量(也就是 a、b、c)也占用 8 个字节的内存,请看下面的演示:

#include <stdio.h>union data{
int n;
char ch;
short m;
};int main(){
union data a;
printf("%d, %d\n", sizeof(a), sizeof(union data) );
a.n = 0x40;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.ch = '9';
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.m = 0x2059;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.n = 0x3E25AD54;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);return 0;
}

运行结果:

4, 4
40, @, 40
39, 9, 39
2059, Y, 2059
3E25AD54, T, AD54

这段代码不但验证了共用体的长度,还说明共用体成员之间会相互影响,修改一个成员的值会影响其他成员。

要想理解上面的输出结果,弄清成员之间究竟是如何相互影响的,就得了解各个成员在内存中的分布。以上面的 data 为例,各个成员在内存中的分布如下:

成员 n、ch、m 在内存中“对齐”到一头,对 ch 赋值修改的是前一个字节,对 m 赋值修改的是前两个字节,对 n 赋值修改的是全部字节。也就是说,ch、m 会影响到 n 的一部分数据,而 n 会影响到 ch、m 的全部数据。

上图是在绝大多数 PC 机上的内存分布情况,如果是 51 单片机,情况就会有所不同:

为什么不同的机器会有不同的分布情况呢?这跟机器的存储模式有关,我们将在VIP教程《大端小端以及判别方式》一节中展开探讨。

共用体的应用

共用体在一般的编程中应用较少,在单片机中应用较多。对于 PC 机,经常使用到的一个实例是: 现有一张关于学生信息和教师信息的表格。学生信息包括姓名、编号、性别、职业、分数,教师的信息包括姓名、编号、性别、职业、教学科目。请看下面的表格:

Name

Num

Sex

Profession

Score / Course

HanXiaoXiao

501

f

s

89.5

YanWeiMin

1011

m

t

math

LiuZhenTao

109

f

t

English

ZhaoFeiYan

982

m

s

95.0


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

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

经过上面的分析,我们可以设计一个包含共用体的结构体,请看下面的代码:

#include <stdio.h>
#include <stdlib.h>#define TOTAL 4 //人员总数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;}

运行结果:

Input info: HanXiaoXiao 501 f s 89.5↙
Input info: YanWeiMin 1011 m t math↙
Input info: LiuZhenTao 109 f t English↙
Input info: ZhaoFeiYan 982 m s 95.0↙Name            Num     Sex     Profession      Score / Course
HanXiaoXiao     501     f       s               89.500000
YanWeiMin       1011    m       t               math
LiuZhenTao      109     f       t               English
ZhaoFeiYan      982     m       s               95.000000

 


http://chatgpt.dhexx.cn/article/H5Vixshr.shtml

相关文章

C语言 union用法

我们知道结构体&#xff08;Struct&#xff09;是一种构造类型或复杂类型&#xff0c;它可以包含多个类型不同的成员。在C语言中&#xff0c;还有另外一种和结构体非常类似的语法&#xff0c;叫做共用体&#xff08;Union&#xff09;&#xff0c;它的定义格式为&#xff1a; …

c语言union(c语言union用法)

C语言-程序运行结果是&#xff1f;main(){unionstu{lon 我的机器&#xff0b;vc6运行的结果是12 我的理解是首先取最长的b的长度&#xff0c;但是b的长度比我的机器字长(32位即4个字节)整数倍要短&#xff0c;则sizeof(stu)的长度是12 不知道你的机器是不是64位的 如果是则证…

quartz mysql 配置_quartz的数据库配置

Quartz.net官方开发指南 第九课&#xff1a; JobStore JobStore负责保持对所有scheduler “工作数据”追踪&#xff0c;这些工作数据包括&#xff1a;job(任务),trigger(触发器),calendar(日历)等。为你的Quartz scheduler选择合适的JobStore是非常重要的一步&#xff0c;幸运的…

java 灵活配置quartz

项目背景&#xff1a; 最近项目上遇到个需求&#xff0c;需要我们在特定的事件做邮件和短信的发送。但时间并不固定&#xff0c;是根据用户配置的时间表来进行的定时发送任务。有点像闹钟&#xff0c;你设置的时间到了就响。这里我们采取的是每天凌晨定时取数据库里的时间表信…

java quartz配置_java quartz简单使用

1.在项目里引入quartz org.quartz-scheduler quartz 2.3.0 2.quartz的简单实例 package com.example.quartz_demo; import org.quartz.JobDetail; import org.quartz.Scheduler; import static org.quartz.JobBuilder.newJob; import static org.quartz.TriggerBuilder.newTrig…

SpringBoot - 集成Quartz框架之常用配置(二)

文件约定 在Quartz发布的JAR包的org.quartz包下&#xff0c;包含了一个命名为quartz.properties的配置文件并提供了默认属性&#xff0c;如果需要调整默认配置&#xff0c;则可以在类路径下建立一个新的quartz.properties&#xff0c;它将自动被Quartz加载并覆盖默认值。如果使…

浅析Quartz的集群配置

1、基本信息&#xff1a; Quartz是一个开源的作业调度框架&#xff0c;它完全由java写成&#xff0c;并设计用于J2Se和J2EE应用中。它提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征&#xff0c;如&#xff1a;数据库支…

SpringBoot2集成Quartz配置独立数据源

需求说明 Quartz配置需要部署独立的表结构&#xff0c;但是经常存于业务表之间&#xff0c;有些时候可能需要与业务表分开配置&#xff0c;所以在此给Quartz配置独立的数据源 一.版本介绍 Springboot版本为2.1.6 多数据源配置使用druid进行配置,数据库使用的为Oracle11g,如果使…

Quartz配置和运用详解

本文转自&#xff1a;http://topmanopensource.iteye.com/blog/1123824 最近工作需要学习quartz&#xff0c;那么必须首先了解三个概念&#xff1a; 调度器&#xff1a;负责调度作业和触发器&#xff1b; 触发器&#xff1a;设置作业执行的时间、参数、条件等&#xff1b;&…

Springboot——quartz简单配置和使用

文章目录 简单maven项目配置依赖配置编写处理类编写测试类 Springboot 项目配置依赖引入编写任务具体处理类编写配置类注意事项测试 简单maven项目配置 依赖配置 springboot项目中增加如下的quartz依赖信息&#xff1a; <!-- https://mvnrepository.com/artifact/org.qua…

Quartz配置文件quartz.properties加载

Quartz配置文件quartz.properties加载 前天&#xff0c;同事来问我&#xff0c;quatz任务调度的qurtaz.properties配置文件是如何加载的&#xff0c;项目是老大写的&#xff0c;我没看过代码&#xff0c;于是去翻了一遍源码&#xff0c;终于找到了配置的加载地方&#xff0c;让…

quartz mysql 配置_Quartz配置

1. Quartz主要配置 属性名称是否必选类型默认值说明 org.quartz.scheduler.instanceName 否 String QuartzScheduler Schedule调度器的实体名字 org.quartz.scheduler.instanceId 否 String NON_CLUSTERED Schedule调度器的实体的Id,必须唯一。 1. 当你想生成intanceId的时候可…

(AnyWhere-)安卓版“捷径”

下载 久闻酷安大名&#xff0c;下了酷安App&#xff0c;真是发现了新大陆。可以的&#xff0c;看上了AnyWhere-&#xff0c;下载试试 AnyWhere-下载地址 - 酷安 使用教程 一开始看的是这篇文章入坑的 真的不用羡慕iOS&#xff01;神奇APP“AnyWhere”让安卓也能玩“捷径” …

Anywhere,一个随启随用的静态服务器

现在用webpack也很少用到这种启动服务&#xff0c;偶尔做个小demo还是可以用用 Anywhere是一个随启随用的静态服务器&#xff0c;它可以随时随地将你的当前目录变成一个静态文件服务器的根目录。 一、首先得有node 如果没有的话&#xff0c;直接去官网下载安装包或者用brew …

Anywhere 随启随用的静态文件服务器

1.Anywhere 随启随用的静态文件服务器 ----利用nodeJs anywhere搭建本地服务器环境一&#xff1a;首先去nodeJs官网下载最新版nodeJs https://nodejs.org/en/ 安装成功后winr打开cmd 输入node -help 或者node -v查看是否安装成功 二&#xff1a;装好后输入 npm install anywhe…

快速搭建本地WebServer环境--anywhere

方式1. Nodejs anywhere 命令快速搭建 (需要nodejs环境) ● 安装anywhere包 npm install -g anywhere ● 在目录地址栏输入cmd, 打开命令提示符窗口, 输入命令 anywhere -p 8000 ● 将会自动在浏览器打开, 或者手动输入 本机ip:8000 打开 方式2. 使用 PhpStudy 软件 下载链…

如何连接到Sybase SQL Anywhere数据库

Sybase SQL Anywhere数据库具有许多非常有用的功能,与竞争对手相比,它具有很高的竞争力。首先,它允许您处理大量数据。其次,它具有很高的生产率,也就是说,可以快速提供大量数据。第三,它需要最少的管理。最后,它几乎完全自动化地集成到自定义应用程序中,不需要支持。 …

使用cors-anywhere-master 解决VUE+AXIOS跨域问题

在VUE框架中&#xff0c;用AXIOS加载微信文章&#xff0c;遇到跨域问题&#xff01; 解决方案&#xff1a; 1、去GITHUB下载 cors-anywhere-master GitHub - Rob--W/cors-anywhere: CORS Anywhere is a NodeJS reverse proxy which adds CORS headers to the proxied reques…

InstallAnywhere项目,安装开发解决方案

InstallAnywhere项目,安装开发解决方案 InstallAnywhere 是面向应用程序生产商的领先安装开发解决方案。它允许您为物理、虚拟和云环境提供一致、专业的多平台安装。您可以为本地平台(Windows、Linux、Apple、Solaris、AIX、HP-UX 和 IBM)创建可靠的安装。将现有的和新的软件产…

InstallAnywhere 2020 下载安装

InstallAnywhere 2020 InstallAnywhere 2020 提供专业且可靠的多平台安装 无论使用什么平台&#xff0c;InstallAnywhere均可使开发人员轻松创建性能相同的专业安装软件。 您将能够为Windows&#xff0c;Linux&#xff0c;Apple&#xff0c;Solaris&#xff0c;AIX&#xff0c…