C语言学习系列->联合体and枚举

文章目录

  • 前言
  • 联合体
    • 概述
    • 联合体的特点
    • 联合体大小的计算
    • 优点
    • 练习
  • 枚举
    • 概述
    • 优点
    • 使用

前言

在上一篇文章中,小编将结构体的学习笔记整理出来了。现在,小编将枚举和联合体笔记分享给大家。枚举和联合体与结构体一样,都是自定义类型,在学习完枚举和联合体后,C语言中自定义类型也就告一段落啦。

联合体

概述

联合体也是自定义类型,关键字为union,特点是所有成员共⽤同⼀块内存空间,因此,联合体也叫做共用体。

声明

union U
{
	char c;
	char i;
};

code

#include

union U
{
	char c;
	int i;
};

int main()
{
	union U u = { 0 };
	printf("%d\n", sizeof(u));
	return 0;
}

联合体的特点

code

#include

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

分析

C语言学习系列->联合体and枚举_第1张图片

i和共用了一个空间,没有给i单独开一个空间,也没有给c单独开一个空间。

因此,这个叫做联合体(共用体)。

编译器只为最⼤的成员分配⾜够的内存空间,起码得保证最大的有空间容下。


code

#include 
//联合类型的声明
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

分析

C语言学习系列->联合体and枚举_第2张图片

C语言学习系列->联合体and枚举_第3张图片


联合体大小的计算

• 联合的⼤⼩⾄少是最⼤成员的⼤⼩。

• 当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍。

code

#include 
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
};

优点

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

使用

enum Color//颜色
{
 RED=1,
 GREEN=2,
 BLUE=4
};
enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
clr = 5;//避免这样写

可以拿整数给枚举变量赋值呢?
在C语⾔中是可以的,但是在C++是不⾏的,C++的类型检查⽐较严格。

你可能感兴趣的:(C语言学习系列,c语言,学习,java)