18、枚举和联合

1. 枚举

一一列举

一周七天

一年四季

一年十二个月

a. 枚举类型的定义
// 枚举类型
enum Season
{
    // 枚举的可能取值--常量
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER
};

注意,枚举类型的取值,用逗号隔开,最后一个后面没有逗号

使用

enum Season s = SPRING;
  • 默认的值是第一个SPRING为0,依次递增1,2,3
  • 有时候可能觉着默认的是0不合适,我们可以写成SPRING = 3, SUMMER = 6,...改成自己想要的值。
  • 对于不赋值的常量,是根据上一个常量递增得到的。比如SPRING = 2,SUMMER,AUTUMN = 8此时的SUMMER的值就是3
b. 枚举的优点

我们也可以使用#define定义常量,那为什么使用枚举呢

  • 增加代码的可读性和可维护性
  • #define定义的标识符比较,枚举有类型检查,更加严谨
    • 比如#define SPRING 0
    • 这里的SPRING就是一个符号,没有类型
    • 而在枚举类里面是有类型的
  • 防止了命名污染(封装)(命名冲突)
  • 便于调试
  • 使用方便,一次可以定义多个常量

2. 联合

a. 联合类型的定义

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

union Un
{
    char c;
    int i;
};
union Un u;
// 计算 u 所占空间的大小
printf("%d\n", sizeof(u)); // 4

// 打印联合体中 u 和其变量地址
// 发现这三个地址值一模一样
printf("%p\n", &u);
printf("%p\n", &(u.c));
printf("%p\n", &(u.i));
b. 联合的特点

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

之前有讲过如何判断当前计算机的大小端存储。

int a = 0x11223344;
// 低地址 --------> 高地址
// 11 22 33 44	 大端存储
// 44 33 22 11   小端存储
// 如何判断大端小端?
int a = 1; // ---> 0x 00 00 00 01 存储到内存
// 如果是 01 00 00 00 就是小端
// 如果是 00 00 00 01 就是大端
// 因此只要判断第一个字节是00 还是 01就行
// 所以只要取到这个地址,向后访问一个字节就行,但是int类型加1是加4个字节,如何取到呢???
// 所以一种办法是将这个 a 强转成字符指针

if (*(char*)&a == 1)
{
    // 小端
}else{
    // 大端
}

另一种实现方式是

union Un
{
    char c; // 1个字节
    int i;  // 4个字节
}
// 我们可以巧妙应用这个结构
// 当往里面给 i 存储 1的时候,查看 c的值就行
u.i = 1;
if (u.c == 0)
{
    // 大端
}else{
    // 小端
}
c. 联合大小的计算
  • 联合的大小至少是最大成员的大小

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

    union Un
    {
        int a; // 4  对齐数是4
        char arr[5]; // 5  对齐数不是按照数组大小,是数组元素大小,对齐数是1
    };
    

    所以这个联合体的大小是4的整数倍!!!又要包含arr[5]这么大的空间,所以结果是8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今儿背单词吗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值