C语言之旅:自定义类型(联合和枚举)

目录

一.联合体

1.1 联合体的声明

1.2 联合体的使用

1.3 为什么输出 4呢?

1.4 相同成员的结构体和联合体对比

1.5 联合体大小对比

1.6使用联合体判断大小端

二.枚举类型

2.1枚举类型的例举:

 2.2枚举类型的优点

2.3 枚举类型的使用


在上篇文章中已经介绍了结构体。另外,C语言还提供了另外两种数据类型——联合体(union)和枚举(enum),它们各自具有独特的功能和用途。本文将带你深入了解联合体和枚举的概念、用法以及它们在实际编程中的应用。

一.联合体

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

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

所以联合体也叫:共⽤体。 给联合体其中⼀个成员赋值,其他成员的值也跟着变化。

1.1 联合体的声明

union Un
{char c;int i;
};

1.2 联合体的使用

#include <stdio.h>
//联合类型的声明 
union Un
{char c;int i;
};
int main()
{//联合变量的定义 union Un un = {0};//计算连个变量的⼤⼩ printf("%d\n", sizeof(un));return 0;
}

输出结果:4

1.3 为什么输出 4呢?

 int类型的大小通常是4个字节(byte)。由于联合体的大小至少足够大以容纳其最大的成员,因此Un联合体的大小至少应该是int类型的大小,所以输出为 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;
}

输出结果:

012FFD0C
012FFD0C
012FFD0C

这段代码输出了三个地址,它们分别是联合体Un的int成员i的地址、char成员c的地址,以及整个联合体变量un的地址。 

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

输出结果:

11223355

 

 un.i赋值0x11223344,这是一个十六进制数,它会被存储在un联合体所分配的内存中。因为int类型通常占用4个字节,所以0x11223344会被完整地存储在这4个字节中。

然后,代码又对un.c赋值0x55。由于un.c和un.i共享同一块内存,这个赋值会覆盖un.i的最低有效字节(即char类型所占用的字节)。

那么,0x55会覆盖0x11223344的最低字节,变成0x11223355

最后,代码打印un.i的值,由于我们已经修改了它的最低字节,所以输出的是11223355。(小端机器)。

1.4 相同成员的结构体和联合体对比

代码示例:

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

1.5 联合体大小对比

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

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

代码示例:

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

输出结果:
8
16

由于 char 数组的大小是5个字节,而 int 通常需要4字节对齐,编译器可能会选择增加1个字节的填充(padding),使得整个 union Un1 的大小为8个字节,以满足 int 的对齐要求。 

short c[7] 需要14个字节,这超过了 int 的4个字节,所以 union Un2 的大小将是14个字节。与 union Un1 类似,由于内存对齐的原因,编译器可能会增加额外的填充。在这种情况下,编译器可能会添加2个字节的填充,使 union Un2 的总大小为16个字节。

使用联合体可以节省空间。

1.6使用联合体判断大小端

代码示例:

#include <stdio.h>    int check_sys()    
{    union    {    int i;    char c[sizeof(int)]; // 使用字符数组以便访问int的各个字节    } un;    un.i = 1; // 设置int为1    // 检查int的最低有效字节(在小端系统中应该是1)    return *(char *)&un.i == 1; // 如果返回true(非零),则是小端系统;如果返回false(零),则是大端系统    
}    int main()    
{    if (check_sys()) {    printf("这是一个小端系统。\n");    } else {    printf("这是一个大端系统。\n");    }    return 0;    
}

二.枚举类型

枚举类型(enum)是一种用户定义的数据类型,枚举(enum)顾名思义就是⼀⼀列举。把可能的取值⼀⼀列举。

2.1枚举类型的例举:

例如:

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

 //星期
enum Weekday 
{  Sunday,  Monday,  Tuesday,  Wednesday,  Thursday,  Friday,  Saturday  
};

性别有:男、女、保密,也可以一一列举 

//性别
enum Sex 
{  Male,  Female,  Cfidntl  
};

 2.2枚举类型的优点

1. 增加代码的可读性和可维护性

2. 和#define定义的标识符⽐较枚举有类型检查,更加严谨。

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

4. 使方便便,一次可以定义多个常量

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

2.3 枚举类型的使用

#include <stdio.h>  enum Color 
{  Red,  Green,  Blue,     
};  int main(){  // 声明一个Color类型的变量  enum Color myColor;  myColor = Red;  switch (myColor) {  case Red:  printf("颜色是红色。\n");  break;  case Green:  printf("颜色是绿色。\n");  break;  case Blue:  printf("颜色是蓝色。\n");  break;  default:  printf("未知的颜色。\n");  break;  }  return 0;  
}

 注意,在C语言中,枚举常量默认从0开始,并且每个后续常量比前一个常量大1。因此,在这个例子中,Red的值为0,Green的值为1,Blue的值为2

当然也以拿整数给枚举变量赋值。在C语⾔中是可以的,但是在C++是不行的,C++的类型检查⽐ 较严格。

代码示例:

enum Color 
{  Red = 1,  Green = 2,  Blue = 3  
};

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

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

相关文章

项目管理—需求管理规程(软件研发过程标准,管理标准,标书技术编写,资质评审,安全管理体系,项目交付,实施运维,各类建设方案)

软件资料清单列表部分文档清单&#xff1a;工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#xff0c;产品需求规格说明书&#xff0c;需求调研计划&#xff0c;用户需求调查单&#xff0c;用户需求说明书&#xff0c;概要设计说明书&#xff0c;技术解…

[智能AI摄像头]RV1126适配3inch mipi屏幕

3寸屏幕 硬件平台 3寸屏&#xff1a;ST7701S驱动芯片&#xff0c;mipi接口&#xff0c;2lane rv1126&#xff1a;易佰纳38板、正点原子rv1126开发板 所需资料 《屏幕规格书》、《开发板原理图》、《屏幕初始化序列》、《ST7701S数据手册》《rk屏幕相关文档》 驱动板绘制 …

大佬复活,暴打空头,两天拉升 180%

GME 暴打空头 大家还记得 2021 年&#xff0c;美国散户大战华尔街的新闻吗&#xff1f; 当时在推特上&#xff0c;几位大佬进行号召&#xff0c;吸引了大量散户往里冲&#xff0c;短短一个月&#xff0c;把一家业绩平平的美股公司「游戏驿站&#xff08;GME&#xff09;」拉升了…

[ROS 系列学习教程] 建模与仿真 - URDF 建模实践

ROS 系列学习教程(总目录) 本文目录 一、机器人结构组成二、新建功能包三、编写launch文件四、创建底盘五、添加轮子六、添加其他部件七、解决部分实体位于地面以下的问题 前文介绍了URDF建模与URDF语法&#xff0c;接下来介绍怎么使用URDF从零构建一个机器人模型并在rviz中显示…

半小时搞懂STM32知识点——UART

1.UART 1.1为什么要使用UART这种协议?介绍一下UART及其特点 成本低&#xff0c;硬件简单&#xff0c;数据格式灵活&#xff1b; 低速全双工异步串行通信 1.2 UART数据帧格式&#xff1f; 起始位&#xff08;1&#xff09;&#xff0b;数据位&#xff08;5-8&#xff09; 校验位…

Sketch总结

sketch禁用了lineGap https://www.sketch.com/docs/designing/text/ http://www.sketchcn.com/sketch-chinese-user-manual.html https://github.com/sketch-hq/sketch-document https://developer.sketch.com/file-format/ https://animaapp.github.io/sketch-web-viewer/ htt…

JAVA云his医院管理系统源码 SaaS模式+融合B/S版电子病历 基于云计算技术开发的云his医院管理系统

JAVA云his医院管理系统源码 SaaS模式融合B/S版电子病历 基于云计算技术开发的云his医院管理系统 定义 美国著名教授Morris.Collen于1988年曾著文为医院信息系统下了如下定义&#xff1a;利用电子计算机和通讯设备&#xff0c;为医院所属各部门提供病人诊疗信息和行政管理信息…

C++二叉搜索树搜索二叉树二叉排序树

C二叉搜索树 1. 二叉搜索树的概念 二叉搜索树&#xff08;BST,Binary Search Tree)&#xff0c;也称为二叉排序树或二叉查找树。它与一般二叉树的区别在于&#xff1a;每个结点必须满足“左孩子大于自己&#xff0c;右孩子小于自己”的规则。在这种规则的约束下&#xff0c;二…

echarts的柱状图使用

1. 柱状图&#xff08;柱体顶部使用外部图片 相关代码 <template><div class"out-bg"><div class"container" ref"warnChartRef"></div></div> </template><script> import * as echarts from echar…

Go微服务: 日志系统ELK核心架构设计

微服务日志系统建设 1 &#xff09;为什么需要日志系统 业务发展越来越庞大&#xff0c;服务器越来越多各种访问日志&#xff0c;应用日志&#xff0c;错误日志量越来越多&#xff0c;无法管理开发人员排查问题&#xff0c;需要到服务器上查日志 2 &#xff09;Elastic Stack…

2024年第十届中西部外语翻译大赛(1)

2024年第十届中西部外语翻译大赛 竞赛信息 “由中西部翻译协会共同体指导发起&#xff0c;各省市译协共建学术指导委员会&#xff0c;2024年第十届中西部外语翻译大赛由中西部翻译协会共同体秘书处&#xff08;武汉公仪网络科技有限公司&#xff09;承办。” - 获奖证书样图 -…

MT3038 植发

思路&#xff1a; 有两个点可以取头发&#xff0c;每个头发寿命不同。 先看点(0,0)&#xff0c;按寿命由小到大排序&#xff08;先考虑寿命短的可以移植到哪里&#xff09;。 (0,0)点头发放置的位置应该让(0,m)点的头发可以尽可能多的放置&#xff08;例如(0,0)点有一根头发…

cmu15445 2023fall project3 详细过程(下)QUERY EXECUTION

QUERY EXECUTION task3/task4 Task #3 - HashJoin Executor and Optimization1、HashJoin1.1 思路1.2 代码 2 NestedLoopJoin优化为HashJoin2.1 思路2.2 代码 Task #4 Sort Limit Executors Top-N Optimization Window Functions1、Sort1.1 思路1.2 代码 2、Limit Executors2…

100m/s高速轧制钢材 八轴测径仪检测毫无压力

关键词&#xff1a;八轴测径仪,在线测径仪,钢材测径仪,高速轧制 随着技术的提升&#xff0c;钢材的生产速度越来越快&#xff0c;一些高速生产的钢材&#xff0c;生产速度甚至达到了100m/s&#xff0c;这是一个非常快的速度。 如果汽车以120公里/小时的速度行驶&#xff0c;那么…

VMware17虚拟机安装Kali Linux2024详解

目录 简介 一、环境搭建 二、下载ISO镜像 三、新建虚拟机 为虚拟机选择合适的操作系统类型和版本 分配适当的内存、硬盘空间和其他虚拟机配置选项 四、硬件配置 编辑虚拟机设置 选择安装介质 五、界面化安装配置 简介 Kali Linux是一个基于Debian的Linux发行版&#…

启明云端ESP32-S3模组WT32-S3选型,Flash最大可选16MB,PSRAM最大可选8MB

使用ESP32-S3单芯片&#xff0c;可以完成语音连接屏控三合一功能。接下来给大家推荐一款ESP32-S3模组WT32-S3&#xff0c;Flash 最大可选 16MB,PSRAM 最大可选 8MB。核心芯片是ESP32-S3。 2.4GHz Wi-Fi(802.11b/g/n)Bluetooth 5(LE)模组&#xff0c;内置ESP32-S3系列芯片&#…

软件工程期末复习(8)需求的表达方法和状态转换图

需求的表达方法 系统模型 需求分析的任务就是借助于当前系统的逻辑模型导出目标系统的逻辑模型&#xff0c;解决目标系统 “做什么” 的问题 通常软件开发项目是要实现目标系统的物理模型。目标系统的具体物理模型是由它的逻辑模型经实例化&#xff0c;即具体到某个业务领域而…

【Linux】常用指令、热键与权限管理

一、常用指令 &#xff08;1&#xff09;ls 功能&#xff1a;列出指定目录下的所有子目录与文件 用法&#xff1a;ls &#xff08;选项&#xff09; &#xff08;目录或文件名&#xff09; 常用选项&#xff1a; -a&#xff1a;列出目录下的所有文件&#xff0c;包括隐藏…

【Redis】Redis面试和工作中十有八九会遇到的问题

1. 数据类型 常用的Redis数据类型有5种&#xff0c;分别是&#xff1a; String、List、Set、SortedSet、Hash 还有一些高级数据类型&#xff0c;比如Bitmap、HyperLogLog、GEO等&#xff0c;其底层都是基于上述5种基本数据类型。因此在Redis的源码中&#xff0c;其实只有5种数…

45°和68°焕新上市,五粮液完成产品体系化布局

执笔 | 尼 奥 编辑 | 扬 灵 如今&#xff0c;白酒行业正经历周期性调整&#xff0c;头部化和品牌化集中趋势日益显著。五粮液在这一关键时刻&#xff0c;敏锐地捕捉到市场机遇&#xff0c;通过产品焕新&#xff0c;进一步完善和丰富了其代际系列产品体系。 这一举措不仅巩…