顺德做pc端网站,国际国内时事新闻,wordpress 腾讯云短信,北京开发公司提示#xff1a;文章写完后#xff0c;目录可以自动生成#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、联合体#xff08;一#xff09;、联合体的声明#xff08;二#xff09;、联合体的特点#xff08;三#xff09;、联合体大小的计算#xff01;文章写完后目录可以自动生成如何生成可参考右边的帮助文档 文章目录 前言一、联合体一、联合体的声明二、联合体的特点三、联合体大小的计算四、联合体的小应用 二、枚举一、枚举的类型声明二、枚举的类型优点三、枚举类型的使用 总结 前言
提示这里可以添加本文要记录的大概内容 提示以下是本篇文章正文内容下面案例可供参考 本文主要介绍了C语言中自定义模型的剩下两种类型——联合体和枚举。
一、联合体
一、联合体的声明
联合体的关键字为union,它的声明跟结构体类型联合体也是由一个或者多个成员构成这些成员可以选择不同的类型。但是编译器只为最大的成员分配足够的空间。因为联合体所有的成员共用一块内存空间所有联合体也叫做共用体下面是联合体的一段声明和定义变量的代码
#includestdio.h
union Un
{
char c;
int i;
};
int main()
{
//联合体变量的定义并初始化
union Un un{0};}二、联合体的特点
联合体最大的特点就是联合体的成员共用一块内存空间这样一个联合变量的大小至少是最大成员的大小因为联合体至少得有能力保存最大的那个成员 以代码来验证咱们上面的观点
#includestdio.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;
}运行结果如下 从上面运行结果我们可以看出联合体的成员确实共用一块内存空间因为它们的起始地址都是一样的。
我们给联合体其中一个成员赋值其他成员的值也跟着变化。 #includestdio.h
union Un
{
char c;
int i;
};
int main()
{
union Un un {0};
un.i0x11223344;
un.c0x55;
printf(%x\n,un.i);
}
运行结果如下 我们可以看出我们通过改变结构体成员c的值间接性改变了成员i的值从原来的0x11223344-0x11223355
三、联合体大小的计算
要计算联合体的大小我们要了解以下两条规则 联合体的大小至少是最大成员的大小 当最大成员的大小不是最大对齐数的整数倍的时候就要对齐到最大对齐数的整数倍我们分析一下下面代码中联合体的大小
#include stdio.hunion 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;}运行结果如下 我们从上面特点知道联合体的大小至少是最大成员的大小且必须是成员最大对齐数的整数倍。对于结构体Un1来说最大成员为c它的大小是5个字节而最大对齐数是i的对齐数为4故而应为4的倍数所以我们应该浪费3个字节最终Un1结构体的大小为8个字节对于结构体Un2来说最大成员为c它的大小为14个字节而最大对齐数是i的对齐数为4故而应为4的倍数所以我们应该浪费2个字节最终Un2结构体的大小为8个字节。
四、联合体的小应用
使用联合体可以节省空间 咱们以下面一个例子来说明 比如我们要搞一个活动要上线一个礼品兑换单礼品兑换单中有三种商品图书、杯子、衬衫。 每种商品都有库存量、价格、商品类型和商品类型相关的其他信息例如图书还有的属性书名、作者、页数杯子还有的属性设计衬衫还有的属性设计、可选颜色、可选尺寸。 如果我们不考虑很多的话可以直接粗暴地定义结构体直接将所有属性囊括即可
struct gift_list
{
//公共地属性
int stock_number;//库存量
double price;//定价
int item_type;//商品类型//特殊属性
char title[20];//书名
char author[20];//作者
int num_pages;//页数int design[30];//设计
int colors;//颜色
int sizes;//尺寸
}
这样我们所设置地结构体就涵盖了所有属性要用那块属性地话直接调用即可但是这样简单粗暴地做法就会使得结构体的大小偏大比较浪费内存。因为对于礼品兑换单中的商品来说我们只有部分属性是常用的有几种属性没有用到 例如对于商品是图书来说的话design、colors、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
{
int design[30];//设计
}mug;//杯子的特殊属性
struct
{
int design[30];//设计
int colors;//颜色
int sizes;//尺寸
}shirt;//衬衫的特殊属性
}item;//特殊属性
};联合体可以用来判断机器小大端字节序。 前面我们写的判断大小端字节序的代码为
#includestdio.h
int main()
{int a 1;//0x 00 00 00 01if (*((char*)a) 1){printf(小端\n);}else{printf(大端\n);}
}
而我们可以充分利用联合体的内存分配特点联合体的成员共有一块内存空间修改代码如下
#includestdio.h
union Un
{char c;int i;
};
int main()
{union Un un { 0 };un.i 1;if (un.c 1){printf(小端\n);}else{printf(大端\n);}
}
这样会使得代码更加简单好理解少去了取地址和强转类型的操作。
二、枚举
一、枚举的类型声明
我们都知道枚举顾名思义就是一 一地列举把可能地值一一地给列出来枚举地关键字是enum我们以星期天为例来进行枚举地声明
#includestdio.h
enum Day//星期
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
}D;
int main()
{printf(%d\n,Mon);printf(%d\n,Tues);printf(%d\n,Wed);}运行结果如下 枚举中成员的取值默认从1开始依次递增1当然也可以手动赋值。 以颜色为例
#includestdio.h
enum
{
RED2,
GREEN4,
BLUE8
};
int main()
{
printf(%d\n,RED);
printf(%d\n,GREEN);
printf(%d\n,BLUE);
}运行结果如下
二、枚举的类型优点
我们都知道定义常量的话可以用#define来实现那我们用枚举的优点是什么呢
增加代码的可读性和可维护性和#define定义的标识符相比较枚举具有类型检查更加严谨便于调试预处理阶段会删除#define定义的符号使用方便一次可以定义多个变量枚举变量是遵循作用域规则的枚举声明在函数内只能在函数内使用。
三、枚举类型的使用
咱们以构造一个计算器为例来阐述一下枚举的使用 原先我们设置的计算器为
void meau()
{printf(*****************************\n);printf(****1.ADD 2.SUB ******\n);printf(****3.MUL 4.DIV ******\n);printf(****0.Exit ******\n);printf(*****************************\n);printf(*****************************\n);}
int aDD(int x, int y)
{return x y;
}
int sUB(int x, int y)
{return x - y;
}
int mUL(int x, int y)
{return x * y;
}
int dIV(int x, int y)
{return x / y;
}
int main()
{int input0;int a 0, b 0;do {int result 0;meau();printf(请选择-:\n);scanf(%d, input);printf(请输入要进行操作的两个数\n);scanf(%d %d, a, b);switch (input){case 1:result aDD(a, b);printf(加法的运算结果为%d\n, result);break;case 2:result sUB(a, b);printf(减法的运算结果为%d\n, result);break;case 3:result mUL(a, b);printf(乘法的运算结果为%d\n, result);break;case 4:result dIV(a, b);printf(除法的运算结果为%d\n, result);break;case 0:printf(退出运算\n);exit(-1);break;default:printf(输入错误请重新输入\n);}} while(input);
}我们在switch中还是用数字01234来做选择不太直观。 而利用上枚举类型后我们可以修改代码
#includestdio.h
void meau()
{printf(*****************************\n);printf(****1.ADD 2.SUB ******\n);printf(****3.MUL 4.DIV ******\n);printf(****0.Exit ******\n);printf(*****************************\n);printf(*****************************\n);}
enum Option//更加直观
{Exit,ADD,SUB,MUL,DIV
};int aDD(int x, int y)
{return x y;
}
int sUB(int x, int y)
{return x - y;
}
int mUL(int x, int y)
{return x * y;
}
int dIV(int x, int y)
{return x / y;
}
int main()
{int input0;int a 0, b 0;do {int result 0;meau();printf(请选择-:\n);scanf(%d, input);printf(请输入要进行操作的两个数\n);scanf(%d %d, a, b);switch (input){case ADD:result aDD(a, b);printf(加法的运算结果为%d\n, result);break;case SUB:result sUB(a, b);printf(减法的运算结果为%d\n, result);break;case MUL:result mUL(a, b);printf(乘法的运算结果为%d\n, result);break;case DIV:result dIV(a, b);printf(除法的运算结果为%d\n, result);break;case Exit:printf(退出运算\n);exit(-1);break;default:printf(输入错误请重新输入\n);}} while(input);}
运行结果如下
我们在代码中充分利用了枚举类型这样增加代码的可读性与维护性会让使用者更加直观、清晰明了这就是枚举的重要使用作用。
总结
本文主要介绍了C语言中自定义类型的剩余两种——联合体和枚举类型如有错误请批评指正感谢支持