自定义类型(二):枚举和联合

枚举:顾名思义就是一一列举
比如在我们的日常生活中,一个星期有7天,一年有12个月等等都可以使用枚举来一一列举表示。
枚举类型的定义:

//例1
enum sex
{
    male,   //注意逗号
    female,
    secret  //注意最后一个成员末尾没有逗号
}
//例2
enum Color
{
    red,    //注意逗号
    green,
    blue    //注意最后一个成员末尾没有逗号
};

//这里的enum sex,enum Color都是枚举类型,
//{}中的内容是枚举类型的可能取值,也叫作枚举常量。
//这里的可能取值都是有一个确定的值的,默认为0,依次递增,但是可以更改。

//举例1说明:取值都是有一个确定的值的,默认为0,依次递增
#include<stdio.h>

enum color
{
    RED,
    GREEN,
    BLUE,
    BLACK,
    GRAY,
    WHITE
};

int main()
{
    printf("%d\n",RED);
    printf("%d\n",GREEN);
    printf("%d\n",BLUE);
    printf("%d\n",BLACK);
    printf("%d\n",GRAY);
    printf("%d\n",WHITE);
    return 0;
}
//举例2说明:枚举常量的值可以更改
#include<stdio.h>
enum color
{
    RED = 10,   //赋初值为10
    GREEN,
    BLUE,
    BLACK,
    GRAY,
    WHITE
};
int main()
{
    printf("%d\n",RED);
    printf("%d\n",GREEN);
    printf("%d\n",BLUE);
    printf("%d\n",BLACK);
    printf("%d\n",GRAY);
    printf("%d\n",WHITE);
    return 0;
}

例1结果:
这里写图片描述
例2结果:
这里写图片描述
下面举例说明一下这里通过赋初值改变枚举常量的值其他两种情况,

//情况1
#include<stdio.h>
enum color
{
    RED,   
    GREEN,
    BLUE,
    BLACK = 10,//赋初值为10
    GRAY,
    WHITE
};
int main()
{
    printf("%d\n",RED);
    printf("%d\n",GREEN);
    printf("%d\n",BLUE);
    printf("%d\n",BLACK);
    printf("%d\n",GRAY);
    printf("%d\n",WHITE);
    return 0;
}
//通过结果发现值的变化是从赋初值的成员往后开始变化的(依次递增1)
//如果赋初值的位置不是从第一个成员开始的,那么第一个成员到赋初值的成员
//之间的成员(包括第一个成员,不包括被赋初值的成员)的值依旧是默认从0
//开始,往后依次递增1,直到遇到被赋初值的成员,值开始从初值开始往后递增

//情况2
#include<stdio.h>
enum color
{
    RED = 22,
    GREEN = 33,
    BLUE = 44,
    BLACK = 55,
    GRAY = 66,
    WHITE = 77
};
int main()
{
    printf("%d\n",RED);
    printf("%d\n",GREEN);
    printf("%d\n",BLUE);
    printf("%d\n",BLACK);
    printf("%d\n",GRAY);
    printf("%d\n",WHITE);
    return 0;
}
//由结果可知我们可以给每一个枚举常量都附上一个初值

情况1结果为:
这里写图片描述
情况2结果为:
这里写图片描述
总结: 枚举常量就是整数

枚举的使用

enum Color//颜色
{
    RED=1, 
    GREEN=2, 
    BLUE=4
};
enum Color clr1 = GREEN;
//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
//假如我们使用枚举常量所代表的值赋值
enum Color clr2 = 2;
//虽然二者意义相同,但请试想一周之后,一年之后,或者别人看你的代码时,
//结果可想而知,你或者别人根本就不会明白你的这个数字是什么意思
//这就是所谓的魔鬼数字。

枚举的优点

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

联合(共用体)

联合体特点

1、联合里的所有成员共用同一块空间,所以联合也叫作共用体。
2、联合体的大小至少(要考虑内存对齐)是最大成员的大小。因为联合至少得有能力保存最大的那个成员
3、联合体变量的地址和联合体内的所有成员的地址在数值上是一样的

union un
{
    int i;
    char c;
}x;
int main()
{
    printf("%lu\n",sizeof(x));//该联合体的大小
    printf("%p\n",&x);//联合体的地址
    printf("%p\n",&x.i);//联合体中的成员i的地址
    printf("%p\n",&x.c);//联合体中的成员c的地址
}

根据结果可以发现:联合体的大小至少是最大成员的大小;联合体变量的地址和联合体内所有成员的地址在数值上是一样的。
结果为:
这里写图片描述

联合体内存对齐

联合的大小至少是最大成员的大小。
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

举例说明:

//联合0的最大对齐数为4
union un0
{
    char a[5];
    int i;
}x0;
//联合1的最大对齐数为2
union un1
{
    char a[5];
    short i;
}x1;
//联合2的最大对齐数为1
union un2
{
    char a[5];
    char i;
}x2;

int main()
{
    printf("%lu\n",sizeof(x0));//联合0的大小(8)
    printf("%lu\n",sizeof(x1));//联合1的大小(6)
    printf("%lu\n",sizeof(x2));//联合2的大小(5)
}
//解析:
//联合0至少为5个字节,但5不是最大对齐数4的倍数,
//因此联合0的大小需为4的倍数就是8,
//联合1至少为5个字节,但5不是最大对齐数2的倍数,
//因此联合0的大小需为2的倍数就是6,
//联合2至少为5个字节,并且5是最大对齐数1的倍数,
//因此联合0的大小就是5.

结果为:
这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值