服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言关于自定义数据类型之枚举和联合体详解

C语言关于自定义数据类型之枚举和联合体详解

2022-02-28 14:59Ersansui C/C++

枚举顾名思义就是把所有的可能性列举出来,像一个星期分为七天我们就可以使用枚举,联合体是由关键字union和标签定义的,和枚举是一样的定义方式,不一样的是,一个联合体只有一块内存空间,什么意思呢,就相当于只开辟最

前言

在C语言的自定义数据类型中,除了我们最为常用的结构体之外,还有两个比较少用的自定义数据类型,分别为枚举和联合体(也可以称为共用体)。

今天,我们一起看学习一下相关的知识吧!

C语言关于自定义数据类型之枚举和联合体详解

枚举

什么是枚举?

顾名思义,就是一一列举,把所有的情况,所有的取值,一一列举出来。

在我们生活中,有不少的东西是可以全部列举出来的。

如一个星期有七天,一年有十二个月,性别有男和女,评价有优秀、良好、及格和不及格等等。

当某些数据的值只有固定的几种可能取值的时候,我们就可以使用枚举类型。

枚举类型的定义

enum 枚举类型名 { 枚举值1 ,枚举值2,… ,枚举值n };

枚举类型的定义和结构体类似,先使用enum这个关键字,后面加上枚举类型的名字,括号内是枚举的值,最后别忘记分号。

还有,最后的一个枚举值后面不需要逗号!

一般定义枚举类型的方法如下:

注意:这是定义枚举类型,而不是定义枚举变量!

例如如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
enum Day//星期
{
    Mon,
    Tues,
    Wed,
    Thur,
    Fri,
    Sat,
    Sun
};
 
 
 
enum Sex//性别
{
    MALE,
    FEMALE,
    SECRET
};
 
 
enum Color//颜色
{
    RED,
    GREEN,
    BLUE
};

此外,还有其他的一些定义的方法。

枚举类型的优点

那么我们来思考一个问题,为什么需要枚举呢?

我们其实可以通过#define的方式来定义常量,那么我们还需要定义枚举吗?

其实是需要的。

在有些情况下,枚举可以让我们的代码更加清晰明了。

比如,我们在需要打印菜单的时候,就需要有不同的选项,那么每一个选项就对应一个值,那么我们可以使用枚举让数值与对应的含义对上号,那么这就可以让我们在实现每一个具体的细节的时候,知道这一种case情况对应的具体含义。

此外,还有别的优点:

  • 防止了命名污染(封装)
  • 便于调试
  • 使用方便,一次可以定义多个常量

枚举类型的使用

通过枚举类型,我们可以定义枚举变量

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
enum Color//颜色
{
    RED,
    GREEN,
    BLUE
};
 
 
//使用方法和其他类型一直,就像int a;一样
enum Color clr;
 
//使用枚举值来给枚举类型赋值
clr = RED;
 
//注意,一般我们给枚举赋值的时候,都用枚举值,而不用其他的值,否则就没有什么意义了

我们一般使用结构体的时候,都像上面的栗子一样。

先创建好枚举的模板,燃用这个模板来创建变量。

此外,还有其他的方法:

创建模板的同时定义枚举变量

?
1
2
3
4
5
6
enum Color//颜色
{
    RED,
    GREEN,
    BLUE
}clr1,clr2;//在最后这里,我们定义了两个枚举变量

省略枚举类型名字,匿名创建枚举变量

?
1
2
3
4
5
6
enum
{
    RED,
    GREEN,
    BLUE
}clr1,clr2;//这里定义了两个枚举变量

上面的两个变量依旧可以使用,只是,我们没有写出该枚举类型的名字,就只能这样来定义变量,以后不能在利用这个模板来创建变量了

使用typedef来给枚举类型重命名

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef enum Color//颜色
{
    RED,
    GREEN,
    BLUE
}cr;//注意,这里的cr是新的枚举类型名字,不是定义的枚举变量
 
 
 
//还可以匿名重命名
 
typedef enum
{
    RED,
    GREEN,
    BLUE
}cr;

枚举中需要注意的点

  • 枚举值只能是整型的数据,如字符、整数等,不能是浮点型
  • 枚举类型变量赋值的时候,一般用枚举值来赋值,不适用其他的数值来赋值
  • 枚举值本身是一个常量,我们可以对枚举变量的值进行修改,但不能对枚举值进行修改
  • 枚举值被处理的时候,会被看成整数数值,因此枚举变量可以算术运算、关系运算等

联合体

联合体类型的定义

union 联合体类型名 { 数据类型 成员名1 , 数据类型 成员名 2 , … , 数据类型 成员名n;};

联合体也叫共用体,这个也是一种特殊的数据类型。

这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间。

栗子如下:

?
1
2
3
4
5
union Un
{
    char c;
    int i;
};

联合体的特点

联合体变量的成员是使用共同的一块空间的。

联合体的大小,至少是成员中最大成员的大小。
(这里的至少我们后面再说)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<stdio.h>
 
union Un
{
    int i;
    char c;
};
union Un un;
 
 
int main() {
 
    // 下面输出的结果是一样的吗?
    printf("%p\n", &un);
    printf("%p\n", &(un.i));
    printf("%p\n", &(un.c));
 
    return 0;
}

运行上面的代码,我们会发现三个地址都相同

C语言关于自定义数据类型之枚举和联合体详解

成员变量i是第一个成员,该地址和联合体的地址相同我们可以理解,c作为第二个成员变量,其地址也是和第一个成员变量的地址相同,那么这就说明,它们确实使用的是同一块空间

联合体的使用

联合体类型定义变量的方法,和结构体、枚举类似,都有多种方法

先创建模板,在定义变量

?
1
2
3
4
5
6
union Un
{
    int i;
    char c;
};
union Un un;

创建模板的同时定义变量

?
1
2
3
4
5
union Un
{
    int i;
    char c;
}un;//此处的un是一个联合体变量

匿名定义联合体变量

?
1
2
3
4
5
union
{
    int i;
    char c;
}un;//此处的un是一个联合体变量

同样的,由于联合体类型名的省略,我们只可以这样来定义变量,后面就再也不能使用该模板来定义变量了

typedef重命名联合体类型名

?
1
2
3
4
5
6
7
8
9
10
11
12
typedef union Un
{
    int i;
    char c;
}un;
 
 
typedef union
{
    int i;
    char c;
}un;

联合体存在内存对齐

上面说到,联合体的大小,至少是最大成员变量的大小。为什么是至少呢?

我们先来看下面的栗子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
union Un
{
    char arr[6];
    short s;
};
 
union Un u;
 
int main() {
 
    // 下面输出的结果是一样的吗?
    printf("%u", sizeof(union Un));
 
    return 0;
}

上面的代码输出的结果为6

如果我们把字符数组的大小改成5,会发现大小还是6

这是因为,联合体中也存在着对齐

上面的栗子中,会认为字符数组的默认对齐数为1,而short的默认对其数位2,但是成员变量的大小会根据数组的大小来计算,而不是根据数组的元素类型。假如你是元素个数为6的字符数组,那么大小就是6,元素个数为5的字符数组,大小就是5,而int、short等数据类型就按照默认的大小来计算。

首先需要联合体的大小至少是最大成员变量的大小。

然后要求大小应该为各个成员变量中,最大对齐数的倍数,如果不是倍数,那么对齐到整数倍处。

这就能说明,为什么上面的代码把字符数组的大小改为5个元素的时候,联合体的大小仍然为6.

结语

今天的分享到这里就结束啦!

由于本人能力有限,难免会有出错的地方,还希望各位能够指出!

希望各位能给我点个赞、点个收藏哦~

谢谢支持!

C语言关于自定义数据类型之枚举和联合体详解

到此这篇关于C语言关于自定义数据类型之枚举和联合体详解的文章就介绍到这了,更多相关C语言 自定义数据类型内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_61021362/article/details/120961494

延伸 · 阅读

精彩推荐
  • C/C++C语言实现电脑关机程序

    C语言实现电脑关机程序

    这篇文章主要为大家详细介绍了C语言实现电脑关机程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    xiaocaidayong8482021-08-20
  • C/C++C/C++经典实例之模拟计算器示例代码

    C/C++经典实例之模拟计算器示例代码

    最近在看到的一个需求,本以为比较简单,但花了不少时间,所以下面这篇文章主要给大家介绍了关于C/C++经典实例之模拟计算器的相关资料,文中通过示...

    jia150610152021-06-07
  • C/C++c++ 单线程实现同时监听多个端口

    c++ 单线程实现同时监听多个端口

    这篇文章主要介绍了c++ 单线程实现同时监听多个端口的方法,帮助大家更好的理解和学习使用c++,感兴趣的朋友可以了解下...

    源之缘11542021-10-27
  • C/C++学习C++编程的必备软件

    学习C++编程的必备软件

    本文给大家分享的是作者在学习使用C++进行编程的时候所用到的一些常用的软件,这里推荐给大家...

    谢恩铭10102021-05-08
  • C/C++详解c语言中的 strcpy和strncpy字符串函数使用

    详解c语言中的 strcpy和strncpy字符串函数使用

    strcpy 和strcnpy函数是字符串复制函数。接下来通过本文给大家介绍c语言中的strcpy和strncpy字符串函数使用,感兴趣的朋友跟随小编要求看看吧...

    spring-go5642021-07-02
  • C/C++C语言中炫酷的文件操作实例详解

    C语言中炫酷的文件操作实例详解

    内存中的数据都是暂时的,当程序结束时,它们都将丢失,为了永久性的保存大量的数据,C语言提供了对文件的操作,这篇文章主要给大家介绍了关于C语言中文件...

    针眼_6702022-01-24
  • C/C++深入理解goto语句的替代实现方式分析

    深入理解goto语句的替代实现方式分析

    本篇文章是对goto语句的替代实现方式进行了详细的分析介绍,需要的朋友参考下...

    C语言教程网7342020-12-03
  • C/C++C++之重载 重定义与重写用法详解

    C++之重载 重定义与重写用法详解

    这篇文章主要介绍了C++之重载 重定义与重写用法详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...

    青山的青6062022-01-04