资讯专栏INFORMATION COLUMN

【C语言进阶】自定义类型(2)枚举&联合

leiyi / 728人阅读

目录

一、枚举

(一)枚举类型的定义

(二)使用枚举的原因 

(三)枚举的优点 

(四)枚举的大小

(五)枚举的使用

二、联合(共用体)

(一)联合类型的定义

(二)联合的特点

(三)面试题

(四)联合大小的计算



一、枚举

枚举顾名思义就是:列举 。   即把可能的取值一一列举出来

比如我们现实生活中:

  • 一周当中从周一至周日的7天,可以一一列举;
  • 性别有:男、女、保密,可以一一列举;
  • 月份有12个月,可以一一列举;
  • 颜色有赤橙黄绿亲蓝紫等,可以一一列举;
  • ......

(一)枚举类型的定义

这里我们直接上代码:

//枚举类型#include enum Sex//性别{    //枚举的可能取值-常量	MALE = 2,	FEMALE = 4,	SECRET = 8    //以上为给常量赋一个初始值};enum Day//星期{	Mon,	Tues,	Wed,	Thur,	Fri,	Sat,	sun};enum Color//颜色--三原色 RGB{	RED,//0	GREEN,//1	BLUE//2};int main(){    printf("%d %d %d/n", RED, GREEN, BLUE);    printf("%d %d %d/n", MALE, FEMALE, SECRET);    return 0;}

执行结果:

以上定义的 enum Dayenum Sexenum Color 都是枚举类型。 { } 中的内容是枚举类型的可能取值,也叫 枚举常量

这些可能取值都是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值,这些值叫做枚举常量

上文代码中 enum Sex 枚举类型中的值就为枚举常量,其中的常量值为248

(二)使用枚举的原因 

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

#include #define RED 0#define GREEN 1#define BLUE 2int main(){    int color = RED;    return 0;}

(三)枚举的优点 

1.增加代码的可读性和可维护性
2.和#define定义的标识符比较枚举有类型检查,而#define定义的标识符是无类型的,所以更加的严谨。
3.防止了命名污染(封装)
4.便于调试
5.使用方便,一次可以定义多个常量


(四)枚举的大小

enum的大小该如何去求呢?

例:

#include enum Sex{    MALE,    FEMALE,    SECRET};int main(){    enum Sex s = MALE;    printf("%d/n", sizeof(s));    return 0;}

执行结果:

 思考:为什么这里的结果为4呢?


分析:

首先这里 MALE 实际意义上是一个整数,因为他的枚举常量值默认为 0,而 0 是一个整数,这里不管赋值给 FEMALESECRET ,他们的枚举常量值1、2都是一个整数,那么此时s就是一个整形类型的变量值,所以 enum 的值为4

(五)枚举的使用

enum Color//颜色{  RED=1,  GREEN=2,  BLUE=4 }; int main(){    enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。    clr = 5;     return 0;}

 思考:clr = 5可行吗? 


解答:NO! 


原因:

枚举常量和常量值是有区别的,将常量直接赋值给枚举常量类型,编译器会报错或警告 

注:枚举类型的常量如果中间某个值被自定义赋值,那么其前面的值仍然从0开始递增,其后面的值按照自定义的值递增。

总结:枚举是一种类型,可以用来定义变量(枚举变量),但是其成员是常量值(枚举常量)

二、联合(共用体)

(一)联合类型的定义

联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间。(所以联合也叫共用体)

例:

//联合-联合体-共用体#include union Un //共用体类型的声明{    char c;//1    int i;//4};//5个字节int main(){    union Un u;    printf("%d/n", sizeof(u));    printf("%d/n", sizeof(u.c));    printf("%d/n", sizeof(u.i));        printf("%p/n", &u);    printf("%p/n", &(u.c));    printf("%p/n", &(u.i));    return 0;}

执行结果:

分析: 

当然此处第一块空间并不是 u.iu.c 各占一半空间,而是共用了一块空间,u.i 的地址也就和 u.c一样了

(二)联合的特点

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)


(三)面试题:

判断当前计算机的大小端存储

#include check_system(){    union    {        char c;        int i;    }u;    u.i = 1;    //返回1,表示小端    //返回0,表示大端    return u.c;}int main(){    //int a = 0x11 22 33 44;    //低地址——————————————————>高地址    //...[][][][][11][22][33][44][][][][]...  大端字节序存储模式    //...[][][][][44][33][22][11][][][][]...  小端字节序存储模式    //讨论一个数据放在内存中存放的字节顺序(大小端字节序问题)    int a = 1;    int ret = check_system();    if(1 == ret)        printf("小端/n");    else        printf("大端/n");    return 0;}

如果这边对于大小端的内容有所遗忘/不了解的可以到我的另一篇博文中再复习学习一遍哦,链接放在下方 !

【C语言进阶】数据在内存中的存储

(四)联合大小的计算

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

例: 

#include union U1{    int a;//4     char arr[5];//5union U2{    short s[7];//7	int b;//4};int main(){    union U1 u1;    union U2 u2;    printf("%d/n", sizeof(u1));    printf("%d/n", sizeof(u2));    return 0;}

执行结果:

分析:

u1:

数组a为整型,大小为4个字节,他的默认对齐数为8,对齐数是4

而arr是字符数组,其中有5个元素,大小为5 * 1 = 14个字节,他的默认对齐数是8,对齐数是1。

5不是最大对齐数4的倍数,所以浪费3个字节后为8个字节,而对齐到4的倍数后大小为8


u2:

数组s为短整型数组,有7个元素,大小为7 * 2 = 14个字节,他的默认对齐数是16,对齐数是14

数组b为整型,大小为4个字节,默认对齐数就是8,对齐数是4

14不是最大对齐数4的倍数,所以浪费2个字节后为16个字节,对齐到4的倍数后大小为16

总结:结构体、共用体是存在内存对齐的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/119107.html

相关文章

  • C语言进阶】☀️数据类型&&整型在内存中的存储

    目录 ​  一、数据类型介绍 二、类型的意义 三、类型的基本归类 整型家族 浮点数家族 构造类型(自定义类型) 指针类型 空类型 四、整形在内存中的存储 原码、反码、补码 大小端字节序 为什么有大端和小端? 一道经典笔试题  一、数据类型介绍 数据从大的方向分为两类: 内置类型自定义类型内置类型我们前面已经学习过,如下: char            //字符数据类型 short      ...

    Xufc 评论0 收藏0
  • C语言中还有这些类型,别再说你不知道了!手把手带你解锁C语言中的定义类型,让你写你所想。

    摘要:结构体类型的特殊声明在初阶结构体中,我们已经将了结构体类型是如何进行声明的,那么在这里,我们将讲一些特殊的结构体声明不完全的声明。所以我们应该这样写通过指针来找到下一个同类型结构体的写法,我们就称之为结构体的自引用。 ...

    hizengzeng 评论0 收藏0
  • C语言进阶】字符串&内存函数

    摘要:字符串常量适用于那些对它不做修改的字符串函数。同时,语言提供了一系列库函数来对操作字符串,这些库函数都包含在头文件中。目标空间必须足够大,以确保能存放源字符串。拷贝个字符从源字符串到目标空间。 前言:         字符串是一种非常重要的数据类型,但是C语言不存在显式的字符串类型,C...

    pingan8787 评论0 收藏0
  • Python超细腻研究面向对象设计

      面向对象设计是一类编程方式,此编程方式的落地式需要使用类和目标来达到,因此,面向对象设计本身就是对类和目标的应用,今日给大家介绍一下python面向对象设计开发设计及本质特征,感兴趣的小伙伴一起了解一下吧  序言  面向对象设计对新手而言不难理解但无法运用,尽管我们给大家汇总过面向对象战略部署方式(定义类、创建对象、给目标发信息),可是看似简单其实不简单。大量程序编写训练与阅读高质量的编码有可...

    89542767 评论0 收藏0
  • C语言实现简易动态电话簿&&文末提供源代码下载

    摘要:导航前言功能函数结构设定菜单交互主函数通讯录初始化新增联系人查找联系人删除联系人修改联系人查看所有联系人清空所有联系人以名字排序所有联系人结尾语前言本文将实现一个简易的电话簿管理。信息包括名字,性别,电话号码,年龄,住址。 ...

    苏丹 评论0 收藏0

发表评论

0条评论

leiyi

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<