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

C++联合枚举和类型别名

联合 union

联合是一种特殊的类一个union联合可有多个数据成员 这些数据成员共同使用同一片存储空间(这样的机制目的是节省内存)

1.分配给一个union对象的存储空间至少要能容纳它的最大数据成员

2.union中不能含有引用类型的成员,默认情况下,union的成员都是公有的,这一点和struct相同

3.union既不能继承自其他类,也不能作为基类使用,所以在union中不能含有虚函数

4.为union的一个数据成员赋值时会令其它数据成员变成未定义的状态


 联合
//可以像创建结构一样创建联合
union keywords
{
  unsigned long Birthday;
  unsigned	short ssn;
  const char *pet;
}; 

结构体内变量Birthdayssn*pet共用一块内存的,即&Birthday=&ssn=&pet,且此union联合体所占的内存的长度由联合体中占空间最大的成员决定

所以在keywords这个联合体中,其内存由Birthday决定,所以他们实际存储的值只有一个,即最后赋值的那个,利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间,当访问其内成员时可用.->来直接访问

注意:
const char *pet: 声明了一个指向字符或常量字符串的指针(其中pet所指向的内容不可修改 因为要输入字符串 而char为单字符类型 需要用pet的这个字符串的第一个参数的地址 进行字符串的查找)


联合
keywords key;
key.Birthday = 20000912;// key.Birthday第一次赋值
cout << key.Birthday << endl;//读取正常
key.pet = "wangcai";//key.pet第一次赋值
cout << key.pet << endl;//读取正常
cout << key.Birthday << endl;//再次读取时key.Birthday第一次赋值为无效

结果
在这里插入图片描述

可以看出,由于联合体中的几个成员都使用一个内存所以他们实际存储的值只会是结构体最后赋值的成员的值


枚举 enum

枚举类型(enumeration)是C++中的一种派生数据类型,枚举是用户定义的若干枚举常量的集合

定义格式:枚举类型的定义格式为

enum <类型名> {<枚举常量表>};

关键字enum : 指明其后的标识符是一个枚举类型的名字

枚举常量表 : 由枚举常量构成, “枚举常量” 或称 “枚举成员” ,是以标识符(变量名)形式表示的int整型量,表示枚举类型的取值.枚举常量表用于列出枚举类型的所有取值,各枚举常量之间以,间隔符间隔,且各枚举常量必须各不相同,取值类型与条件表达式相同


例如:

enum weekdays { zero, one, two, three, four };

编译器会按照各个枚举值在定义时出现的先后顺序把他们与0~n~1的整数 分别关联起来(其中n是枚举值的总个数,也就是说枚举值其实是枚举类型中的序号)

枚举的值不需要使用双引号(枚举成员不是字符串,是以标识符形式表示的整型量

:枚举常量只能以标识符形式表示,而不能是整型、字符型等文字常量(标识符的意义相当于变量的变量名)


定义一个枚举类型后 像这样创建该类型的变量

weekdays today;// 声明枚举类型weekdays 变量today
today = one;
cout << "今天星期" << today << endl;//输出值为 1 因为one在枚举类型weekdays中序号为1
today = two;
cout <<"明天星期"<< today << endl;//输出值为 2 因为two在枚举类型weekdays中序号为2
 

运行结果:在这里插入图片描述

注意:🎯

枚举值另外的一个作用是可以作为switch语句的条件case标号


类型别名typedef

typedef是C/C++语言中保留的关键字,用来定义任意一种数据类型的别名,需要注意的是typedef并没有创建新的类型,只是指定了一个类型的别名而已 typedef定义的类型的作用域只在该语句的作用域之内,也就是说如果typedef定义在一个函数体内,那么它的作用域只存在于这个函数体内

typedef符经常使用的场景:

1.指定一个简单的别名,避免了书写过长的类型名称(类似于宏定义)
2.实现一种定长的类型,在跨平台编程的时候尤其重要
3.使用一种方便阅读的单词来作为别名,方便阅读代码

typedef int* IP;//给int类型定义一个别名 名为intpointer 

🔥此行代码定义了IP是一个int类型的指针,也就是说IP的类型是int*(也可以直接定义类型名)

此后每当定义整型指针时,就可以使用IP这个类型名来进行指代定义,例如:

int a = 5;
IP i = &a; //此时intpointer为int整型指针类型
cout << *i;

结果

在这里插入图片描述


完整代码

#include <iostream>

using namespace std;

//todo 联合
//可以像创建结构一样创建联合
union keywords
{
  unsigned long Birthday;
  unsigned	short ssn;
  const char *pet;
  //声明一个指向字符或字符串常量的指针(p所指向的内容不可修改 因为要输入字符串 而char为单字符类型 需要用pet的这个字符串的第一个参数的地址 进行字符串的查找)

 //变量Birthday ssn *pet 是共用一块内存的 即 &Birthday = &ssn= & pet 内存的长度由联合体中占空间最大的成员决定 
 //在keywords这个联合体 内存长度由Birthday决定  所以他们实际存储的值只有一个,即最后赋值的那个
 //利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问

}; 

//todo枚举
//编译器会按照各个枚举值在定义是出现的先后顺序把他们与0~n-1的整数 分别关联起来(n是枚举值的总个数 也就是说枚举值其实是枚举类型中序号)
enum weekdays { zero, one, two, three, four };
//枚举的值不需要使用双引号(枚举成员不是字符串,是以标识符形式表示的整型量 表示枚举类型的取值。枚举常量表列出枚举类型的所有取值,各枚举常量之间以","间隔,且必须各不相同。取值类型与条件表达式相同)
//todo注 :枚举常量只能以标识符形式表示,而不能是整型、字符型等文字常量



int main()
{
	//todo联合
	keywords key;
	key.Birthday = 20000912;
	cout << key.Birthday << endl;
	key.pet = "wangcai";
	cout << key.pet << endl;
	//由于联合体中的几个成员都使用一个内存所以他们实际存储的值只有一个,即最后赋值的那个
	cout << key.Birthday << endl;

	//cout << key.Birthday << endl;//key.pet的第一个元素的首地址

	//todo枚举
	//定义一个枚举类型后 像这样创建该类型的变量
	weekdays today;// 声明枚举类型weekdays 变量today
	today = one;
	cout << "今天星期" << today << endl;//输出值为 1 因为one在枚举类型weekdays中序号为1
 
	today = two;
	cout <<"明天星期"<< today << endl;//输出值为 2 因为two在枚举类型weekdays中序号为2
	//todo枚举值可以作为switch语句的条件case标号
	
	
	//todo类型别名
	typedef int* intpointer;//给int类型定义一个别名 名为intpointer 
	//此后每当定义整型指针时 就可以使用intpointer这个类型名来进行定义
	//这行代码定义了 intpointer是一个int类型的指针,也就是说intpointer的类型是int*(也可以直接定义类型名)



	int a = 5;
	intpointer i = &a; //此时intpointer为int整型指针类型
	cout << *i;

	return 0;
}

运行效果
在这里插入图片描述

相关文章:

  • while循环与中断语句break、continue、return以及goto的使用
  • CentOS使用Screen管理会话选项
  • 循环程序跳出(_kbhit()、getch() 、getchar())
  • C++ 类与对象
  • (转) Android中ViewStub组件使用
  • C++ 构造函数与析构函数
  • MFC应用程序中处理消息的顺序,创建窗口的过程关闭窗口的顺序(非模态窗口),打开模式对话框的函数调用顺序...
  • C++ this指针 与 类的继承
  • OpenGL_Qt学习笔记之_07(闪烁的星星)
  • C++ 继承机制中的构造器与析构器
  • C#数组
  • C++ 访问控制
  • ASA842配置内网DNS欺骗测试
  • C++ 覆盖方法与重载方法
  • Ubuntu 12.04 ping 响应慢
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • JS 面试题总结
  • js作用域和this的理解
  • learning koa2.x
  • mysql 5.6 原生Online DDL解析
  • SSH 免密登录
  • vue-loader 源码解析系列之 selector
  • webpack入门学习手记(二)
  • 阿里研究院入选中国企业智库系统影响力榜
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 浏览器缓存机制分析
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 手机端车牌号码键盘的vue组件
  • 微信小程序填坑清单
  • 一个完整Java Web项目背后的密码
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • (2022 CVPR) Unbiased Teacher v2
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (javascript)再说document.body.scrollTop的使用问题
  • (poj1.2.1)1970(筛选法模拟)
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (二)Linux——Linux常用指令
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .NET CLR基本术语
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .NET开源全面方便的第三方登录组件集合 - MrHuo.OAuth
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • @AutoConfigurationPackage的使用
  • @Autowired注解的实现原理
  • @EventListener注解使用说明
  • @RequestBody的使用
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600
  • [ vulhub漏洞复现篇 ] ThinkPHP 5.0.23-Rce