当前课程知识点:C++语言程序设计基础 > 第2章 C++简单程序设计(二) > 自定义类型 > 自定义类型
自定义类型
l typedef 已有类型名 新类型名表
n 例:
typedef double Area, Volume;
typedef int Natural;
Natural i1,i2;
Area a;
Volume v;
l using 新类型名 = 已有类型名;
n 例:
using Area = double;
using Volume = double;
l 定义方式:
将全部可取值一一列举出来。
l 语法形式:
enum 枚举类型名 {变量值列表};
例:enum Weekday {SUN, MON, TUE, WED, THU, FRI, SAT};
默认情况下
SUN=0,MON=1,TUE=2,......,SAT=6
l 不限定作用域枚举类型:
enum 枚举类型名 {变量值列表};
l 限定作用域的enum类将在第4章介绍。
l 枚举元素是常量,不能对它们赋值
例如有如下定义
enum Weekday {SUN, MON, TUE, WED, THU, FRI, SAT};
不能写赋值表达式:SUN = 0
l 枚举元素具有默认值,它们依次为: 0,1,2,......。
l 也可以在声明时另行指定枚举元素的值,如:
enum Weekday{SUN=7,MON=1,TUE,WED, THU,FRI,SAT};
l 也可以在声明时另行指定枚举元素的值;
l 枚举值可以进行关系运算。
l 整数值不能直接赋给枚举变量,如需要将整数赋值给枚举变量,应进行强
制类型转换。
l 枚举值可以赋给整型变量。
l 设某次体育比赛的结果有四种可能:胜(WIN)、负(LOSE)、平局(TIE)、比赛取消(CANCEL),编写程序顺序输出这四种情况。
l 分析:
比赛结果只有四种可能,可以声明一个枚举类型。
#include <iostream>
using namespace std;
enum GameResult {WIN, LOSE, TIE, CANCEL};
int main() {
GameResult result;
enum GameResult omit = CANCEL;
for (int count = WIN; count <= CANCEL; count++) {
result = GameResult(count);
if (result == omit)
cout << "The game was cancelled" << endl;
else {
cout << "The game was played ";
if (result == WIN) cout << "and we won!";
if (result == LOSE) cout << "and we lost.";
cout << endl;
}
}
return 0;
}
l auto:编译器通过初始值自动推断变量的类型
n 例如:auto val = val1 + val2;
如果val1+val2是int类型,则val是int类型;
如果val1+val2是double类型,则val是double类型。
l decltype:定义一个变量与某一表达式的类型相同,但并不用该表达式初始化变量
n 例如:decltype(i) j = 2;
我们在写程序的时候呢
如果需要给类型起一个别名
就可以用typedef这个关键字
那么我们来看比如这样一个例子
我们看
我们可以用typedef
将预定义的类型double
起上别名Area Volume
叫面积 叫体积
为什么需要这样呢
有的时候给这样的类型起个别名
在程序中可读性就更好
它的意义就更明确
那么也有另外一种办法
就是用这个using
用typeef是在C语言中
继承过来的办法
那么如果说我们要用C++
里面规定的新的
这个using关键字呢
我们可以using新的类型名
等于已有类型名
比如说我们using Area=double
这也起到了一个起别名的作用
我们在C++中
虽然有那么多预定义类型
但是不是就够用了呢
还是不够用
我们还是需要自定义类型
比如说枚举类型
就是一个用户的自定义类型
什么是枚举类型呢
比如我们举一个例子
如果你要表示一星期中的七天
你觉得用什么类型比较好呢
可能你有可能想到字符类型
有可能想到整数类型
但是都不是那么准确
为什么呢
比如说你用整数类型
来表示一星期的中七天
零 一 二 三 四 五 六
或者
一 二 三 四 五 六 七
那么这种限制只能是你程序逻辑
自己来限制
从语法规定上是限制不了的
只要你将星期规定为整数类型
用户输入8 输入12 输入35
那都是合法制
那为了保证
它是在0到6范围之内的数据
我们在程序中就要写代码
去做这种数据合法性检验
枚举类型恰好可以解决
我们刚才这个问题
因为我们一星期中的七天
0到6
它恰好可以用
整数的一个子集来表示
而且这个子集数字并不多
可以一一列举出来
只要我们列举出来
这个新类型它的取值范围
就是0 1 2 3 4 5 6
把数字都列举出来
这就是定义了一个新的类型
它是用枚举的方式定义的
所以这种类型
在C++中称为枚举类型
我们来看
我们可以这样来定义
一个Weekday类型
用这个enum关键字
enum关键字后面
是一个枚举类型名
然后后面跟一对大括号
大括号里面是一组值的列表
也就是Weekday类型
它的可取值的全部列表
这是一些常量 枚举常量
默认情况下SUN它会等于0
然后MON对1
然后依次2 3 4 5 6
这种是不限定作用域的枚举类型
是C++从C语言
继承过来的枚举类型
C++中也可以定义
限定作用域的枚举类型
关于限定作用域的枚举类型
我们将在后续的章节中介绍
在使用
不限定作用域枚举类型的时候
大家需要注意这样几点
首先对于枚举元素
是按常量处理的
不能对它们进行赋值
比如说我们定义了这样一个
Weekday类型以后
我们不能对其中的枚举常量
SUN再赋值了
那么枚举类型元素呢
它有默认值
默认情况下从开始头一个起
依次为0 1 2 3
按1去递增
如果我们不希望它按这样的
默认的方式得到默认值的话
我们也可以
在定义枚举类型的时候
给枚举元素指定不同的值
比如说在这个例子里面
我们给SUN指定为7
给MON指定为1
如果你不给MON指定为1的话
7后面接下来它会自动是8的
所以我给MON指定为1
然后后面TUE就自动为2了
后面2 3 4 5 6
这样就符合我们要求了
枚举值它是可以进行关系运算的
那么我们看到枚举值
实际上就是整数的一个子集
那么它与整数之间
是不是可以互通呢
我们能用一个整数
直接给枚举值赋值吗 不可以
整数不能直接赋值给枚举变量
如果要将整数
赋值给枚举变量的话
要先做类型转换
显示的将整数转换为枚举类型
如果整数
在枚举类型的取值范围之内
转换就会成功
否则的话 转换就会失败
枚举值可以给整型变量赋值
因为它是整型的子集
下面我们来看这样一个例子
看看枚举类型是怎么用的
一场体育比赛
有多少种状态呢
胜 负 平局 取消
这样四种状态
那我们就在这个例题中
用枚举类型来表示这四种状态
现在我们来看这个源代码
在这里我们定义一个
GameResult 枚举类型
它的枚举值有WIN LOSE
TIE和CANCEL四个
然后我们来看看怎么样
去定义一个枚举类型的变量
这里给了两行 两种方式
result
直接用GameResult来定义的
而omit
用enum GameResult来定义的
我想说的是
这两种形式都可以
你带或者不带enum关键字
都没关系 都是可以的
定义一个枚举变量的时候
也可以给它赋初始值
比如说这个omit
它的初始值就是CANCEL
接下来我们看这个for循环
在这个for循环里面
用来初始化这个循环变量count的
是一个枚举值
所以用枚举常量值
给整数变量赋值是可以的
初始化是可以的
再看count和CANCEL
进行关系比较
所以枚举值跟int数据之间
是可以进行关系比较的
那么接下来呢
我们试图将count赋值给Result
这个赋值就不能直接做了
因为count是int类型
而Result
是GameResult枚举类型
所以
我们首先要进行强制类型转换
如果count它的取值
在这个枚举常量范围之内
这个转换就能够成功
否则的话转换就不成功
好 那么这道例题呢
逻辑很简单
主要是给大家演示一下
这个枚举类型定义
以及枚举类型的变量定义初始化
以及枚举类型的变量和int变量
它们之间混合运算的问题
下面给大家介绍
两个新的类型关键字
第一个是auto
auto关键字起什么作用呢
我们来看这个例子
大家就体会到了
比如说这个例子里面这个val
定语为auto类型
那么它到底是个什么类型呢
auto好象是个自动的 对吧
到底它是什么类型
它的类型取决于给它
进行初始化的这个表达式类型
也就是在这个例子里面
取决于val1+val2
这个表达式它的结果类型
如果这个表达式的类型是int类型
那么val就是int
如果这个表达式类型是double
那么这个val就是double
所以这个val的类型取决于
用来初始化的表达式的类型
那有的时候呢
我们定义一个变量
想用一个表达式来初始化
但是并不想取用
这个表达式的类型 怎么办
我们看下面这个例子
我们想定义一个j
用2去初始化它
但是我们并不想让变量j
跟2有同样的类型
我们希望变量j跟i有同样的类型
所以前面用一个decltype
它是delclrationtype的缩写
那么尽管2是初始值
但是j的类型会跟i是一样的
好 这一节的内容就是这些
-导学
--第1章导学
-计算机系统简介
--计算机系统简介
--计算机系统简介 测试题
-计算机语言和程序设计方法的发展
--计算机语言和程序设计方法的发展 测试题
-面向对象的基本概念
--面向对象的基本概念 测试题
-程序的开发过程
--程序的开发过程
--程序的开发过程 测试题
-信息的表示和储存
--计算机的数字系统
--数据的编码表示
--信息的表示和储存 测试题
-实验指导
-导学
--第二章导学
-C++语言概述
--C++语言概述 测试题
-基本数据类型、常量、变量
--程序举例
--基本数据类型、常量、变量 测试题
-运算与表达式
--运算与表达式 测试题
-实验二:简单程序设计(上)
-数据的输入和输出
--数据的输入和输出
--数据的输入和输出 测试题
-选择结构
--if语句
--switch语句
--选择结构 测试题
-循环结构
--for语句
--循环结构 测试题
-自定义类型
--自定义类型
--自定义类型
-第2章小结
--第二章小结
-实验二:C++简单程序设计(下)
-导学
--导学
-函数定义
--函数定义
--函数定义 测试题
-函数调用
--例3-2
--例3-3
--例3-4
--例3-5
--例3-6
--函数调用 测试题
-嵌套与递归
--例3-9
--例3-10
--嵌套与递归 测试题
-函数的参数传递
--函数的参数传递
--函数的参数传递 测试题
-引用类型
--引用类型 测试题
-含有可变参数的函数
--含有可变参数的函数 测试题
-内联函数
--内联函数 测试题
-constexpr函数
--CONSTEXPR函数课后习题
-带默认参数值的函数
--带默认参数值的函数 测试题
-函数重载
--函数重载 测试题
-C++系统函数
--C++系统函数习题
-第3章小结
--第三章小结
-实验三(上)函数的应用
-实验三(下)函数的应用
-导学
--导学
-面向对象程序的基本特点
--面向对象程序的基本特点 测试题
-类和对象
--类和对象的定义
--类和对象 测试题
-构造函数
--构造函数基本概念
--委托构造函数
--复制构造函数
--构造函数 测试题
-析构函数
--析构函数
--析构函数 测试题
-类的组合
--类的组合
--类的组合程序举例
--前向引用声明
--类的组合 测试题
-UML简介
--UML简介
--UML简介课后习题
-结构体与联合体
--结构体与联合体 测试题
-枚举类
--枚举类
--枚举类 测试题
-第4章小结
--第四章小结
-实验四(上)
--实验四(上)
-实验四(下)
--实验四(下)
-导学
--导学
-标识符的作用域与可见性
--标识符的作用域与可见性 测试题
-对象的生存期
--对象的生存期
--对象的生存期 测试题
-类的静态成员
--类的静态成员 测试题
-类的友元
--类的友元 测试题
-共享数据的保护
--共享数据的保护 测试题
-多文件结构和预编译命令
--多文件结构和预编译命令 测试题
-第5章小结
--小结
-实验五
--实验五
-导学
--导学
-数组的定义与初始化
--数组的定义与使用
--一维数组应用举例
--数组的定义与初始化 测试题
-数组作为函数的参数
--数组作为函数的参数 测试题
-对象数组
--对象数组
--对象数组 测试题
-基于范围的for循环
-指针的定义和运算
--指针的定义和运算 测试题
-综合实例
--综合实例
-实验六(上)
--实验六上
-指针与数组
--指针数组
--指针与数组 测试题
-指针与函数
--指针类型的函数
--指向函数的指针
--指针与函数 测试题
-对象指针
--对象指针
--对象指针 测试题
-动态内存分配
--动态内存分配 测试题
-智能指针
--智能指针
-vector对象
--vector对象
--vector对象 测试题
-对象复制与移动
--移动构造
--对象复制与移动 测试题
-字符串
--C风格字符串
--string类
--字符串 测试题
-第6章小结
--第六章小结
-综合实例
--综合实例
-实验六(下)
--实验六(下)