文章目录
- 前言
- 联合体
- 概述
- 联合体的特点
- 联合体大小的计算
- 优点
- 练习
- 枚举
- 概述
- 优点
- 使用
前言
在上一篇文章中,小编将结构体的学习笔记整理出来了。现在,小编将枚举和联合体笔记分享给大家。枚举和联合体与结构体一样,都是自定义类型,在学习完枚举和联合体后,C语言中自定义类型也就告一段落啦。
联合体
概述
联合体也是自定义类型,关键字为union,特点是所有成员共⽤同⼀块内存空间,因此,联合体也叫做共用体。
声明
union U
{
char c;
char i;
};
code
#include<stdio.h>
union U
{
char c;
int i;
};
int main()
{
union U u = { 0 };
printf("%d\n", sizeof(u));
return 0;
}
联合体的特点
code
#include<stdio.h>
union U
{
char c;
int i;
};
int main()
{
union U u = { 0 };
printf("%d\n", sizeof(u));
printf("%p\n", &u);
printf("%p\n", &(u.i));
printf("%p\n", &(u.c));
return 0;
}
运行结果
4
008FFADC
008FFADC
008FFADC
分析
i和共用了一个空间,没有给i单独开一个空间,也没有给c单独开一个空间。
因此,这个叫做联合体(共用体)。
编译器只为最⼤的成员分配⾜够的内存空间,起码得保证最大的有空间容下。
code
#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;
}
运行结果
11223355
分析
联合体大小的计算
• 联合的⼤⼩⾄少是最⼤成员的⼤⼩。
• 当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍。
code
#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:
这里,我们第一反应可能认为大小为5,因为c的字节是最大的,为5。
但是我们忽略可第二个规则“当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍。”
这里的c数组是char型,自身大小是1,vs默认对齐数是8,故数组c的大小为1
i是int型,vs默认对齐数是8,故i的大小是4
联合的最大对齐数是4,最大成员是5,显然5不是4的倍数
5后面只有8是4的倍数
因此,输出结果为8
对Un2:
一个short类型是2个字节,现在有7个,那么一共14个字节
联合体中最大成员是14,最大对齐数是4,显然14不是4的倍数
14后面6是4的倍数
因此,输出结果为16
总结:
联合体大小不是最大成员的大小
优点
使用联合体可以节省一定的空间
HAUE某学院学生会需举办活动,要上线⼀个礼品兑换单,礼品兑换单中有三种商品:图书、杯⼦、衬衫。
每⼀种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。
图书:书名、作者、页数
图书:书名、作者、页数
杯子:设计
杯子:设计
衬衫:设计、可选颜色、可选尺寸
衬衫:设计、可选颜色、可选尺寸
结构其实设计的很简单,⽤起来也⽅便,但是结构的设计中包含了所有礼品的各种属性,这样使得结构体的⼤⼩就会偏⼤,⽐较浪费内存。因为对于礼品兑换单中的商品来说,只有部分属性信息是常⽤的。
使用联合体:
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;
};
虽然写起来有点麻烦,但是节省了一定的空间
练习
用联合体写⼀个程序,判断当前机器是⼤端?还是⼩端?
union Un
{
char c;
int i;
};
int main()
{
union Un un;
un.i = 1;
if (un.c == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
枚举
概述
枚举,顾名思义,列举
将有限个,一 一列举出来,这就是枚举类型
声明
enum Day//星期
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
enum Sex//性别
{
MALE,
FEMALE,
SECRET
};
这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。
enum Sex//性别
{
MALE=3,
FEMALE=5,
SECRET=7
};
优点
- 增加代码的可读性和可维护性
- 和#define定义的标识符⽐较枚举有类型检查,更加严谨。
- 便于调试,预处理阶段会删除 #define 定义的符号
- 使⽤⽅便,⼀次可以定义多个常量
- 枚举常量是遵循作⽤域规则的,枚举声明在函数内,只能在函数内使⽤
使用
enum Color//颜色
{
RED=1,
GREEN=2,
BLUE=4
};
enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
clr = 5;//避免这样写
可以拿整数给枚举变量赋值呢?
在C语⾔中是可以的,但是在C++是不⾏的,C++的类型检查⽐较严格。