没有联合和枚举 , C语言怎么能在江湖混 ?

2024-02-06 23:52

本文主要是介绍没有联合和枚举 , C语言怎么能在江湖混 ?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本篇会加入个人的所谓‘鱼式疯言’
❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言
而是理解过并总结出来通俗易懂的大白话,
我会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.
🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 !!!
在这里插入图片描述

前言

在本篇文章中,小编将带领友友们体验联合体和枚举的奥妙之处 😎 😎 😎
下面有请我们今天的主角闪亮登场

目录

1.联合体
2.枚举

一. 联合体

<1>. 联合体类型的概念

union union_name {member_type1 member1;member_type2 member2;...
};

union_name 是联合体的名称
member_type1、member_type2 是成员的数据类型
member1、member2 是成员的名称

像结构体一样,联合体也是由一个或者多个成员构成,这些成员可以不同的类型。
但是编译器只为最大的成员分配足够的内存空间。
联合体的特点是所有成员共用同一块内存空间
所以联合体也叫:共用体

<2>. 联合体的特点

第一个特点:

先请宝子们看一段代码 😃 😃 😃
思考一下哦! ! !

#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;
}

在这里插入图片描述

可以很明显的看出他们的地址居然是一模一样哒。

是哒,这就是为什么小编会说,联合体中的成员共同同一块空间了 。
见图也可知晓哦。❤️ ❤️ ❤️
在这里插入图片描述

第二个特点:

老规矩,还是先看代码哦! ! !

#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);return 0;
}

在这里插入图片描述
我们发现将i的第4个字节的内容修改为55了

就充分体现了给联合体其中一个成员赋值,其他成员的值也跟着变化的特点。

在这里插入图片描述

鱼式疯言

联合体的主要特点用大白话来说就是:

同空间,互影响,可改变。

<3>.联合体大小

重要的提前说

• 联合的大小至少是最大成员的大小。

• 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

证明过程如下

#include <stdio.h>
union Un1
{int i;char c;};
union Un2
{short c[7];int i;
};
int main()
{//下面输出的结果是什么?printf("%d\n", sizeof(union Un1));printf("%d\n", sizeof(union Un2));return 0;
}

在这里插入图片描述

在这里插入图片描述

联合体的大小又谁决定,肯定是由最大的那块数据类型决定,

但我们前提是的至少哦

如果超过了怎么办,我们就必须想结构体一样,利用内存对齐来分配我们的空间大小。

什么! ! !
小爱同学说没有看过我写的结构体内存对齐
那小编就把对应标题链接粘贴在这帮助各位友友一起理解哦 💖 💖 💖
《来 ! 来 ! 来 ! 瞧瞧伏地魔大哥是怎么看C语言结构体的 ! ! !》 http://t.csdnimg.cn/XL9n2

鱼式疯言

最大成员是对齐数的整数倍时,整体就是最大内存

不是的话,就要和结构体对齐一样办,整体内存就是对齐后的内存

是不是有小伙伴就疑惑了,我们结构体和联合体的区别在哪呢 🤔 🤔 🤔

好学的友友们请看下个小标题哦,精彩马上呈现 💖 💖 💖

<4>. 联合体与结构体的对比

#include<stdio.h>
//定义结构体类型
struct S
{char c;int i;
};//定义联合体类型
union Un
{char c;int i;
};int main()
{//计算各种大小printf("%zd\n", sizeof(struct S));printf("%zd\n", sizeof(union Un));return 0;
}

在这里插入图片描述
在这里插入图片描述
有图有真相

鱼式疯言

简而言之,言而简之。

我们的结构体成员不会互相影响,但占内存

我们的联合体会互相影响,但不占内存

<5>. 联合体的实际运用

栗子 一:

使用联合体是可以节省空间的,举例:
比如,我们要搞一个活动,要上线一个礼品兑换单,礼品兑换单中有三种商品:图书、杯子、衬衫。
每一种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。
图书:书名、作者、页数
杯子:设计
衬衫:设计、可选颜色、可选尺寸
那我们不耐心思考,直接写出一下结构:

//第一种结构体分布
//定义一个结构体礼物
struct gift_list1
{//相同的属性//库存量int nums;//价格float prize;//商品类型char type[20];//书名char bookname[30];//作者char autor[20];//页数int num_book;//设计char dec[50];//颜色char color[20];//大小int sizes;
};

如果我们插入联合体的把不同的结构体属性联合起来就可以节省我们的内存

神奇的代码一:

//第二种插入联合体的结构体分布
//定义一个结构体礼物
struct gift_list2
{//相同的属性//库存量int nums;//价格float prize;//商品类型char type[20];//将不同属性的也联合起来union pu{struct book{//书名char bookname[30];//作者char autor[20];//页数int num_book;};struct cup{//设计char dec[50];};struct shirt{//设计char dec[50];//颜色char color[20];//大小int sizes;};};};

栗子二:

如何判断大小端存储 ? ? ?
假如小爱同学没学联合体之前,肯定会这样写代码
小编说的是假如哦 😁 😁 😁

//判断大小端存储_test
//指针强转法
int conc1(void)
{int a = 1;return *(char*)(&a);
}int main()
{int c1 = conc1();if (c1==1){printf("小端存储\n");}else{printf("大端存储\n");}return 0;
}

在这里插入图片描述
但你今天学了小编写的联合体的介绍,友友们不妨这样写代码吧 💖 💖 💖

//联合体
union MyUnion
{int i;struct MyStruct{char s1;char s2;char s3;char s4;};
};//结构体法
int conc2(void)
{//00 00 00 01 大端存储//01 00 00 00 小端存储union MyUnion a = { 0 };a.i = 1;return a.s1;
}int main()
{int c2 = conc2();if (c2==1){printf("小端存储\n");}else{printf("大端存储\n");}return 0;
}

在这里插入图片描述

在这里插入图片描述
因为 s1 的全部数据 与 i 的前一个字节数据是一致的
所以我们只需要抽离出对应的 s1 即可

鱼式疯言

从中我们看到的联合体本质是联合不同的内存,从中达到节省空间的良效

同时利用公用同一块内存空间的便利,可以有效抽离每个字节的数据

二. 枚举

<1>.枚举的简介

C语言中,枚举是一种用来定义一组具名整数常量的数据类型。枚举类型定义了一系列的枚举常量,也称为 枚举成员。每个枚举常量都有一个对应的整数值,可以在程序中使用这个整数值来表示相应的枚举常量

enum Weekday {MONDAY,    // 0TUESDAY,   // 1WEDNESDAY, // 2THURSDAY,  // 3FRIDAY,    // 4SATURDAY,  // 5SUNDAY     // 6
};

枚举类型的定义使用关键字 “enum”,后面跟着枚举类型的名称,然后是一对花括号 {} ,其中列出枚举常量。每个枚举常量都可以显式地指定一个整数值,如果没有指定,默认从 0 开始递增。

鱼式疯言

从我们的枚举的简介中就可以提炼出很多至关重要的信息

一. 枚举本身是 常量

二. 枚举和结构体,联合体一样都是属于自定义的一种 数据类型

三. 枚举只能常量只能表示的 整数

<2>. 举俩个栗子

栗子 一

//枚举类型的定义
enum MyEnum
{one=1,two,three
};int main()
{int n = 0;scanf("%d", &n);switch (n){case one:printf("one\n");break;case two:printf("two\n");break;	case three:printf("three\n");break;}return 0;
}

在这里插入图片描述
我们可以用这些枚举常量来替换我们case的整数值,以此来增加代码的可读性

鱼式疯言

枚举常量与普通常量之间可以替换

爱提问的小爱同学就要问了,为啥好像用 #define 宏定义枚举常量也是可以的哦 ! ! !
但我们为啥要用枚举呢,这个问题小爱同学问的很好啊。那我们来试试宏定义的效果如何吧 💕 💕 💕

//宏定义的常量
#define one 1
#define two 2
#define three 3int main()
{int n = 0;scanf("%d", &n);switch (n){case one:printf("one\n");break;case two:printf("two\n");break;	case three:printf("three\n");break;}return 0;
}

在这里插入图片描述
哇塞,没想到效果一样嘞 😲 😲 😲
小爱同学又有疑问了 ? ? ?

那居然效果一样,我们是该用 宏定义 还是用 枚举

居然我们有 宏定义 了,为啥还需要 枚举 呢?

是不是 枚举 有比 宏定义 更有优势的地方呢 ?

这些问题呢,我们小编都会 一 一 为宝子们解答哦,先别着急哦 💖 💖 💖
友友们先看第二栗子哦

栗子二(c++的环境测试)

//枚举定义
enum MyEnum
{one,two,three
};int main()
{int n = 0;scanf("%d", &n);enum MyEnum e = 2;switch (n){case one:printf("one\n");break;case two:printf("two\n");break;	case three:printf("three\n");break;}return 0;
}

在这里插入图片描述
友友们是不是想为啥会报错呢? ? ?
这时聪明的小爱同学就大胆的说出了他的想法:
因为这是枚举类型不能匹配整型类型,就会报错 😁 😁 😁
小编不得不为小爱同学点赞哦,完全正确

没错小编提过枚举类型是也是 数据类型 哦,如果出现类型不匹配就很有可能出现 警告和报错

鱼式疯言

无论是什么枚举类型,联合体类型,结构体类型,温馨提示下友友们都记得类型同一哦 ❤️ ❤️ ❤️

<3>. 枚举类型的与宏定义的差别

在上面的中我们可以明显的看到,枚举有类型检查吧,我们宏定义是没有的呢。
所以小编总结了一下五点

  1. 增加代码的可读性和可维护性
  1. 和#define定义的标识符比较枚举有类型检查,更加严谨。
  1. 便于调试,预处理阶段会删除#define 定义的符号
  1. 使用方便,一次可以定义多个常量
  1. 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用

鱼式疯言

总之枚举的使用可谓是优势俱全啊 💖 💖 💖
但小编的想法是

建议友友们相同类型的常量我们更常用枚举

如果是不同类型的常量我们更常用宏定义来解决呢

总结

在本篇文章中,小编主要带着大家理解了

  • 联合体:熟悉了联合体的定义并知晓了实际的使用场景,还有联合体相比于结构体的优势
  • 枚举:熟悉了枚举如何定义,枚举需要注意的哪些点,以及枚举相比于宏定义的优势

如果觉得小编写的还不错的咱可支持三关下,不妥当的咱评论区指正

希望我的文章能给各位家人们带来哪怕一点点的收获就是 小编创作 的最大动力 💖 💖 💖

在这里插入图片描述

这篇关于没有联合和枚举 , C语言怎么能在江湖混 ?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/685928

相关文章

AI绘图怎么变现?想做点副业的小白必看!

在科技飞速发展的今天,AI绘图作为一种新兴技术,不仅改变了艺术创作的方式,也为创作者提供了多种变现途径。本文将详细探讨几种常见的AI绘图变现方式,帮助创作者更好地利用这一技术实现经济收益。 更多实操教程和AI绘画工具,可以扫描下方,免费获取 定制服务:个性化的创意商机 个性化定制 AI绘图技术能够根据用户需求生成个性化的头像、壁纸、插画等作品。例如,姓氏头像在电商平台上非常受欢迎,

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

豆包 MarsCode 不允许你还没有女朋友

在这个喧嚣的世界里,爱意需要被温柔地唤醒。为心爱的她制作每日一句小工具,就像是一场永不落幕的浪漫仪式,每天都在她的心田播撒爱的种子,让她的每一天都充满甜蜜与期待。 背景 在这个瞬息万变的时代,我们都在寻找那些能让我们慢下来,感受生活美好的瞬间。为了让这份浪漫持久而深刻,我们决定为女朋友定制一个每日一句小工具。这个工具会在她意想不到的时刻,为她呈现一句充满爱意的话语,让她的每一天都充满惊喜和感动

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

怎么让1台电脑共享给7人同时流畅设计

在当今的创意设计与数字内容生产领域,图形工作站以其强大的计算能力、专业的图形处理能力和稳定的系统性能,成为了众多设计师、动画师、视频编辑师等创意工作者的必备工具。 设计团队面临资源有限,比如只有一台高性能电脑时,如何高效地让七人同时流畅地进行设计工作,便成为了一个亟待解决的问题。 一、硬件升级与配置 1.高性能处理器(CPU):选择多核、高线程的处理器,例如Intel的至强系列或AMD的Ry

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return