当前位置: 首页 > news >正文

自定义类型:联合与枚举

联合体

联合体类型的声明

联合体和结构体一样,都是由一个或是多个成员组成,也可以放置不同类型,关键字为union

union un
{char i;int c;
};

不过和结构体不同的是,联合体只会为最大的结构体成员分配足够的内存空间,联合体的特点是所有的成员都共用一个空间,所以又叫共用体

union un
{char i;int c;
};
int main()
{union un u = { 0 };printf("%zd\n", sizeof(union un));return 0;
}

我们来看看这个联合体长度是多少

四个位元,这正好验证了上述的话,那么只有4个空间,那么 i 去哪里了?我放到下面说

我们先将它们的地址打印出来

union un
{char i;int c;
};
int main()
{union un u = { 0 };printf("%zd\n", sizeof(union un));printf("%p\n", &u);printf("%p\n", &(u.i));printf("%p\n", &(u.c));return 0;
}

运行结果:

我们发现三个所在地址一样,我们画个图

当存储c是i会被覆盖,所以i和c是共用一个空间的

联合体的特点

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小,再补充一点:在联合内如果有成员被改变,那么其他成员也会被改变

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

这里原本存储的是 44 33 22 11

当我再走下去时变成了 55 33 22 11

因此得知当一个成员被改变时其他的成员也会变动

相同成员的结构体和联合体对比

我们来对比结构体和联合体的区别在哪?

我们先在两个不同的地方定义两个同样的成员

结构体:

struct S
{char a;int b;
};

联合体:

union un
{char a;int b;
};

我们先看输出分别是多少:

分别为8和4,再看它在的成员偏移量

结构体:

联合体:

将成员偏移量的图画出来

我们看到结构体有可能会造成空间浪费,而联合体可以节省空间

联合体大小的计算

联合的大小至少是最大成员的大小

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

我们先将代码写出来

union Un1
{char c[5];int i;
};union Un2
{short c[7];int i;
};int main()
{printf("%zd\n", sizeof(union Un1));printf("%zd\n", sizeof(union Un2));return 0;
}

我们先计算所需要的空间

所以输出为8和16,我们打印看看

我们发现联合体和结构体一样都会有对齐现象

在结构体和联合体的对比中我们知道联合体可以节省空间,假如我需要上线一个"礼品兑换清单",礼品中有三样商品:书籍  衬衫  杯子,每个商品都会有价格 库存量和商品类型,当然还有其他的的特殊类型

我们先直接写出一个商品清单的结构体

struct li_wu_qing_dan
{int ku_cun_liang;double jia_ge;char shang_pin_lei_xing[50];char shu_ming[20];char zuo_zhe[20];unsigned int ye_shu;char she_ji[20];int yan_se;int chi_cun;
};

我们当然也可以直接使用这个结构体,可是这样会造成内存空间不必要的浪费,那该怎么做呢?

我们先将这三样商品的共同属性提取出来,在使用联合体将商品个别的属性储存起来,这样可以节省空间

struct li_wu_qing_dan
{int ku_cun_liang;double jia_ge;char shang_pin_lei_xing[50];union{struct {char shu_ming[20];char chu_ban_she[20];int ye_shu;}book;struct {char she_ji[20];char yan_se;int chi_cun;}cup;struct {char yan_se;}shirt;}item;
};

联合的一个练习

写一个程序,判断当前机器是大端?还是小端?

union un
{char c;int i;
}un;
int main()
{union un un;un.i = 1;if (un.i == 1)printf("小端");elseprintf("大端");
}

我们先调试看看

我们看到是倒着存的,我们前面在数据在内存中的存储方式提到过大端和小端的存储方式

小端的存储模式为低位数在内存的高位地址处,高位字节在内存的高地址处,大端则是低位数在高位的地址处,高位数在地址的低位地址处,我们调试的截图位小端存储模式,所以输出为小端

我们也可以将它写成一个函数再进行判断

int chick_sys()
{union un{char c;int i;}un;union un un;un.i = 1;if (un.i == 1)return 1;elsereturn 0;
}
int main()
{if ((chick_sys) == 1)printf("小端");elseprintf("大端");
}

甚至可以直接返回un.i

int chick_sys()
{union un{char c;int i;}un;union un un;un.i = 1;return un.i;
}
int main()
{if ((chick_sys) == 1)printf("小端");elseprintf("大端");
}

枚举类型

枚举类型的声明

枚举就是将可能的取值一一列举出来

例如:一周有七天

性别有 男 女 和保密

三原色有 红 黄 蓝

这些都是可以列举的

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开始,我们将它打印出来

enum Color
{RED,GREEN,BLUE
};int main()
{printf("%d\n", RED);printf("%d\n", GREEN);printf("%d\n", BLUE);return 0;
}

也可以在声明枚举类型是进行赋值

enum Color
{RED = 2,GREEN = 4,BLUE = 8
};int main()
{printf("%d\n", RED);printf("%d\n", GREEN);printf("%d\n", BLUE);return 0;
}

枚举类型的优点

为什么要使用枚举?

不是#define也可以定义常量吗,为什么非要用枚举呢?\

下列是优点:

1.增加代码的可读性

2.和#define相比枚举有类型检查,更加严谨

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

4.使用方便,可以定义多个常量

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

枚举类型的使用

前面也说了如何使用枚举,先创建枚举常量再给枚举变量赋值

enum Color
{RED = 2,GREEN = 4,BLUE = 8
};
int main()
{enum Color c = 4;return 0;
}

那么是否可以拿整数给变量赋值呢,C语言可以

但是在C++中会报错

http://www.dtcms.com/a/465413.html

相关文章:

  • Java9
  • 基于Spring Boot + Vue 3的乡村振兴综合服务平台
  • Java-145 深入浅出 MongoDB 基本操作详解:数据库查看、切换、创建集合与删除完整教程
  • disable-devtool 网络安全 禁止打开控制台
  • TCP协议的可靠性保障
  • ktv支付订房网站模板商业策划书范文6篇
  • 十一、OpenCV中图形的绘制
  • 用户中心网站设计北京社保网址
  • 安卓13_ROM修改定制化-----如何给安卓手机里安装或者内置数字证书文件 cer类型的证书文件如何转换为可内置文件
  • 仿mudou——Connection模块(连接管理)
  • vue3 + el-upload组件集成阿里云视频点播从本地上传至点播存储
  • 外贸网站是用什么软件做的法制教育网站
  • c/c++字符串比较
  • 国外建站公司上海企业自助建站系统
  • AI 生产工艺参数优化:中小型制造企业用 “智能调参“ 提升产品合格率与生产效率
  • 《Linux基础入门指令》:从零开始理解Linux系统
  • NVIDIA HGX H100 GPU 服务器现已在 DigitalOcean 欧洲数据中心上线
  • 工程师招聘网站住建局网站官网
  • SAP-ABAP:SAP中的用户确认对话框:深入理解与实践POPUP_TO_CONFIRM
  • 购物网站上分期怎么做的广东移动手机营业厅网站
  • 云辉泵阀通过订单日记实现流程重构之路
  • 黑马商城微服务项目准备工作并了解什么是微服务、SpringCloud
  • 濮阳市城乡建设管理局网站怎么建网站
  • 腾讯云网站建设教学视频免费行情软件有哪些
  • 电子商务网站建设技术解决方案别人给公司做的网站字体侵权吗
  • 软考软件设计师常考知识点:(三)数据结构
  • 双向链表----“双轨联动,高效运行” (第九讲)
  • CEX-DEX 稳定币套利模型
  • 【C++STL :list类 (一) 】C++98 完全指南:std::list 详解与源码剖析
  • shell脚本02