【C语言】自定义类型:联合和枚举


前言

一、联合体(联合体类型的声明和特点以及联合体大小的计算)
二、枚举类型(枚举类型的声明和优点)


一、联合体

1.联合体类型的声明

联合体类型的定义(声明)如下:

union tag//联合体名
{
   member-list;//成员变量列表
}variable-list;//联合体变量列表

像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以是不同的类型。
但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同⼀块内存空间。所以联合体也叫:共用体。
给联合体其中⼀个成员赋值,其他成员的值也跟着变化。

2.联合体的特点和使用

联合体的成员是共用同⼀块内存空间的,这样⼀个联合变量的大小,至少是最大成员的大小(因为联合体至少得有能力保存最大的那个成员)。因为联合体的成员共用同⼀块内存空间的特性,所以给联合体其中⼀个成员赋值(或改变联合体其中⼀个成员的值),其他成员的值也会跟着变化。

示例如下:

#include <stdio.h>

union Un
{
	char c;
	int i;
};

int main()
{
	union Un un = { 0 };
	un.i = 0x11223344;
	printf("%x\n", un.i);
	un.c = 0x55;
	printf("%x\n", un.i);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

3.联合体大小的计算

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

注:对齐数 = 编译器默认的一个对齐数 与 该成员变量大小的较小值。
(特殊情况:如果该成员变量是数组的话,数组的对齐数 = 编译器默认的一个对齐数 与 该数组中元素的大小的较小值)
-VS 中默认的值为 8
-Linux中 gcc 没有默认对齐数,对齐数就是成员自身的大小

例一:

#include <stdio.h>

union un1
{
 char c[5];
 int i;
};

int main()
{
 printf("union un1的大小 = %zd\n", sizeof(union un1));
 return 0;
}

在这里插入图片描述
联合体的第一个成员变量 c 是一个字符数组。数组的对齐数 = 编译器默认的一个对齐数 与 该数组中元素的大小的较小值。VS编译器中默认的值为 8,而该数组中元素的大小是1字节,比8小,所以数组 c 的对齐数是1
对齐数 = 编译器默认的一个对齐数 与 该成员变量大小的较小值。VS编译器中默认的值为 8,而 i 的大小是4字节,比8小,所以数组 i 的对齐数是4
因为联合体的大小至少是最大成员的大小,所以这个联合体的大小至少是5字节,但是联合体的大小还应该是最大对齐数4(数组 c 的对齐数是1,i的对齐数是4)的整数倍,所以该联合体的实际大小为8字节。

例二:

#include <stdio.h>

union un2
{
 short c[7];
 int i;
};

int main()
{
 printf("union un2的大小 = %zd\n", sizeof(union un2));
 return 0;
}

在这里插入图片描述
联合体的第一个成员变量 c 是一个短整型数组。数组的对齐数 = 编译器默认的一个对齐数 与 该数组中元素的大小的较小值。VS编译器中默认的值为 8,而该数组中元素的大小是2字节,比8小,所以数组 c 的对齐数是2
对齐数 = 编译器默认的一个对齐数 与 该成员变量大小的较小值。VS编译器中默认的值为 8,而 i 的大小是4字节,比8小,所以数组 i 的对齐数是4
因为联合体的大小至少是最大成员的大小,所以这个联合体的大小至少是14字节,但是联合体的大小还应该是最大对齐数4(数组 c 的对齐数是2,i的对齐数是4)的整数倍,所以该联合体的实际大小为16字节。

二、枚举类型

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,当然在声明枚举类型的时候也可以赋初值。
以下示例演示其使用:

例一:

#include <stdio.h>

enum Sex//性别
{
	MALE,
	FEMALE,
	SECRET
};

int main()
{
	printf("%d %d %d\n", MALE, FEMALE, SECRET);
	return 0;
}

在这里插入图片描述
例二:

#include <stdio.h>

enum Sex//性别
{
	MALE = 3,
	FEMALE,
	SECRET
};

int main()
{
	printf("%d %d %d\n", MALE, FEMALE, SECRET);
	return 0;
}

在这里插入图片描述
例三:

#include <stdio.h>

enum Sex//性别
{
	MALE = 3,
	FEMALE = 0,
	SECRET
};

int main()
{
	printf("%d %d %d\n", MALE, FEMALE, SECRET);
	return 0;
}

在这里插入图片描述

2.枚举类型的优点

我们可以使用 #define(一种预处理指令) 定义常量,为什么非要使用枚举?
枚举的优点:
(1)增加代码的可读性和可维护性
(2)和#define定义的标识符比较枚举有类型检查,更加严谨。
(3)便于调试,预处理阶段会删除 #define 定义的符号
(4)使用方便,一次可以定义多个常量
(5)枚举常量是遵循作用域规则的,如果枚举声明在函数内,就只能在函数内使用


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值