【C语言篇】自定义类型:联合体和枚举详细介绍

news2024/9/21 10:35:50

文章目录

  • 联合体
    • 联合体类型的声明
    • 联合体的特点
    • 联合体和结构体对比
    • 联合体大小的计算
    • 判断大小端
  • 枚举
    • 枚举类型的声明
    • 枚举类型的优点
    • 枚举的使用

联合体

联合体类型的声明

像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。

但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。所以联合体也叫:共⽤体。

给联合体其中⼀个成员赋值,其他成员的值也跟着变化。

#include <stdio.h>
//联合类型的声明 
union Un
{
    char c;
    int i;
};

int main()
{
    //联合变量的定义 
    union Un un = {0};
    //计算连个变量的⼤⼩ 
    printf("%d\n", sizeof(un));
    return 0;
}

输出的结果:4

这是为什么呢?

联合体的特点

联合的成员是共⽤同⼀块内存空间的,这样⼀个联合变量的⼤⼩,⾄少是最⼤成员的⼤⼩(因为联合体⾄少得有能⼒保存最⼤的那个成员)

//代码1 
#include <stdio.h>
//联合类型的声明 
union Un
{
    char c;
    int i;
};
int main()
{
    //联合变量的定义 
    union Un un = {0};
    // 下⾯输出的结果是⼀样的吗? 
    printf("%p\n", &(un.i));
    printf("%p\n", &(un.c));
    printf("%p\n", &un);
    return 0;
}

输出结果一样

//代码2 
#include <stdio.h>
//联合类型的声明 
union Un
{
    char c;
    int i;
};
int main()
{
    //联合变量的定义 
    union Un un = {0};
    un.i = 0x11223344;
    un.c = 0x55;
    printf("%x\n", un.i);//11223355
    return 0;
}

综上:

代码1输出的三个地址⼀模⼀样,代码2的输出,我们发现将i的第4个字节的内容修改为55了。 我们仔细分析就可以画出,un的内存布局图。

在这里插入图片描述

联合体和结构体对比

struct S
{
    char c;
    int i;
};
struct S s = {0};

union Un
{
    char c;
    int i;
};
union Un un = {0};

在这里插入图片描述

联合体大小的计算

  • 联合的⼤⼩⾄少是最⼤成员的⼤⼩。
  • 当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍。

在VS环境下

#include <stdio.h>
union Un1
{
    char c[5];//和五个char类型一样的 1 8 1
    int i;//4 8 4
};
union Un2
{
    short c[7];
    int i;
};
int main()
{
    //下⾯输出的结果是什么? 
    printf("%d\n", sizeof(union Un1));//8
    printf("%d\n", sizeof(union Un2));//16
    return 0;
}

使⽤联合体是可以节省空间的,举例:

⽐如,我们要搞⼀个活动,要上线⼀个礼品兑换单,礼品兑换单中有三种商品:图书、杯⼦、衬衫。

每⼀种商品都有:库存量、价格、商品类型和商品类型相关的其他信息

图书:书名、作者、⻚数

杯⼦:设计

衬衫:设计、可选颜⾊、可选尺⼨

直接写代码如下:

struct gift_list
{
    //公共属性 
    int stock_number;//库存量 
    double price; //定价 
    int item_type;//商品类型 

    //特殊属性 
    char title[20];//书名 
    char author[20];//作者 
    int num_pages;//⻚数 
    char design[30];//设计 
    int colors;//颜⾊ 
    int sizes;//尺⼨ 
};

上述的结构其实设计的很简单,⽤起来也⽅便,但是结构的设计中包含了所有礼品的各种属性,这样使得结构体的⼤⼩就会偏⼤,⽐较浪费内存。因为对于礼品兑换单中的商品来说,只有部分属性信息是常⽤的。

⽐如: 商品是图书,就不需要design、colors、sizes。

所以我们就可以把公共属性单独写出来,剩余属于各种商品本⾝的属性使⽤联合体,这样就可以节省所需的内存空间,⼀定程度上节省了内存。

struct gift_list
{
    int stock_number;//库存量 
    double price; //定价 
    int item_type;//商品类型 

    union {
        struct
        {
            char title[20];//书名 
            char author[20];//作者 
            int num_pages;//⻚数 
        }book;
        struct
        {
            char design[30];//设计 
        }mug;
        struct 
        {
            char design[30];//设计 
            int colors;//颜⾊ 
            int sizes;//尺⼨ 
        }shirt;
    }item;
};

判断大小端

在【C语言篇】数据在内存中的存储我们讲过数据在内存中存储分为大端和小端

  • ⼤端(存储)模式: 是指数据的低位字节内容保存在内存的⾼地址处,⽽数据的⾼位字节内容,保存在内存的低地址处。
  • ⼩端(存储)模式: 是指数据的低位字节内容保存在内存的低地址处,⽽数据的⾼位字节内容,保存在内存的⾼地址处。

之前我们的写法是这样的:

//写一个程序,判断当前机器是大端?还是小端?
int main()
{
    int a = 1;
    if (*(char*)&a == 1)
    {
        printf("小端\n");
    }
    else
    {
        printf("大端\n");
    }
    //0x 00 00 00 01
    return 0;
}

这里我们可以使用联合体很好实现:

union Un
{
    char c;
    int i;
};

int main()
{
    union Un un = { 0 };
    un.i = 1;
    if (un.c == 1)
    {
        printf("小端\n");
    }
    else
    {
        printf("大端\n");
    }
    //0x 00 00 00 01
    return 0;
}

枚举

枚举类型的声明

枚举顾名思义就是⼀⼀列举。

把可能的取值⼀⼀列举。

⽐如我们现实⽣活中:

⼀周的星期⼀到星期⽇是有限的7天,可以⼀⼀列举

性别有:男、⼥、保密,也可以⼀⼀列举

⽉份有12个⽉,也可以⼀⼀列举

三原⾊,也是可以一一列举

enum Day//星期
{
    Mon,
    Tues,
    Wed,
    Thur,
    Fri,
    Sat,
    Sun
};

enum Sex//性别
{
 MALE,
 FEMALE,
 SECRET
}enum Color//颜⾊
{
 RED,
 GREEN,
 BLUE
};

以上定义的 enum Dayenum Sexenum Color 都是枚举类型。

{}中的内容是枚举类型的可能取值,这些都是常量,也叫枚举常量

这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。

enum Color//颜⾊
{
    //它们都是常量,之后不能改,但是在最初始是可以赋初值
    RED=2,
    GREEN=4,
    BLUE=8
};

枚举类型的优点

为什么使⽤枚举?

我们可以使⽤ #define 定义常量,为什么⾮要使⽤枚举?

枚举的优点:

  1. 增加代码的可读性和可维护性
  2. #define定义的标识符⽐较,枚举有类型检查,更加严谨。
//例子如下
#include <stdio.h>
enum Sex
{
    MALE=3,
    FEMALE=5,
    SECRET=7
};

int main()
{
    enum Sex sex1 =3;//会报错,必须使用枚举常量
    enum Sex sex2 = FEMALE;
    return 0;
}

在这里插入图片描述

注意:以上例子在C语⾔中是可以的,但是在C++是不⾏的,C++的类型检查更严格

  1. 便于调试,预处理阶段会删除 #define 定义的符号

  2. 使⽤⽅便,⼀次可以定义多个常量

  3. 枚举常量是遵循作⽤域规则的,枚举声明在函数内,只能在函数内使⽤


枚举的使用

增加可读性例子如下:

#include <stdio.h>
//写一个计算器-完成整数的加法、减法、乘法、除法

enum Option
{
    EXIT,//0
    ADD,//1
    SUB,//2
    MUL,//3
    DIV//4 
};

void menu()
{
    printf("**********************************\n");
    printf("****** 1. add    2. sub     ******\n");
    printf("****** 3. mul    4. div     ******\n");
    printf("****** 0. exit              ******\n");
    printf("**********************************\n");
}

int main()
{
    int input = 0;
    do
    {
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        switch (input)
        {
            case SUB:
                break;
            case ADD:
                break;
            case MUL:
                break;
            case DIV:
                break;
            case EXIT:
                printf("退出\n");
                break;
            default:
                printf("选择错误,重新选择\n");
                break;
        }
    } while (input);
    return 0;
}

以上就是关于联合体和枚举的详细介绍啦,各位大佬有什么问题欢迎在评论区指正,您的支持是我创作的最大动力!❤️
在这里插入图片描述

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

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

相关文章

第10章 无持久存储的文件系统 (1)

目录 前言 10.1 proc文件系统 10.1.1 /proc 内容 本专栏文章将有70篇左右&#xff0c;欢迎关注&#xff0c;查看后续文章。 前言 即存在于内存中的文件系统。如&#xff1a; proc&#xff1a; sysfs&#xff1a; 即/sys目录。 内容不一定是ASCII文本&#xff0c;可能是二进…

Delaunay三角化重要性质,最小角最大化

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 最大化最小角 推论 有点集P是一般点集&#xff08;没有多点共线&#xff0c;没有4点共圆&#xff09;&#xff0c;那么该点集的delauney三角后的最小角不小于其他非de…

HTML5+CSS3笔记(Xmind格式):第五天

Xmind鸟瞰图&#xff1a; 简单文字总结&#xff1a; HTML5CSS3知识总结&#xff1a; canvas坐标&#xff1a; 画图的基本步骤&#xff1a; 1.创建画布 2.获取画布 3.开始路径规划 4.规定画笔颜色 5.规定画笔粗细 6.开始作…

OLAP与OLTP:数据处理系统的两种核心架构

目录 一、什么是OLAP&#xff1f; 二、什么是OLTP&#xff1f; 三、OLAP与OLTP的主要区别 四、结论 在数据管理和分析的领域中&#xff0c;OLAP&#xff08;在线分析处理&#xff09;和OLTP&#xff08;在线事务处理&#xff09;代表了两种重要的数据处理模式。它们在功能、目标…

MoE-LLaVA: Mixture of Experts for Large Vision-Language Models

发表时间&#xff1a;6 Jul 2024 论文链接&#xff1a;https://arxiv.org/pdf/2401.15947 作者单位&#xff1a;Peking University Motivation&#xff1a;最近的进展表明&#xff0c;扩展大型视觉语言模型 (LVLM) 有效地提高了下游任务的性能。然而&#xff0c;现有的缩放方…

uniapp版本更新除了plus.runtime.getProperty的解决办法

以下是展示图 带尺寸的图片: 首先把以下代码放到想要更新弹出的页面 //template部分<uni-popup ref"popup" background-color"#fff"><versionUp handleCloseVersion"closeVersion"></versionUp></uni-popup>//script…

支付宝开放平台竟出现一张神秘人脸!

前言 ​ 我因一个单子来到支付宝开放平台来。在将其加入书签的时候&#xff0c;我发现出现了个神秘的人脸 一张笑容明媚的脸&#xff0c;就是出现的时候不太对 正常的收藏网址 应该是显示对应log 就不继续找相关例子了 ​ 添加书签的页面&#xff0c;本该出现log的地方缺出现了…

SQL注入实例(sqli-labs/less-23)

0、初始网页 1、闭合方式判断 闭合符号为单引号&#xff0c;通过测试发现过滤了注释&#xff0c;所以直接闭合 2、确定查询表的列数 确定查询表的列数为3列 ?id1 order by 3 3、确定回显位置 回显位置为第二列和第三列 ?id-1 union select 1,2,3 4、查看当前登录和数据…

【统信UOS】桌面系统通过自定义内网补丁仓库升级内网系统

原文链接&#xff1a;【统信UOS】桌面系统通过自定义内网补丁仓库升级内网系统 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于在统信桌面系统上通过自定义内网补丁仓库升级内网系统的文章。在企业或组织内部网络环境中&#xff0c;为了安全性和便捷性&#xff…

《Ubuntu22.04环境下的ROS2学习笔记1》

一、在ROS2环境下创建工作空间 ROS2相比ROS1来说工作空间的创建有较大的不同&#xff0c;同时工作空间中的四个目录被更换为src(存放源码) &#xff0c; build(存放编译的中间文件) &#xff0c; install(存放可执行文件) &#xff0c; log(日志)。同时命令行也有些许变化&…

【循环神经网络】案例:周杰伦歌词文本预测【训练+python代码】

文章目录 1、简介2、数据集3、构建词典4、构建数据集对象5、构建网络模型6、构建训练函数6.1、多分类交叉熵损失函数&#x1f53a;6.2、Adam&#x1f53a;6.3、代码 7、构建预测函数8、word_to_index和index_to_word8.1、word_to_index8.2、index_to_word8.3、使用场景 9、Data…

OpenHarmony编译

简介&#xff1a;本文将会介绍编译OpendHarmony环境的搭建、编译、和刷机&#xff08;rk3568&#xff09; 使用场景&#xff1a;修改系统源码&#xff0c;需要验证修改的功能是否正确、编译镜像、编译SDK 1、VS Code&#xff0c;下载链接&#xff0c;用于修改源码 2、linux环…

“低代码”平台的机遇与挑战

低代码平台的机遇 提高开发效率&#xff1a; 低代码平台通过提供可视化的开发工具和可重用的组件&#xff0c;显著提高了开发效率。开发者能够更快速地构建和部署应用&#xff0c;迅速响应市场需求。据普遍观点&#xff0c;低代码平台能够提升30%以上的开发效率&#xff0c;而无…

记一次用户认证代码重构中设计模式及设计原则的使用

目录 一、需求二、初始代码 - 上来就怼三、重构1 - 单一职责&#xff08;方法级&#xff09;四、重构2 - 单一职责&#xff08;类级、策略模式&#xff09;、简单工厂五、重构3 - 依赖注入&#xff08;避免重复创建对象&#xff09;六、重构4 - 使用Map替代if...else、享元模式…

AI浪潮下的程序员命运:消失还是进化?

随着人工智能技术的迅猛发展&#xff0c;程序员职业正面临着前所未有的挑战与机遇。在这个变革的时代&#xff0c;程序员们究竟该如何应对&#xff0c;才能在AI浪潮中乘风破浪&#xff0c;开创属于自己的朝阳之路呢&#xff1f; 程序员这一职业正迎来前所未有的变革&#xff0…

DC-9靶机渗透测试

DC-9靶机 文章目录 DC-9靶机信息收集web渗透后台渗透用户横向移动权限提升靶机总结 信息收集 扫描目标主机存在的端口信息 存在80和22端口 看来思路应该不会有太大变化了&#xff0c;但是ssh端口是处于过滤的状态 进行漏洞扫描也没扫描出有可以利用的 但知道了一些界面 web渗透…

沪深300股指期货如何操作套期保值?

沪深300股指期货的套期保值是一种重要的风险管理工具&#xff0c;用于对冲投资组合面临的市场风险。 以下是套期保值流程的详细步骤说明&#xff1a; 第一&#xff0c;评估套保需求&#xff1a;投资者首先需要基于对市场走势的深入分析和对投资组合的细致评估&#xff0c;确定…

python-flask-上传多个文件并存储

本地环境&#xff1a;win10 / centos6 &#xff0c; python3 flask入门看这里&#xff1a; ↓ python-flask结合bootstrap实现网页小工具实例-半小时速通版_bootstrap flask-CSDN博客 https://blog.csdn.net/pxy7896/article/details/137854455 动态添加和删除表格中的行&…

论文概览 |《Urban Analytics and City Science》2024.07 Vol.51 Issue.6

本次给大家整理的是《Environment and Planning B: Urban Analytics and City Science》杂志2024年7月第51卷第6期的论文的题目和摘要&#xff0c;一共包括16篇SCI论文&#xff01; 论文1 Digital twins on trial: Can they actually solve wicked societal problems and chan…

[开端]JAVA抽象类使用到redis观察着

一、绪论 当redis内容发生变化时需要通知一些观察者做一些动作怎么做&#xff1f; 二、JAVA抽象类 public abstract class AbstractRedisChangeListener {public abstract void change(String key, String value, String crudType); }使用abstract进行修饰一个类 其中抽象类…