新手入门C语言之联合体和枚举

        在上一篇文章中,我们了解到在C语言中,自定义类型有三种,这里我们介绍后两种,联合体和枚举。

一.联合体

1.联合体的声明

        像结构体一样,联合体也是由一个或多个成员构成,这些成员的类型可以是不一样的,与结构体不同的是,编译体只为联合体中最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间,所以联合体也叫:共用体。

        联合体的关键字是union,我们可以举例写出一个联合体的定义与初始化

union Un
{
	char c;//1
	int i;//4
};

int main()
{
	union Un u = {0};

	return 0;
}

2.联合体的特点

        联合的成员是共用同一块内存空间的,他们的首地址是相同的,联合变量的带线啊哦,至少是最大的成员的大小。

        现在,我们来看一下联合体的大小和地址

union Un
{
	char c;//1
	int i;//4
};

int main()
{
	union Un u = {0};
	printf("%zd\n", sizeof(u));//大小为4
	printf("%p\n%p\n%p\n", &u,&u.i,&u.c);

	return 0;
}

        我们会发现,大小为4,而输出地址时三者是相同的。

        既然是这样的,那我们是否可以通过更改c的值,来改变i的值呢?

int main()
{
	union Un u = { 0 };
	u.i = 0x11223344;
	u.c = 0x55;

	return 0;
}

        我们会发现,i的结果发生了变化,变成了0x11223355

       下面,我们来对比结构体和联合体内存布局的情况。

        我们发现,联合体节省了很多的空间。         

        因此,我们清楚了,一般来说,我们在使用某一个联合体的时候,都会使用联合体的一个变量。

3.联合体大小的计算

        联合的大小至少是最大成员的大小,但是,当最大成员的大小不是最大对齐数的整数倍时候,就要对齐到最大对齐数的整数倍

        我们写出如下的代码,进行分析

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

        在这个代码中,最大成员的大小是5,但是联合体的大小并不是5,char类型的对齐数是1,int类型的对齐数是4,因此最大对齐数是4,所以,我们在设计联合体的时候,设计的大小应该是8

        现在,我们再看一个代码来举例一下

        

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

        在这个联合体中,大小是16,一定要注意联合体的大小啊哦是最大对齐数的整数倍

4.联合体的实例

        那么,我们在什么时候会应用到联合体呢?下面给大家举一个实例。

我们要搞⼀个活动,要上线⼀个礼品兑换单,礼品兑换单中有三种商品:图书、杯⼦、衬衫。 每⼀种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。 图书:书名、作者、⻚数 杯⼦:设计 衬衫:设计、可选颜⾊、可选尺⼨

在这里,三种礼品有公共的属性,也有特殊的属性,我们当然可以直接写一个结构体,来进行实践

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

5.联合体判断大小端

在之前,我们已经可以写出一个函数来判断大小端了,那么我们是否可以利用联合体的性质,来写出一个程序呢?

int check_sys()
{
 union
 {
 int i;
 char c;
 }un;
 un.i = 1;
 return un.c;//返回1是⼩端,返回0是⼤端 
}

这样,就可以实现啦。

二.枚举

1.枚举的声明

        枚举实际就是一一列举,比如,我们可以列举一周有七天,性别有男女,月份有十二个月等等。

        现在,我们开始写出枚举的式子吧。

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

enum Color//颜⾊
{
 RED,
 GREEN,
 BLUE
};

        这些都可以表示枚举。

        当然,我们也可以进行创建和初始化。

int main()
{
	enum Color color = RED;
	//RED = 5;//err
	printf("%d\n", RED);
	printf("%d\n", GREEN);
	printf("%d\n", BLUE);

	return 0;
}

        在输出枚举的结果的时候,我们可以发现,如果我们不更改数据,RED代表的就是0,GREEN代表1,依次类推,我们是不能在主函数内进行更改的,这是因为,当枚举创建的时候,就是一个枚举常量,如果我们想更改数据,就必须要在枚举创建的时候赋初始值。

enum Color
{
	//三原色的可能取值,枚举常量
	RED=5,//5
	GREEN,//6
	BLUE//7
};

        当然,也可以这样更改

enum Color
{
	//三原色的可能取值,枚举常量
	RED,//0
	GREEN=5,//5
	BLUE//6
};

 2.枚举的优点

        我们会发现,枚举的内容在#define也可以做到,那么,为什么非要使用枚举呢?

1. 增加代码的可读性和可维护性

        便于书写和维护

2. 和#define定义的标识符⽐较枚举有类型检查,更加严谨。

        在C++中,把枚举单独认为是一种特定的类型,因此,不规范时会报错,使得程序更加严谨。

 3. 便于调试,预处理阶段会删除 #define 定义的符号

        在调试中,不会删除枚举中的内容

4. 使⽤⽅便,⼀次可以定义多个常量

5. 枚举常量是遵循作⽤域规则的,枚举声明在函数内,只能在函数内使⽤

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-03-29 07:18:05       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-29 07:18:05       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-29 07:18:05       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-29 07:18:05       18 阅读

热门阅读

  1. Redis缓存数据库表(列单独缓存)

    2024-03-29 07:18:05       16 阅读
  2. Spring Boot整合Redis

    2024-03-29 07:18:05       16 阅读
  3. 《青少年成长管理2024》 006 “成长需要教育”

    2024-03-29 07:18:05       18 阅读
  4. MyBatis3源码深度解析(二十七)MyBatis整合Spring框架

    2024-03-29 07:18:05       21 阅读
  5. 设计模式的主要分类

    2024-03-29 07:18:05       17 阅读
  6. QT基本数据类型

    2024-03-29 07:18:05       18 阅读
  7. scala05-函数式编程01

    2024-03-29 07:18:05       20 阅读
  8. scala05-函数式编程02

    2024-03-29 07:18:05       20 阅读
  9. ES-LTR粗排模块

    2024-03-29 07:18:05       27 阅读
  10. 使用OpenSSL工具验证证书

    2024-03-29 07:18:05       20 阅读