【手撕C语言基础】联合体与枚举

news2024/11/20 20:43:37
  • (꒪ꇴ꒪ ),hello我是祐言
  • 博客主页:C语言基础,Linux基础,软件配置领域博主🌍
  • 快上🚘,一起学习!
  • 送给读者的一句鸡汤🤔:
  • 集中起来的意志可以击穿顽石!
  • 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏

        C语言是一门功能强大且灵活的编程语言,提供了许多特性和工具,使开发人员能够更好地控制和处理数据。在C语言中,联合体枚举是两个重要的概念,它们提供了一种在程序中存储和操作不同类型数据的方式。本文将深入探讨联合体和枚举的概念、语法和用法,并通过实例分析来说明它们的实际应用。

一、联合体

1.联合体基本概念

      
        联合体的外在形式跟结构体非常类似,但它们有一个本质的区别:结构体中的各个成员是各自独立的,而联合体中的各个成员却共用同一块内存,因此联合体也称为共用体,有一种“堆叠”的效果。

 

        联合体的特点如下:

  • 联合体的大小等于其中最大成员的大小,因为联合体中的成员共享同一块内存空间;
  • 联合体各成员之间形成一种“互斥"的逻辑,在某个时刻只有一个成员有效;
  • 联合体的成员可以是不同的数据类型,可以是基本类型(如整数、浮点数、字符等)或自定义类型(如结构体、枚举等)。
  • 给联合体的某个成员赋值,会覆盖其他的成员,使它们失效。

2.联合体的定义语法

        (1)联合体名字:用来区分各个不同的联合体;
       (2) 成员:是包含在联合体内部的数据,可以是任意的数据类型。

union 联合体名字 {
    成员类型 成员1;
    成员类型 成员2;
     ...
};
3.联合体操作


        联合体的操作跟结构体形式上别无二致,但由于联合体特殊的存储特性,不管怎么初始化和赋值,最终都有且仅有一个成员是有效的。

        联合体初始化成员引用联合体指针综合实例:

#include <stdio.h>

union Data {
    int i;
    float f;
    char str[20];
};

int main() {
    // 初始化联合体
    union Data data1 = { .i = 10 };
    printf("Value of data1.i: %d\n", data1.i);

    // 成员引用
    data1.f = 3.14;
    printf("Value of data1.f: %.2f\n", data1.f);

    // 联合体指针的使用
    union Data *data2 = &data1;
    data2->i = 20;
    printf("Value of data1.i: %d\n", data1.i);

    return 0;
}

        在上述示例中,我们定义一个名为 Data 的联合体,它有三个成员:整数 、浮点数 f和字符数组 str。然后,使用该联合体进行初始化、成员引用和联合体指针的使用。

二、枚举

1.枚举的概念与特点

         枚举类型的本质是提供一种范围受限的整型,比如用0-6表示七种颜色,用0-3表示四种状态等,但枚举在C语言中并未实现其本来应有的效果,直到C++环境下枚举才拥有原本该有的属性。

        枚举还是C语言中用于定义一组具有离散取值的常量的数据类型。枚举类型可以提高程序的可读性,并提供一种清晰地表示一组相关常量的方式。枚举的特点如下:

  • 枚举类型是用户自定义的数据类型,由一组命名的常量组成。
  • 枚举常量的取值是离散的,每个常量都具有唯一的整数值。
  • 默认情况下,枚举常量的第一个值为0,后续常量的值依次递增。
   2.枚举示例     

        我们定义一个名为 spectrum 的枚举类型,其中包含了颜色的枚举常量。这些常量分别是redorangeyellowgreenbluecyanpurple。我们可以使用这些常量来表示不同的颜色。

        在 main 函数中,我们声明了一个枚举变量 color,并将其初始化为 orange,表示颜色为橙色。然后,我们打印出枚举变量 color 的值。

#include <stdio.h>

enum spectrum {
    red,
    orange,
    yellow,
    green,
    blue,
    cyan,
    purple
};

int main() {
    enum spectrum color = orange;
    printf("Color: %d\n", color);

    return 0;
}

        枚举数据最重要的作用,是使用有意义的单词,来替代无意义的数字,提高程序的可读性。

三、联合体与枚举的综合应用

        下面例程定义了一个结构体Data,其中包含一个枚举类型DataType的成员type联合体类型DataValue的成员value。通过结合使用联合体和枚举,该例程实现了以下功能设计:

  • 枚举类型DataType用于标识数据的类型,其中包含了三个常量:INTEGERFLOATSTRING。这些常量用于表示数据的类型,以便在处理数据时能够正确识别其类型。

  • 联合体类型DataValue用于存储不同类型的数据值,其中包含了三个成员:整数i、浮点数f和字符数组str。这些成员共享同一块内存空间,只能同时存储其中一个成员的值。

  • 结构体Data包含了两个成员:typevaluetype成员用于存储数据的类型,通过枚举常量进行标识。value成员使用联合体类型DataValue来存储具体的数据值。

  • 函数printData用于打印数据的值。根据数据的类型,它通过switch语句选择适当的输出格式并打印数据的值。

        在main函数中,我们创建了三个Data类型的变量data1data2data3,分别表示一个整数、一个浮点数和一个字符串数据。然后,我们调用printData函数来打印这些数据的值,根据数据的类型选择适当的输出格式。

#include <stdio.h>

enum DataType {
    INTEGER,  // 整型
    FLOAT,    // 浮点型
    STRING    // 字符串型
};

union DataValue {
    int i;           // 整数
    float f;         // 浮点数
    char str[20];    // 字符串
};

struct Data {
    enum DataType type;       // 数据类型
    union DataValue value;    // 数据值
};

void printData(struct Data data) {
    switch (data.type) {
        case INTEGER:
            printf("整数: %d\n", data.value.i);
            break;
        case FLOAT:
            printf("浮点数: %.2f\n", data.value.f);
            break;
        case STRING:
            printf("字符串: %s\n", data.value.str);
            break;
        default:
            printf("无效的数据类型。\n");
            break;
    }
}

int main() {
    struct Data data1 = {INTEGER, {.i = 10}};
    struct Data data2 = {FLOAT, {.f = 3.14}};
    struct Data data3 = {STRING, {.str = "Hello"}};

    printData(data1);
    printData(data2);
    printData(data3);

    return 0;
}

四、总结

        在本文中,探讨了C语言中联合体和枚举的概念、语法和用法。通过实例分析展示了联合体和枚举在不同场景下的实际应用。学习和理解联合体和枚举,使我们可以更好地处理和操作不同类型的数据,提高程序的可读性和可维护性。

        希望本文对小白的你在C语言编程中的学习和实践有所帮助~

📢写在最后

  • 今天的分享就到这啦~
  • 觉得博主写的还不错的烦劳 一键三连喔~
  • 🎉感谢关注🎉

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

九五从零开始的运维之路(其二十)

[TOC](文章目录) 文章目录 前言一、LAMP是什么二、配置环境及安装1.配置yum源2.关闭防火墙、网络图形化工具及SElinux3.安装软件包 三、配置apache服务器内容四、启动服务五、访问验证总结 前言 本篇将简述的内容&#xff1a;Linux系统下的LAMP平台部署 基于discuz框架的论坛搭…

StartAllBack| Win11 更新系统后闪屏

解决方法&#xff1a;安装最新版 StartAllBack 中文官网&#xff1a;http://www.startallback.cn 激活方式&#xff1a; ① 点击下载好的 .exe 文件安装 StartAllBack ② 打开 StartAllBack 的安装目录 为我安装的路径&#xff1a;C:\Users\你的用户名\AppData\Local\Start…

opencv 基础学习08-图像通道操作

opencv 基础学习08-图像通道操作 什么是图像通道&#xff1f;通道操作&#xff1a;**1 通过索引拆分**2 通过opencv 函数拆分通道合并 什么是图像通道&#xff1f; OpenCV的通道拆分功能可用于将多通道图像拆分成单独的通道&#xff0c;这在图像处理和计算机视觉任务中具有许多…

[MySQL]MySQL内外连接

[MySQL]MySQL内外连接 文章目录 [MySQL]MySQL内外连接1. 内连接2. 外连接2.1 左外连接2.2 右外连接 3. 简单练习 1. 内连接 内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选&#xff0c;也是在开发过程中使用的最多的连接查询。 语法&#xff1a; SELECT ... FR…

【USRP X310】如何将你的X310转化为USRP RIO 可以用于FPGA编程

X310 转化为USRP RIO X310产品X310和NI-USRP对应关系 简介第一步原理解释打开工具运行 Initialize Flash.vi可以去选择设备类型Hardware Current Version 如何选择 第二步创建工程运行校准程序 附录&#xff1a;射频子板的IDWBXSBXCBXUBXTwinRX X310产品 X310和NI-USRP对应关系…

【Android知识笔记】应用进程(一)

应用进程的启动流程 冷启动与热启动 冷启动与热启动相比:冷启动除了要启动目标进程的入口Activity外,还需要通过AMS向Zygote申请启动目标应用进程,而热启动由于目标进程已经启动,只需直接打开目标进程的入口Activity即可。 AMS冷启动大概流程: 应用进程是在什么时机被启…

网络数据安全风险评估实施指引(二)

评估手段是多种多样的。信息安全风险评估可以用各种不同的方式识别资产脆弱性和攻击路径&#xff0c;数据安全风险评估也包含但不限于以下措施&#xff1a; 人员访谈&#xff1a;对相关人员进行访谈&#xff0c;核查制度规章、防护措施、安全责任落实情况&#xff1b; 文档查…

HTTP、HTTPS协议详解

文章目录 HTTP是什么报文结构请求头部响应头部 工作原理用户点击一个URL链接后&#xff0c;浏览器和web服务器会执行什么http的版本持久连接和非持久连接无状态与有状态Cookie和Sessionhttp方法&#xff1a;get和post的区别 状态码 HTTPS是什么ssl如何搞到证书nginx中的部署 加…

C#使用Chart进行统计,切换不同的图表类型

WindowsForm应用程序中Chart图表控件所属的命名空间&#xff1a; Chart 命名空间&#xff1a; System.Windows.Forms.DataVisualization.Charting 对应的dll路径&#xff1a; C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Syst…

链表的头指针、头节点和首元节点

链表的头指针、头节点和首元节点 头节点(哑结点) 有时&#xff0c;在链表的第一个节点之前会额外增设一个节点&#xff0c;该节点的数据域一般不存放数据&#xff08;有些情况下也可以存放链表的长度等信息&#xff09;&#xff0c;此节点被称为头节点。 若链表中存在头节点&…

[每周一更]-(第54期):Go的多版本管理工具

参考 https://zhuanlan.zhihu.com/p/611253641https://learnku.com/articles/78326 前文概要 Go语言从开始使用从1.13起步&#xff0c;随着泛型的支持&#xff0c;带领团队在转型Go的时候&#xff0c;做基础组件架构选型使用1.18&#xff0c;但是Go版本不断迭代想使用最新版本…

Java的日期时间API

目录 JDK8之前的日期时间API java.lang.System类 java.util.Date类 java.text.SimpleDateFormat类 java.util.Calendar(日历)类 java.util.GregorianCalendar类 JDK8中新日期时间API LocalDate、LocalTime、LocalDateTime 类 Instant类 java.time.format.DateTimeFor…

SCA Sentinel分布式系统的流量防卫兵

Sentinel官网:https://sentinelguard.io/zh-cn Sentinel:Sentinel是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量控制、流量路由、熔断降级、系统自适应保护等多个维度来帮助用户 保障微服务的稳定性 Sentinel与Hystrix对…

http连接处理(下)(四)

1.结合代码分析请求报文响应 下面我们将介绍服务器如何响应请求报文&#xff0c;并将该报文发送给浏览器端。首先介绍一些基础API&#xff0c;然后结合流程图和代码对服务器响应请求报文进行详解。 基础API部分&#xff0c;介绍stat、mmap、iovec、writev。 流程图部分&…

NodeJS 后端通过Http获取Base64格式数据显示图片 ②〇

文章目录 前言BASE64前端开发后端开发异步代码效果总结 ⡖⠒⠒⠒⠤⢄⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸ ⠀⠀⠀⡼⠀⠀⠀⠀ ⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢶⣲⡴⣗⣲⡦⢤⡏⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠋⠉⠉⠓⠛⠿⢷⣶⣦⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⠀…

Rust操作MySQL

查询 本部分是对 「Rust入门系列」Rust 中使用 MySQL[1]的学习与记录 经常使用的时间处理库&#xff1a; chrono 流式查询使用&#xff1a; query_iter 输出到Vec使用&#xff1a; query 映射到结构体使用&#xff1a; query_map 获取单条数据使用&#xff1a; query_first 命名…

RTP及RTP Header Extension

https://www.rfc-editor.org/rfc/rfc3550.txt 译文&#xff1a; http://www.gpssoft.cn/download/protocol/RFC-3550-%E4%B8%AD%E6%96%87%E7%89%88.pdf RTP&#xff1a;real-time transport protocol&#xff0c;实时传输协议 每一个 RTP 包中都有前 12 个字节&#xff0c;而…

了解PostgreSQL sql shell和VACUUM命令

从SQL Shell进入PostgreSQL&#xff1b;没用过这东西&#xff0c;看一下&#xff1b; 一直回车&#xff1b;最后输入口令就登入了&#xff1b;此时是登入默认的数据库postgres&#xff1b;这个数据库是默认安装的&#xff1b; 看一下有没有表&#xff0c;根据资料可以用 \d 或…

K210学习篇(五)PWM

machine.PWM PWM&#xff1a; 脉宽调制模块&#xff0c; 硬件支持的PWM&#xff0c; 可以指定任意引脚&#xff08;0到47引脚&#xff09; 每个 PWM 依赖于一个定时器&#xff0c; 即当定时器与 PWM 功能绑定后&#xff0c; 不能作为普通定时器使用了。 因为有 3 个定时器&…

go语言终端交叉编译的事项

一、可以使用的编译环境 go env 查看编译的环境 1.编译linux 64环境[centos7以及以上版本] go env -w GOOS"linux" go env -w GOARCH"amd64" 2.编译linux 32环境[centos6以及以下版本] go env -w GOOS"linux" go env -w GOARCH"386"…