首页 > 其他分享 >自定义类型:联合和枚举

自定义类型:联合和枚举

时间:2024-06-05 21:34:07浏览次数:21  
标签:自定义 int 联合体 union 枚举 un 类型 成绩

自定义类型:联合和枚举

上文我们了解到了对于C语言中没有定义的类型,我们可以用结构体自己重新定义一个适用的类型。那么自定义类型除了结构体还有另外两种自定义类型,分别是联合、枚举

1.联合体类型的声明

像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以是不同的类型。但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。所以联合体也叫:共⽤体
给联合体其中⼀个成员赋值,其他成员的值也跟着变化。

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

我们发现计算的结果如下图所示,不难发现联合体的特点是所有成员共⽤同⼀块内存空间,只为联合体中最大的成员分配足够大的空间。

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

通过代码调试我们发现,联合体中对char c的修改是在int i的第一个字节地址处修改,得出结论:联合的成员是共⽤同⼀块内存空间的。
在这里插入图片描述
在这里插入图片描述
打印结果如下:
在这里插入图片描述

下面我运用图解的方式来理解联合体的特点如下:
在这里插入图片描述

3. 联合体⼤⼩的计算

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

#include <stdio.h>
union Un1
{
 char c[5];//最大成员大小为5,最大对齐数为4,5不是4的整数倍,所以Un1的大小为8
 int i;
};
union Un2
{
 short c[7];//最大成员大小为2*7=14,最大对齐数为4,14不是4的整数倍,所以Un2的大小为16
 int i;
};
int main()
{
 //下⾯输出的结果是什么?
 printf("%d\n", sizeof(union Un1));//8
 printf("%d\n", sizeof(union Un2));//16
 return 0;
}

打印结果如下图所示:
在这里插入图片描述

我们发现联合体的大小计算结果不是最大成员的大小,因为当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍。

4.相同结构体和联合体的对比

//结构体
struct S
{
 char c;
 int i;
};
struct S s = {0};
//联合体
union Un
{
 char c;
 int i;
};
union Un un = {0};

上面的结构体和联合体内存对比图解:
在这里插入图片描述
我们发现联合体会比结构体更加节约内存。

5.联合体的运用

使用联合体是可以节省空间的,举例:
比如,学校有多种课程,
理科生:语文,数学,英语,物理,化学,生物
文科生:语文,数学,英语,政治,历史,地理
职高生:语文,数学,英语,计算机,专业课
那么语文,数学,英语是必选的,是公共属性,我们可以放在结构体中,另外的科目,为特殊属性,我们可以将特殊属性用联合体来存储,节省空间。

struct course
{
 //公共属性
 int Chinese;//语文成绩
 int Maths;//数学成绩
 int English;//英语成绩
 //特殊属性
 int Physics;//物理成绩
 int Chemistry;//化学成绩
 int Biology;//生物成绩
 int Politics;//政治成绩
 int History;//历史成绩
 int Geography;//地理成绩
 int Computer;//计算机成绩
 int Professional course;//专业课成绩
};

这样用结构体存储占用内存过多,我们可以用联合体进行改进,如下:

struct course
{
 //公共属性
 int Chinese;//语文成绩
 int Maths;//数学成绩
 int English;//英语成绩
 //特殊属性
 union{
	struct 
	{
	int Physics;//物理成绩
    int Chemistry;//化学成绩
    int Biology;//生物成绩
    };
	struct
	{
	int Politics;//政治成绩
    int History;//历史成绩
    int Geography;//地理成绩
    };
	struct 
	{
	int Computer;//计算机成绩
    int Professional course;//专业课成绩
    };
      }
};

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

6. 枚举类型的声明

枚举顾名思义就是⼀⼀列举。
把可能的取值⼀⼀列举。
⽐如我们现实⽣活中:
⼀周的星期⼀到星期⽇是有限的7天,可以⼀⼀列举
性别有:男、⼥、保密,也可以⼀⼀列举
⽉份有12个⽉,也可以⼀⼀列举
三原⾊,也是可以一 一列举
这些数据的表⽰就可以使⽤枚举了。

 enum Day//
星期
{
 Mon,
 Tues,
 Wed,
 Thur,
 Fri,
 Sat,
 Sun
};
enum Sex//
性别
{
 MALE,
 FEMALE,
 SECRET
};

以上定义的enum Day ,enum Sex 都是枚举类型。
{}中的内容是枚举类型的可能取值,也叫枚举常量。
这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。

enum Color//
颜⾊
{
 RED=2,
 GREEN=4,
 BLUE=8
};
 

7. 枚举类型的优点

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

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

8. 枚举类型的使⽤

enum Color//
颜⾊
{
 RED=1,
 GREEN=2,
 BLUE=4
 enum Color clr = GREEN;//使⽤枚举常量给枚举变量赋值
};

标签:自定义,int,联合体,union,枚举,un,类型,成绩
From: https://blog.csdn.net/2302_81707171/article/details/139465620

相关文章

  • 存储引擎及特点、约束条件、严格模式、基本字段类型(整型、浮点型、字符串、日期时间
    【一】存储引擎在平常我们处理的文件格式有很多,并且针对不同的文件格式会有对应不同的存储方式和处理机制针对不同的数据应该有对应不同的处理机制存储引擎就是不同的处理机制。#查看所有引擎showengines;四种主要的存储引擎(1)Innodb引擎是MySQL5.5版本之后的默认存......
  • 习题整理《C++17从入门到精通》第二章-变量和基本类型
                                                             //复习用,如有错误,请指正1.下面哪些是不合法的变量标识符?为什么?@ohd      *zara    a2bc    move_name    a_123myname50  _......
  • 习题整理《C++17从入门到精通》第五章-复合类型:数组、指针和引用
                                                            //复习用,如有错误,请指正1.下面程序的输出是什么?#include<iostream>usingnamespacestd;intmain(){intx=10;int&ref=x;......
  • Redis-2-基本数据类型
    1.Redis基础命令命令描述示例KEYS查看符合模板的所有keyKEYSpatternDEL删除一个指定的keyDELkeyEXISTS判断key是否存在EXISTSkeyEXPIRE给一个key设置有效期,有效期到期时该key会被自动删除EXPIREkeysecondsTTL查看一个KEY的剩余有效期TTLke......
  • python用于类型注解的库- typing
    一、简介动态语言的灵活性使其在做一些工具,脚本时非常方便,但是同时也给大型项目的开发带来了一些麻烦。自python3.5开始,PEP484为python引入了类型注解(typehints),虽然在pep3107定义了函数注释(functionannotation)的语法,但仍然故意留下了一些未定义的行为.现在已经拥有许......
  • 面向对象设计方法Review-02.抽象数据类型
    结构化开发方法基本思想:自顶向下,逐步求精,过程抽象,模块化技术概念:结构化程序设计:按照一定的原则与原理,组织编写正确且易读的程序的软件技术。结构化分析设计:数据流图、数据字典、模块结构图。优势:合理性(管理复杂性的有效手段:分解,抽象,层次)、正确性(依据规约,完成任务)程序&......
  • docker自定义仓库
    使用官方镜像创建registry仓库容器: 下载官方registry镜像: #dockerpullregistry  在本地创建registry仓库容器: #mkdir-p/opt/data/registry#dockerrun-idt-p5000:5000--nameregistry-v/opt/data/registry/:/tmp/registryregistry//以上命令会创建一个名......
  • 基本数据类型(整形,浮点型,字符串)
    数据类型(8)int123,456float2.3strstrs='ssssss'#大小写#转小写print(strs.lower())#转大写print(strs.upper())#首字母大写print(strs.title())#大小写互转字符串替换print(strs.replace('world','Tom'))字符串拆分print(strs.split('......
  • Toast自定义
    一、创建布局文件toast.xml<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wra......
  • Python数据类型转换(新)
    目录Python数据类型的转换隐式类型转换显式类型转换Python数据类型的转换数据类型分为1.隐式类型转换2.显式类型转换隐式类型转换在隐式类型转换中,Python会自动将一种数据类型转换为另一种数据类型,不需要认为去干预比如在进行算术运算的时候,较低数据类型(整数)就会......