这篇文章总结一下c语言中的联合体和枚举。看看这两个东西到底是什么。大家一起学习。
文章目录
- 一、联合体
- 1.联合体类型的声明。
- 2.联合体的大小。
- 3.相同成员的结构体和联合体对比
- 4.联合体大小的计算。
- 二、枚举类型
- 1.枚举类型的声明。
- 2.枚举类型的优点。
- 枚举类型的使用。
一、联合体
1.联合体类型的声明。
像结构体一样,联合体也是由一个或者多个成员构成,这些成员可以是不同的类型。但是编译器只为最大的成员分配足够的空间。联合体的特点是所有成员共用一块内存空间。所以也叫:共用体。给联合体赋值,其他成员的值也会跟着变化。
#include <stdio.h>
//联合类型的声明
union Un
{
char c;
int i;
};
int main()
{
//联合变量的定义
union Un un = {0};
//计算连个变量的⼤⼩
printf("%d\n", sizeof(un));
return 0;
};
输出结果为4。
char c 和int i共同处于一个空间当中,字节长度为最大的int类型占四个字节。
2.联合体的大小。
联合的成员是共用同一块内存空间的,这样的一个联合变量的大小至少是最大成员的大小。(联合至少得有能力保存最大的那个成员)。
#include <stdio.h>
//联合类型的声明
union Un
{
char c;
int i;
};
int main()
{
//联合变量的定义
union Un un = {0};
// 下⾯输出的结果是⼀样的吗?
printf("%p\n", &(un.i));
printf("%p\n", &(un.c));
printf("%p\n", &un);
return 0;
}
根据图片可以看出这个代码输出的三个地址一摸一样。
//
代码
2
#include <stdio.h>
//联合类型的声明
union Un
{
char c;
int i;
};
int main()
{
//联合变量的定义
union Un un = {0};
un.i = 0x11223344;
un.c = 0x55;
printf("%x\n", un.i);
return 0;
}
这个代码输出后第四个字节的位置变成了55。下面画一个图解释。
因为是联合体,联合体共用一块内存空间。int 类型占四个字节,char类型占一个字节。un.c是char的首地址替换了un.i的首地址。
3.相同成员的结构体和联合体对比
//结构体
struct S
{
char c;
int i;
};
struct S s={0};
//联合体
union Un
{
char c;
int i;
};
union Un un={0};
结构体和联合体在内存中储存方式是不一样的。
这是结构体所占的内存。
这是联合体所占的内存。
4.联合体大小的计算。
- 联合的大小至少是最大成员的大小。
- 当最大成员大小不是最大对齐数的整倍数的时候,就要对齐到最大对齐数的整倍数。
#include <stdio.h>
union Un1
{
char c[5];
int i;
};
union Un2
{
short c[7];
int i;
};
int main()
{
//下⾯输出的结果是什么?
printf("%d\n", sizeof(union Un1));
printf("%d\n", sizeof(union Un2));
return 0;
}
输出结果是8和16。
Un1因为联合的大小最少是最大成员的大小,char c[5]是5个字节,但是因为当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍数,所以最大对齐数必须是4的整倍数为8。
Un2 short[7]是14个字节,最大成员的大小是14,此时最大成员大小不是最大对齐数的整倍数对齐到最大对齐数的整倍数,最大对齐数必须是4的整倍数是16。
根据上面所讲内容可以看出联合体是可以节省空间的。
⽐如,我们要搞⼀个活动,要上线⼀个礼品兑换单,礼品兑换单中有三种商品:图书、杯⼦、衬衫。
每⼀种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。
- 图书:书名、作者、⻚数
- 杯⼦:设计
- 衬衫:设计、可选颜⾊、可选尺⼨
如果单纯用结构体
struct gift_list
{
//公共属性
int stock_number;//库存量
double price; //定价
int item_type;//商品类型
//特殊属性
char title[20];//书名
char author[20];//作者
int num_pages;//⻚数
char design[30];//设计
int colors;//颜⾊
int sizes;//尺⼨
};
上面的结构的设计包含了所有礼品的各种属性。这样使得结构体的大小就会偏大,浪费内存。对于礼品兑换单中的商品,只有部分属性信息是常用的。其实可以把公共属性单独写出来,剩余属性用联合体,这样就可以节省一部分内存。
struct gift_list
{
int stock_number;//库存量
double price; //定价
int item_type;//商品类型
union {
struct
{
char title[20];//书名
char author[20];//作者
int num_pages;//⻚数
}book;
struct
{
char design[30];//设计
}mug;
struct
{
char design[30];//设计
int colors;//颜⾊
int sizes;//尺⼨
}shirt;
}item;
};
二、枚举类型
1.枚举类型的声明。
枚举顾名思义就是⼀⼀列举。
把可能的取值⼀⼀列举。
在我们现实生活中:
- ⼀周的星期⼀到星期⽇是有限的7天,可以⼀⼀列举
- 性别有:男、⼥、保密,也可以⼀⼀列举
- ⽉份有12个⽉,也可以⼀⼀列举
- 三原⾊,也是可以意义列举
enum Day//星期
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
enum Sex//性别
{
MALE,
FEMALE,
SECRET
}
;
enum Color//颜⾊
{
RED,
GREEN,
BLUE
};
上面定义的enum Day ,enum Sex ,enum Color都是枚举类型。
{ }中的内容是枚举类型的可能取值,也叫枚举常量。
这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。
2.枚举类型的优点。
我们可以使⽤#define 定义常量,为什么⾮要使⽤枚举?
枚举的优点:
- 增加代码的可读性和可维护性
- 和#define定义的标识符⽐较枚举有类型检查,更加严谨。
- 便于调试,预处理阶段会删除#define 定义的符号
- 使⽤⽅便,⼀次可以定义多个常量
- 枚举常量是遵循作⽤域规则的,枚举声明在函数内,只能在函数内使⽤
枚举类型的使用。
enum Color//颜⾊
{
RED=1,
GREEN=2,
BLUE=4
};
enum Color clr = GREEN;//使⽤枚举常量给枚举变量赋值
那是否可以拿整数给枚举变量赋值呢?在C语⾔中是可以的,但是在C++是不⾏的,C++的类型检查⽐较严格。
到这里联合体和枚举的总结就结束了,谢谢大家观看。