41 C 语言共用体:共用体数据类型、共用体变量、访问共用体成员、与结构体的区别

目录

1 什么是共用体

2 共用体与结构体的区别

3 声明共用体类型

4 声明共用体变量

5 共用体内存分析

6 共用体成员的获取和赋值

7 综合案例

7.1 共同体特点演示

7.2 使用共用体存储学生和教师信息


1 什么是共用体

        共用体(Union)是一种特殊的数据结构,允许不同数据类型的成员共享同一块内存区域。这意味着,在任意时刻,共用体中只有一个成员是有效的,因为新赋值的成员会覆盖前一个成员的值。

        共用体主要用于需要节省内存或处理多种数据类型但每次只使用其中一种的情况。例如,表示学生的成绩时,成绩可能以不同的形式给出——整数(80、90)、字符等级('A'、'B')或是浮点数分数(80.5、60.5)。


2 共用体与结构体的区别

特性/类型结构体 (Struct)共用体 (Union)
内存分配每个成员分配独立的内存空间所有成员共享同一块内存空间
内存大小总内存大小可以认为是所有成员内存大小之和总内存大小等于最大成员的内存大小
数据访问可以同时访问所有成员同一时间只能有效访问一个成员
成员存储每个成员有自己的内存地址所有成员的起始地址相同
初始化可以初始化多个成员只能初始化第一个成员
适用场景需要存储和同时访问多个不同数据类型的数据需要节省内存且每次只使用其中一个成员的情况
类型安全更类型安全,每个成员有明确的类型类型安全性较低,容易发生类型混淆

        结构体:每个成员都有独立的内存空间,结构体所占用的总内存可以认为是所有成员占用内存之和(实际内存占用会受到对齐(alignment)的影响)。可以同时访问所有的成员,每个成员都有自己独特的内存地址

        共用体:所有成员共享同一块内存,共用体所占用的内存大小取决于其最大的成员。一次只能有效访问一个成员,访问不同的成员时,实际上是在查看同一内存区域的不同解释


3 声明共用体类型

union 共用体类型名称 {数据类型 成员名1;数据类型 成员名2;...数据类型 成员名n;
};

        下面的 union data 定义了一个名为 data 的共用体类型,该类型包含三个成员:一个整数 m、一个浮点数 x 和一个字符 c。

union data {int m;float x;char c;
};

        该共用体所有成员共享同一块内存,共用体的总内存大小等于其最大成员的大小。在大多数系统中,float 类型通常占用 4 个字节,因此 union data 也将占用 4 个字节。需要注意的是:同一时间只能有效访问一个成员,最后一个被赋值的成员是当前有效的成员

4 声明共用体变量

方式 1:先定义共用体类型,再定义共用体变量

// 声明共用体类型
union data {short m;float x;char c;
};// 声明共用体变量
union data a, b;

        首先定义一个共用体类型 union data,其中包含三个成员:short m、float x 和 char c。 然后在单独的语句中声明共用体变量 a 和 b,这两个变量都是 union data 类型。

方式 2:定义共用体类型的同时定义共用体变量

// 定义共用体类型并声明共用体变量
union data {short m;float x;char c;
} a, b;

        在同一行中定义共用体类型 union data 并同时声明共用体变量 a 和 b。这种方式简洁,减少了代码量。 

方式3:在定义时也可以不给出共用体名

// 定义共用体类型并声明共用体变量,不给出共用体名
union {short m;float x;char c;
} a, b;

        定义共用体时不给出共用体名,直接在定义时声明共用体变量 a 和 b。这种方式适用于不需要多次使用该共用体类型的情况。

5 共用体内存分析

// 定义共用体类型并声明共用体变量
union data {short m;float x;char c;
} a;

        上面这个共用体它由3个成员组成,分别是 m、x 和 c,系统会按照最长的成员为它分配内存,由于成员 x 的长度最长,它占 4 个字节,所以共用体变量 a 的内存空间也为 4 个字节。

6 共用体成员的获取和赋值

        同结构体一样,共用体也使用点号. 获取单个成员,可以进行赋值和取值。

方式 1:先声明共用体变量,再赋值

union data a;
a.c = 4;

        首先声明一个共用体变量 a。然后使用点号 . 给成员 c 赋值为 4。 

方式 2:声明共用体变量的同时,给任一成员赋值

union data a = {.c = 4};

        在声明共用体变量 a 的同时,使用指定成员的方式给成员 c 赋值为 4。这种方式明确指定了赋值的成员,提高了代码的可读性。 

方式 3:声明共用体变量的同时,给首成员赋值

union data a = {8};

        在声明共用体变量 a 的同时,给第一个成员赋值为 8。这种方式不指定成员名,因此只能为第一个成员赋值。如果共用体的第一个成员是 short m,则 m 将被赋值为 8。


7 综合案例

7.1 共同体特点演示

#include <stdio.h>// 方式1
union data
{short m;float x;char c;
};
union data a1, b1;// 方式2
union data2
{short m;float x;char c;
} a2, b2;// 方式3
union
{short m;float x;char c;
} a3, b3;int main()
{// 赋值并访问// 方式1a1.m = 100;b1.x = 3.14;// 打印方式1printf("a1.m: %hd\n", a1.m);  // 100printf("b1.x: %.2f\n", b1.x); // 3.14// 方式2a2.c = 'A';b2.m = 200;// 打印方式2printf("a2.c: %c\n", a2.c);  // Aprintf("b2.m: %hd\n", b2.m); // 200// 方式3a3.x = 2.71;b3.c = 'B';// 打印方式3printf("a3.x: %.2f\n", a3.x); // 2.71printf("b3.c: %c\n", b3.c);   // B// 注意:访问其他成员时,值可能已经被覆盖// 在任意时刻,共用体中只有一个成员是有效的// 访问不同的成员时,实际上是在查看同一内存区域的不同解释a1.c = 'a';printf("a1.c: %c\n", a1.c);  // aprintf("a1.m: %hd\n", a1.m); // 97,这是 a 转换成的数值 97printf("a1.x: %f\n", a1.x);  // 0.000000,字符转换成浮点数// 共用体所占用的内存大小取决于其最大的成员printf("共用体a1的长度为:%zu\n", sizeof(a1));   // 4,成员最大的是 float 类型,所以为 4printf("float类型的长度:%zu\n", sizeof(float)); // 4printf("short类型的长度:%zu\n", sizeof(short)); // 2printf("char类型的长度:%zu\n", sizeof(char));   // 1return 0;
}

        输出结果如下所示:

7.2 使用共用体存储学生和教师信息

        现有一张关于学生信息和教师信息的表格。学生信息包括姓名、编号、性别、职业、 分数,教师的信息包括姓名、编号、性别、职业、教学科目:可以参考下面的表格。

        请利用共用体,只使用一个结构体保存每个人的信息。

NameNumSexProfessionScore / Course
孙二娘501女(f)学生(s)89.5
吴用1011男(m)老师(t)math
顾大嫂109女(f)老师(t)English
林冲982男(m)学生(s)95.0
#include <stdio.h>
#define TOTAL 2 // 定义人员总数// 定义了一个结构体 Person
struct Person
{char name[20];   // 姓名int num;         // 编号char sex;        // 性别 (f: 女, m: 男)char profession; // 职业 (s: 学生, t: 老师)union{                    // 共用体,用于存储学生的分数或教师的教学科目float score;     // 学生的分数char course[20]; // 教师的教学科目} sc;                // sc 是一个共用体变量
};// 以表格形式打印输出所有人的信息
void printTableInfo(struct Person *p);int main()
{struct Person persons[TOTAL]; // 定义了一个结构体数组,用于存储多个人的信息// 输入人员信息for (int i = 0; i < TOTAL; i++){printf("请输入第%d人的信息,格式:姓名 编号 性别 (f: 女, m: 男) 职业 (s: 学生, t: 老师)\n", i + 1);scanf("%s %d %c %c", persons[i].name, &(persons[i].num), &(persons[i].sex), &(persons[i].profession));if (persons[i].profession == 's'){ // 如果是学生printf("请输入该学生成绩:");scanf("%f", &persons[i].sc.score);}else{ // 如果是老师printf("请输入该老师课程:");scanf("%s", persons[i].sc.course);}fflush(stdin); // 刷新输入缓冲区}// 调用输出函数printTableInfo(persons);return 0;
}void printTableInfo(struct Person *p)
{// 输出人员信息printf("\n姓名\t\t编号\t性别\t职业\t成绩 / 科目\n");for (int i = 0; i < TOTAL; i++){if (p[i].profession == 's'){ // 如果是学生printf("%s\t\t%d\t%c\t%c\t\t%.1f\n",p[i].name, p[i].num, p[i].sex, p[i].profession, p[i].sc.score);}else if (p[i].profession == 't'){ // 如果是老师printf("%s\t\t%d\t%c\t%c\t\t%s\n",p[i].name, p[i].num, p[i].sex, p[i].profession, p[i].sc.course);}}
}

        输出结果如下所示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/448142.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大型企业软件开发是什么样子的? - Web Dev Cody

引用自大型企业软件开发是什么样子的&#xff1f; - Web Dev Cody_哔哩哔哩_bilibili 一般来说 学技术的时候 我们会关注 开发语言特性 &#xff0c;各种高级语法糖&#xff0c;底层技术 但是很少有关注到企业里面的开发流程&#xff0c;本着以终为始&#xff08;以就业为导向…

OpenCV高级图形用户界面(8)在指定的窗口中显示一幅图像函数imshow()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在指定的窗口中显示一幅图像。 函数 imshow 在指定的窗口中显示一幅图像。如果窗口是以 cv::WINDOW_AUTOSIZE 标志创建的&#xff0c;图像将以原…

An.如何在an中截取音频片段

如何在an中截取音频片段 在an动画制作过程中&#xff0c;部分片段需要插入音乐&#xff0c;如果想要插入一首歌曲的其中一小节&#xff0c;打开音频编辑软件操作就很麻烦&#xff0c;不妨直接在an中操作&#xff1a; 以这首节气歌为例&#xff0c;前奏太长需要剪掉前面的部分 …

TOGAF 9.2 与 TOGAF 10 的对比分析:架构演进之路

TOGAF 9.2 与 TOGAF 10 的对比分析&#xff1a;架构演进之路 前言 TOGAF&#xff08;The Open Group Architecture Framework&#xff09;自诞生以来&#xff0c;已成为企业架构&#xff08;EA&#xff09;领域的全球标准框架。随着时代的发展&#xff0c;TOGAF也在不断进化&…

基于SpringBoot+Vue+uniapp的在线招聘平台的详细设计和实现

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…

第二课:Python入门学习之开发工具的安装

今天我们进行Python开发工具的安装&#xff0c;其实网上的开发工具是很多的&#xff0c;每个人的习惯也都不一样&#xff0c;我们先去官网下载一个比较常用的吧。废话不多开始操作。 第一步&#xff1a;打开官网地址&#xff1a;https://www.jetbrains.com.cn/ 第二步&#xf…

面试题:Redis(三)

1. 面试题 背景 问题&#xff0c;上面业务逻辑你用java代码如何写&#xff1f; 2. 缓存双写一致性谈谈你的理解&#xff1f; 3. 双检加锁策略 多个线程同时去查询数据库的这条数据&#xff0c;那么我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它。 其他的线程走到这…

微知-Mellanox驱动中的iSCSI是什么?有哪三种网络存储有哪三种?iSER是什么?(iSCSI协议(总线),SAN 存储区域网络)

背景 本文根据Mellanox网卡驱动中关于iSCSI模块&#xff0c;来介绍iSCSI是什么&#xff1f;该技术发展演进背景&#xff1f; 关于iSCSI iSCSI是一种协议&#xff0c;SCSI是总线。比如常说的SAS&#xff08;Serial Attach SCSI&#xff09;存储盘对比与家用的SATA&#xff0…

Uiautomator2与weditor配置一直报错咋办

作者在配置这两个的时候绞尽脑汁了&#xff0c;u2的init总是报错并且无法自动在手机上安装atx&#xff0c;weditor可以打开但是只要对元素操作或者任意操作就会让你去重新init&#xff0c;搞得作者焦头烂额&#xff0c;而且网上各种各样的报错信息眼花缭乱&#xff0c;作者几乎…

NVIDIA NIM平台如何打造AI图表识别系统

NVIDIA NIM是一套易于使用的推理微服务&#xff0c;旨在加速企业中性能优化的生成式 AI 模型的部署。 NIM 推理微服务可以部署在任何地方&#xff0c;从工作站和本地到云&#xff0c;提供企业控制自己的部署选择并确保数据安全。它还提供行业领先的延迟和吞吐量&#xff0c;实现…

使用Windows创建一个MFC应用【带界面】

MFC使用教程【对初学者保姆型友好&#xff01;】 目录 前提条件 1&#xff1a;创建MFC应用程序 2. 项目结构解读 引用 外部依赖项 头文件 源文件 资源文件 文件功能详解 项目的主要流程 步骤2&#xff1a;配置OpenCV 安装OpenCV 包含目录与库文件 步骤3&#xff1…

云卓H30:引领科技与性能的完美融合!

在科技日新月异的今天&#xff0c;一款集高性能与便捷操作于一体的手持地面站成为了无人机、机器人等智能设备的得力助手。云卓H30手持地面站&#xff0c;凭借其搭载的高通骁龙660处理器&#xff0c;在多个适用场景中展现出了卓越的实力。 高通骁龙660&#xff0c;这款先进的移…

Python 如何处理大规模数据库表的迁移与数据迁移的高效执行

Python 如何处理大规模数据库表的迁移与数据迁移的高效执行 引言 在现代应用开发中&#xff0c;随着业务需求的增长&#xff0c;数据库表结构和数据往往需要进行迁移和更新。迁移&#xff08;Migration&#xff09;是指对数据库表的结构、数据类型、索引、约束等进行修改或更新…

Docker 安装sql server 登陆失败

错误&#xff1a; Sqlcmd: Error: Microsoft ODBC Driver 18 for SQL Server : SSL Provider: [error:0A000086:SSL routines::certificate verify failed:self-signed certificate]. Sqlcmd: Error: Microsoft ODBC Driver 18 for SQL Server : Client unable to establish co…

UE5 TimeLine入门

UE5 TimeLine入门 时间轴曲线 共计三个关键帧&#xff08;0,0&#xff09;(1.5,10) (3,0) 蓝图 1.按下空格键执行。 2.时间轴TimeLine函数。 3.动画播放结束后执行。 4.每一帧都执行。

单片机原理及应用笔记:单片机的结构原理与项目实践

作者介绍 李婷婷&#xff0c;女&#xff0c;银川科技学院计算机与人工智能学院&#xff0c;2022级计算机与科学技术9班本科生&#xff0c;单片机原理及应用课程第五组。 指导老师&#xff1a;王兴泽 电子邮箱&#xff1a;365349930qq.com 前言 本篇文章是参考《单片机原理…

rk3568 , rk3588 , rknpu2 sdk , rknn-toolkit2, rknn-toolkit2-lite 的了解

rknpu2 sdk 与 rknn-toolkit 的区别。 网上的截图&#xff1a; 总结&#xff1a; rknpu2 是针对 C接口的&#xff0c; rknn toolkit2 是针对 Python接口的。 至于 连不连板&#xff0c; 是不是 拷贝&#xff0c; 那不重要。 然后是 rknn rootlkit2 与 rknn toolkit2 li…

数据结构算法题:栈与队列的使用(一)

目录 用队列实现栈题目解题思路代码实现创建栈的结构体栈的初始化入栈出栈获取栈顶数据判断栈是否为空销毁栈 用队列实现栈 题目 题目描述&#xff1a; 示例&#xff1a; 解题思路 题目要求使用两个队列实现栈的入栈、出栈、获取栈顶元素、检查栈是否为空栈的基本操作。 …

答题pk小程序的技术特点和性能优势分析

答题小程序是一种在移动设备上运行的应用程序&#xff0c;旨在提供各种类型的答题体验。以下是答题小程序的一些特点和优势&#xff1a; 一、特点 多样化的题目类型&#xff1a; 包括选择题、填空题、判断题等常见题型&#xff0c;还可能有简答题、论述题等更具挑战性的题型。…

健康推荐系统:SpringBoot技术实现

3系统分析 3.1可行性分析 通过对本基于智能推荐的卫生健康系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本基于智能推荐的卫生健康系统采用SSM框架&#…