【C语言】自定义类型:联合和枚举

前言

前面我们学习了一种自定义类型,结构体,现在我们学习另外两种自定义类型,联合 和 枚举

目录

一、联合体

1.  联合体类型的声明

2.  联合体的特点

3.  相同成员联合体和结构体对比

4.  联合体大小的计算

5.  用联合体判断当前机器大小端

二、枚举

1.  枚举类型的声明

2.  枚举类型的优点

3.  枚举类型的使用


正文开始——

一、联合体

1.  联合体类型的声明

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

   #include<stdio.h>
  
   //联合体类型的声明  union是关键字
   union Un
  {
      char c;
      int i;
  };
    
   int main()
  {
     //联合体变量的定义
     union Un un={0};
     //计算联合体变量的大小
     printf("%zd\n",sizeof(un));

   return 0;
  }

2.  联合体类型的特点

联合的成员是共用一块内存空间的(所以联合体也叫共用体),所以联合变量的大小至少是最大成员的大小,因为联合体至少得有能力保存最大的那个成员。

代码 1 及其运行结果

   #include<stdio.h>
   //联合类型的声明
   union Un 
  {
     char c;
     int i;
  };
   
   int main()
 {
   union Un un={0};
   printf("%p\n",&(un.c));
   printf("%p\n",&(un.i));
   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);
    return 0;
  }

图解见下:

i 和 c 共用一块内存空间,所以联合体也叫共用体,同一时间只能使用 i 和 c 中的一个。

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

我们再对比一下相同成员的结构体和联合体的内存布局情况。

  struct S
 {
    char c;
    int i;
 };

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

 union Un un={0};

4.  联合体大小的计算

  • 联合体的大小至少是最大成员的大小。
  • 当最大成员的大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
    #include<stdio.h>
    union Un1
   {
      char c[5];
      int i;
   };
    
    union Un2
   {
     short c[7];
     int i;
   };
 
    int main()
   {
      printf("%zd\n",sizeof(union Un1));
      printf("%zd\n",sizeof(union Un2));
   
      return 0;
   }

计算一个数组的大小,就是这个数组类型大小 * 数组成员个数

【例如】

short [7],2*7=14。

对于 union Un2,我们来计算,首先最大成员的大小是14,最大对齐数为 4,但是14不是最大对齐数的整数倍,那就要对齐到最大对齐数的整数倍,即为16。union Un1同理。

我们发现,对于同样成员的结构体和联合体,联合体有时会占用更少的内存,可以节省空间。

下面我们举个栗子,看看在什么情况下适用联合体。

我们要搞一个活动,要上线一个礼品兑换单,礼品兑换单中有三种商品:图书、杯子、衬衫。每种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。

图书:书名、作者、页数

杯子:设计

衬衫:设计、可选颜色、可选尺寸

以结构体的的方式写

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;       //尺寸
};

这样的结构体设计很简单,用起来也比较方便,但是其中包含了所有的属性,这样就导致结构体的大小就会偏大,浪费内存,并且其中属性并非所有的商品都有。所以我们可以把公共的属性单独写出来,剩余属于各种商品本身的属性使用联合体,这样可以节省内存空间。

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

上面结构体和联合体都是匿名,因为这些类型只会被使用一次。

5.  用联合体判断当前机器大小端  

写一个程序,判断当期机器是大端,还是小端。

int check_sys()
{
    union Un
   {
      char c;
      int i;
   };
   un.i=1;
   return un.c;
}

二、枚举

1.  枚举类型的声明

枚举即列举,把可能取值一一列举出来。

enum Day
{
    Mon;
    Tues;
    Wed;
    Thur;
    Fri;
    Sat;
    Sun;
};

上面定义的 enum Day 是枚举类型。{} 里面的内容是枚举类型的可能取值,也叫 枚举常量

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

enum Color
{
    Blue=3
    Red=4;
    Pink=7;
    Black=9;
};

2.  枚举类型的优点

我们可以使用 #define 定义常量,为什么要使用枚举类型?

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

3.  枚举类型的使用

enum Color
{
    RED=3;
    GREEN=6;
};

enum Color clr = GREEN;  //使用枚举常量给枚举变量赋值

完——

期待我们下一次相遇——

像极了_永彬Ryan.B_高音质在线试听_像极了歌词|歌曲下载_酷狗音乐酷狗音乐为您提供由永彬Ryan.B演唱的高清音质无损像极了mp3在线听,听像极了,只来酷狗音乐!icon-default.png?t=N7T8https://t1.kugou.com/song.html?id=2rsi1cbCPV2

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI Earth应用—— 在线使用sentinel数据VV和VH波段进行水体提取分析(昆明抚仙湖、滇池为例)

AI Earth 本文的主要目的就是对水体进行提取,这里,具体的操作步骤很简单基本上是通过,首页的数据检索,选择需要研究的区域,然后选择工具箱种的水体提取分析即可,剩下的就交给阿里云去处理,结果如下: 这是我所选取的一景影像: 详情 卫星: Sentinel-1 级别: 1 …

利用redis数据库管理代理库爬取cosplay网站-cnblog

爬取cos猎人 数据库管理主要分为4个模块&#xff0c;代理获取模块&#xff0c;代理储存模块&#xff0c;代理测试模块&#xff0c;爬取模块 cos猎人已经倒闭&#xff0c;所以放出爬虫源码 api.py 为爬虫评分提供接口支持 import requests import concurrent.futures import …

dependencyManagement的作用、nacos的学习

使用SpringCloudAlibaba注意各组件的版本适配 SpringCloudAlibaba已经包含了适配的各组件&#xff08;nacos、MQ等&#xff09;的版本号&#xff0c;也是一个版本仲裁者&#xff0c;但是可能已经有了父项目Spring-Boot-Starter-Parent这个版本仲裁者&#xff0c;又不能加多个父…

Mongodb oplog的作用及如何评估和更改保留时间

作者介绍&#xff1a;老苏&#xff0c;10余年DBA工作运维经验&#xff0c;擅长Oracle、MySQL、PG数据库运维&#xff08;如安装迁移&#xff0c;性能优化、故障应急处理等&#xff09; 公众号&#xff1a;老苏畅谈运维 欢迎关注本人公众号&#xff0c;更多精彩与您分享。oplog …

硅纪元视角 | 国内首款鸿蒙人形机器人“夸父”开启应用新篇章

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

景区气象站:守护旅行安全的智能向导

在繁忙的现代社会&#xff0c;人们越来越渴望逃离城市的喧嚣&#xff0c;寻找一处宁静的自然之地放松身心。景区&#xff0c;作为大自然与人类文明交织的瑰宝&#xff0c;吸引了无数游客前来探访。然而&#xff0c;多变的天气往往给游客的旅行带来不确定性。 景区气象站&#x…

Java跳出循环的四种方式

1、continue,break,return continue&#xff1a;跳出当前层循环的当前语句&#xff0c;执行当前层循环的下一条语句。   continue标签 break&#xff1a;跳出当前层循环。 break标签&#xff1a;多层循环时&#xff0c;跳到具体某层循环。 return&#xff1a;结束所有循环…

微观特征轮廓尺寸测量:光学3D轮廓仪、共焦显微镜与台阶仪的应用

随着科技进步&#xff0c;显微测量仪器以满足日益增长的微观尺寸测量需求而不断发展进步。多种高精度测量仪器被用于微观尺寸的测量&#xff0c;其中包括光学3D表面轮廓仪&#xff08;白光干涉仪&#xff09;、共聚焦显微镜和台阶仪。有效评估材料表面的微观结构和形貌&#xf…

如何选择一家适合自己的商城源码?

商城源码的选择取决于多个因素&#xff0c;包括商城的功能需求、稳定性、易用性、可定制性以及价格等。启山智软作为在市场上被广泛认可且表现优异的商城源码提供商&#xff0c;具有以下的特点和优势&#xff1a; 特点①&#xff1a;国内知名的B2B2C开源商城源码系统&#xff…

AI助手崛起:开发者的新伙伴还是未来替代者?

你好&#xff0c;我是三桥君。 自从 ChatGPT 问市以来&#xff0c;AI 将取代开发者的声音不绝于耳&#xff0c;至今还是互联网异常火热的问题。 在软件开发领域&#xff0c;生成式人工智能&#xff08;AIGC&#xff09;正在改变开发者的工作方式。无论是代码生成、错误检测还是…

笔记15:while语句编程练习

练习一&#xff1a; 编写程序&#xff0c;求 2^24^26^2...n^2? -直到累加和大于或等于 10000 为止&#xff0c;输出累加和 -输出累加式中的项数&#xff0c;以及最大的数 n #include<stdio.h> int main() {int sum 0;int i 1;int n 0;while(sum < 10000)//将sum…

Leetcode - 周赛404

目录 一&#xff0c;3200. 三角形的最大高度 二&#xff0c;3201. 找出有效子序列的最大长度 I 三&#xff0c;3202. 找出有效子序列的最大长度 II 四&#xff0c;3203. 合并两棵树后的最小直径 一&#xff0c;3200. 三角形的最大高度 本题直接模拟&#xff0c;分别计算一下…

极简通俗VAE

一、VAE 背景&#xff1a;VAE什么变分自编码器&#xff0c;听起来起名都头大&#xff0c;用大白话告诉你。 把一个复杂图片压缩成两个参数&#xff0c;用这个参数采样再复原。 这个简单的东西是两个参数&#xff0c;均值和方差&#xff0c;用&#xff08;0&#xff0c;1&…

C语言_练习题

求最小公倍数 思路&#xff1a;假设两个数&#xff0c;5和7&#xff0c;那么最小至少也要7吧&#xff0c;所以先假定最小公倍数是两个数之间较大的&#xff0c;然后看7能不能同时整除5和7&#xff0c;不能就加1继续除 int GetLCM(int _num1, int _num2) {int max _num1>_n…

web学习笔记(八十)

目录 1.小程序实现微信一键登录 2. 小程序的授权流程 3.小程序配置vant库 4.小程序配置分包 5.小程序配置独立分包 6.小程序分包预下载 1.小程序实现微信一键登录 要先实现小程序一键登录首先我们需要给按钮设置一个绑定事件&#xff0c;然后在绑定事件内部通过wx.login…

phpexcel导入导出

前言&#xff1a; 如果你到处的excel软件打开有问题&#xff0c;下面有介绍解决办法 导入 1. composer init 初始化 2. 下载phpspreadsheet 这里需要注意php版本&#xff0c;需要大于7.2 composer require phpoffice/phpspreadsheet3. 编写代码 <?php require vendo…

Vue3+.NET6前后端分离式管理后台实战(二十七)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战(二十七)

017-GeoGebra基础篇-微积分函数求解圆弧面积问题

基础篇慢慢的走进尾声&#xff0c;今天给大家带来一个小项目&#xff0c;是关于高中数学微积分部分的展示&#xff0c;这个项目主要包含了函数的介绍、函数与图形绘制的区别、区域函数图像的绘制、积分函数的应用、动态文本的调用、嵌套滑动条的应用等等&#xff0c;以及其他常…

代理模式的实现

1. 引言 1.1 背景 代理模式&#xff08;Proxy Pattern&#xff09;是一种常用的设计模式&#xff0c;它允许通过一个代理对象来控制对另一个对象的访问。在面向对象编程的框架中&#xff0c;代理模式被广泛应用&#xff0c;尤其在Spring框架的AOP&#xff08;面向切面编程&am…

Python的招聘数据分析与可视化管理系统-计算机毕业设计源码55218

摘要 随着互联网的迅速发展&#xff0c;招聘数据在规模和复杂性上呈现爆炸式增长&#xff0c;对数据的深入分析和有效可视化成为招聘决策和招聘管理的重要手段。本论文旨在构建一个基于Python的招聘数据分析与可视化管理系统。 该平台以主流招聘平台为数据源&#xff0c;利用Py…