联合与枚举


  在前面我们对 结构体进行了一个简单的介绍,本章就对 联合与枚举进行探讨。

1. 联合体

1.1 概念

  在进行某些算法的C语言编程的时候,需要使几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构,简称共用体,也叫联合体

联合体与结构体类似,也是由⼀个或者多个成员构成,成员也可以不同的类型,但是编译器只为最大的成员分配足够的内存空间。

1.2 联合体的定义

union 联合名
{
   成员1;
   成员2;
   成员···;
   成员n;
};

  联合体的定义与结构体相同,可参考结构体章节。

1.3 联合体的特点

先观察一段代码:

#include<stdio.h>
struct S   //结构体
{
	int a;
	char b;
};
union U    //联合体
{
	int c;
	char d;
};
int main()
{
	struct S s;
	union U u;
	printf("s=%d\n", sizeof(s));  //计算 s 的大小
	printf("u=%d\n", sizeof(u));  //计算 u 的大小
	return 0;
}

运行结果:

s=8  //不清楚的可以参考上一章(结构体)
u=4  

  最后显示联合体变量 u 的字节大小为 4 ,而整型加上字符型最小也是 5 ,所以联合体成员的存储方式并不是简单的相加。那么接下来就来观察一下成员的地址:
  

#include<stdio.h>
union U    //联合体
{
	int c;
	char d;
};
int main()
{
	union U u;
	printf("u的地址:%p\n", &u);  //计算 u 的大小
	printf("c的地址:%p\n", (&u.c));  //计算成员 c 的大小
	printf("d的地址:%p\n", (&u.d));  //计算成员 d 的大小
	return 0;
}

运行结果:

u的地址:00000035F8F4F784
c的地址:00000035F8F4F784
d的地址:00000035F8F4F784

  可以观察到联合体变量和成员的变量都相同,其实在上面概念中也提到过,所有成员共用同⼀块内存空间,还有重要的一点就是覆盖
  
例(覆盖的表现):

#include<stdio.h>
union U
{
	int a;
	char b;
};
int main()
{
	union U u;
	u.a = 0x11223344;   //赋16进制的值
	u.b = 0x55;         //赋16进制的值
	printf("%x", u.a);  //打印12进制整数
	return 0;
}

运行结果:

11223355

图解:
联合体覆盖

1.4 联合体大小的计算

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

也许用代码会更有说服力:

#include<stdio.h>
union U1
{
	int a;      //4个字节
	char b[5];  //5个字节
};
union U2
{
	int c;      //4个字节
	char d[9];  //9个字节
};
int main()
{
	union U1 u1;
	union U2 u2;
	printf("u1=%d\n", sizeof(u1));
	printf("u2=%d\n", sizeof(u2));
	return 0;
}

运行结果:

u1=8
u2=12

  在 u1 中,对齐数为 4 ,而联合体大小至少是最大成员的大小,同时还要是最大对齐数的整数倍,所以 u1 的大小就是 8 (4 的 2 倍);在 u2 中,数组占了 9 个字节,所以 8 显然是不够了,应扩大到最大对齐数(4)的三倍,也就是 12 。

不了解对齐数的可参考内存对齐规则

2. 枚举

2.1 概念

  枚举是 C 语言中的一种基本数据类型,用于定义一组具有离散值的常量,它可以让数据更简洁,更易读。

枚举类型通常用于为程序中的一组相关的常量取名字,以便于程序的可读性和维护性。

定义一个枚举类型,需要使用 enum 关键字,后面跟着枚举类型的名称,以及用大括号 {} 括起来的一组枚举常量。每个枚举常量可以用一个标识符来表示,也可以为它们指定一个整数值,如果没有指定,那么默认从 0 开始递增。

简单来说就是一 一列举;
比如,一年的月份,周一到周日等

2.2 枚举的定义

enum 枚举名 
{
  枚举元素1;
  枚举元素2;
  ……;
  枚举元素n;
};

2.3 枚举的特点

#include<stdio.h>
enum day  //枚举
{
	MON,
	TUE,
	WED,
	THU,
	FRI,
	SAT,
	SUN
};
int main()
{
	printf("%d %d %d %d %d %d %d", MON, TUE, WED, THU, FRI, SAT, SUN);
	return 0;
}

运行结果:

0 1 2 3 4 5 6

我们可以再次发现如果没有指定整数值,那么默认从 0 开始递增。若为某个常量给定了整数值,那么就从给定了整数值的常量开始向后递增,其之前的则不变。

#include<stdio.h>
enum day
{
	MON,
	TUE,
	WED,
	THU=7,
	FRI,
	SAT,
	SUN
};
int main()
{
	printf("%d %d %d %d %d %d %d", MON, TUE, WED, THU, FRI, SAT, SUN);
	return 0;
}

运行结果:

0 1 2 7 8 9 10

2.4 为什么使用枚举?

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

注意:在 C 语言中,允许给枚举变量赋值。而 C++ 中则不允许此行为。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值