C语言枚举与联合(共用体)
Posted 蓝乐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言枚举与联合(共用体)相关的知识,希望对你有一定的参考价值。
枚举
顾名思义就是一一列举,把可能的取值一一列举。比如现实生活中:
一周从星期一到星期日共七天,可以一一列举;
性别有男,女,保密,可以一一列举;
月份有十二个月,也可以一一列举。
枚举类型的定义
enum Day
{
Mon,
Tues,
Wes,
Thur,
Fri,
Sat,
Sun
};
enum Sex
{
MALE,
FEMALE,
SECRET
};
以上定义的eum Day, eum Sex
都是枚举类型,{}中的内容是枚举类型的可能取值,也叫枚举常量(这些常量是不可更改的)。这些可能取值都是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值。例如:
enum Color
{
RED = 1,
GREEN = 2,
BLUE = 4
};
枚举的优点
为什么使用枚举?
我们可以使用 #define 定义常量,为什么非要使用枚举? 枚举的优点:
- 增加代码的可读性和可维护性
- 和#define定义的标识符比较枚举有类型检查,更加谨慎
#define定义的标识符是没有类型的,由于C语言的源代码会经过预编译,编译,链接到可执行程序几个阶段,在预编译阶段#define定义的标识符不会被替换为其所指的内容,则没有类型的说明,因此没有枚举类型更严谨。 - 防止了命名污染(封装)
枚举成员放在{}内,防止了与别的变量名冲突。 - 便于调试
调试是在可执行程序过程发生的,#define定义的标识符已经被替换为其所指的内容,可能不方便找到错误;而枚举变量认为其成员名,便于调试。 - 使用方便,一次可以定义多个常量
枚举的使用
在使用switch语句时,可以把case后的整型替换成枚举变量可以时代码更据可读性。例如实现一个简易计算器时,我们将各个选项放在枚举类型中,将会大大方便我们的读写代码:
enum Option
{
EXIT,
ADD,
SUB,
MUL,
DIV
};
int main()
{
int input = 0;
do
{
scanf("%d", &input);
int a = 0;
int b = 0;
int ret = 0;
switch (input)
{
case ADD:
scanf("%d %d", &a, &b);
ret = Add(a, b);
break;
case SUB:
scanf("%d %d", &a, &b);
ret = Sub(a, b);
break;
case MUL:
scanf("%d %d", &a, &b);
ret = Mul(a, b);
break;
case DIV:
scanf("%d %d", &a, &b);
ret = Div(a, b);
break;
case EXIT:
break;
default:
printf("请重新选择:\\n");
break;
}
printf("结果是%d\\n", ret);
} while (input);
return 0;
}
枚举类型的大小
下面这个代码的结果是什么呢?
int main()
{
printf("%d\\n", sizeof(enum Sex));
return 0;
}
枚举常量是整型,因此大小是4,也就是说sizeof(enum Sex)
与sizeof(int)
是相等的,但是两者并不是一回事,二者是完全不同的类型
//枚举的使用可以是:
enum Sex s = MALE;
//但不可以是:
enum Sex s = 1;
这是因为enum Sex 类型与 int 类型是不同的。
联合(共用体)
联合类型的定义
联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列成员,特征是这些成员共用同一块空间(所以联合也叫共用体),例如:
//联合类型的声明
union SN
{
char c;
int i;
};
int main()
{
//联合变量的定义
union SN s;
//计算联合变量的大小
printf("%d\\n", sizeof(s));
return 0;
}
程序运行发现联合变量s的大小是4个字节,这说明:
联合的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少的有能力保存那个最大的成员)。
//下面三个语句的结果相同吗?
printf("%p\\n", &s);
printf("%p\\n", &(s.c));
printf("%p\\n", &(s.i));
程序运行的结果也验证了联合的特点,也就是说,联合s的内存分布如下:
那么,利用联合的特点,我们对于之前判断大小端存储模式的方法又多了一种,我们先来回顾一下大小端存储模式,对于int a = 1;
若为小端存储模式,则a在内存中应为01 00 00 00,若为大端存储模式,则a在内存中应为00 00 00 01. 因此,我们可以利用联合的特性,去除整型a的第一个字节,判断其是否为1,进而判断当前机器是大端存储模式还是小端存储模式:
int judge_sys()
{
union UN
{
char c;
int i;
};
union UN u;
u.i = 1;
return u.c;
}
int main()
{
int ret = judge_sys();
if (ret == 1)
{
printf("小端\\n");
}
else
{
printf("大端\\n");
}
return 0;
}
联合大小的计算
- 联合的大小至少是其最大成员的大小。
- 联合也遵循内存对齐规则。比如:
union SNS
{
int i;
char ch[5];
};
int main()
{
printf("%d\\n", sizeof(union SNS));
return 0;
}
联合的最大成员大小为4,数组ch相当于5个字符变量,每个大小均为1,该联合的最大对齐数为4,因此联合的大小应为4的整数倍8.
总结
以上是关于C语言枚举与联合(共用体)的主要内容,如果未能解决你的问题,请参考以下文章