当前课程知识点:面向对象程序设计(C++) > 第二讲 基础语法(1) > 2.2 变量的初始化、类型推导与基于范围的循环 > 变量的初始化、类型推导与基于范围的循环
那刚才我们看到在定义变量的时候呢
说给它进行一个0:27 值
或者有的时候也把它称之为变量的初始化
是用等号这样的一种语法形式来进行的
其实在这个0:36 这个版本里头
这种标准里头呢
还有一种新的对变量进行初始化的一种办法
我们称之为初始化列表
那它是用这个花括号括起来的
这个元素的序列
那么可以用来对这个变量进行初始化
大家看下面这个例子
inta括号这是一个数组
那它有多少个元素呢不知道
一般来讲我们都是在后面跟上
等号然后花括号比方说135
这样呢这个数组a就有三个元素
分别是1和3 5
这是一个相对常规一点的一个办法
那么在1:23 的这种标准里头
我们还有一种新办法
可以把这个等号省略掉
也就是说有一个数组a
ina括号那么呢我们用三个元素
所组成的这样的一个序列
对这个数组a进行初始化
就是花括号135把这等号没了
那这个呢跟上面的这条语句是等效的
这是一个在这个初始化花括号之前
可以有等号也可以没有等号
那么对于其他的一些变量的定义
那我们可以做一个列举
大家来对比一下
在我们目前对变量进行初始化
有哪些不同的办法
大家看第一个inta=3+5
后面3+5是一个表达式
那么把表达式的结果去赋给这个a
它这个a等于它
那当然了你也可以写成是
a等于括号3+5
就是把3+5的运算结果
用花括号括起来去赋给a
那当然你也可以是用一个圆括号
这个a圆括号3+5
那这个圆括号在我们后面讲到
面向对象的这种类定义对象的时候
会大量的来用到
对于这个普通的类型
就是在这个语言里头3:01 的
本来就基础的类型
比如int float double等等
那么呢也支持
跟这个对象的定义类似的方法
这个具体我们后面还会讲到的
用圆括号来对它进行赋值
来对它进行初始化
那么有了这个初始化列表之后呢
我们也可以是这样子写
inta花括号3+5那么这个结果
跟你去写inta=3+5是一样的
那么下面这两个例子呢
是用到了new这个运算符
这我们前面讲过了
开辟一个内存然后把它返回回来
那么下面你可以看到int*i等于new int
圆括号10
这个呢跟刚才我们看到的inta圆括号3+5
其实是类似的
就是我分配一个内存空间能够放int
然后呢把10给它设置到这个内存里头去
这相当于说指针变量i所指的内存单元
它有一个初始值是10
所以这就是这个new int圆括号10
它的含义
那再看最后一句话的这个例子
double*d=new double花括号1.2f
什么意思呢就是跟前面那个new
那个*号i一样
开辟一个存放double的内存空间
把地址给变量d存起来
然后这个内存空间里头存什么呢
存的是1.2这样的一个浮点值
可是这个时候没有用圆括号
用的是花括号
这个也是可以的
这叫做初始化列表对变量进行初始化
它的这种语法形式
也就是在你的变量后面
直接跟上花括号
来表示对这个变量进行赋值
进行这个初始化
那么跟变量相关的
还有一个知识值得介绍的呢
是这个类型的推导
它的这个关键字叫5:25
那么可以对变量或表达式的结果的类型
让编译器自己把它根据语句的写法
自己推导出来
就是我代码里头没有这个类型的名字
编译器呢并不报错
因为它可以通过上下文推导出来
这个类型到底是什么
我们来看这个代码的例子
首先我们定义了一个anon-u的一个结构
struct然后里头是一个char*name
这个结构是anon-u这个它的名字
接着呢我们定义了第二个结构
这个结构里头有两个成员
一个呢是名字叫做d它的类型是int
这个是你代码里头写好了
第二个成员呢它的变量名是id
它的类型是什么呢类型我没有写
类型我要求这个编译器去使用
anon-u这个变量它的名字来定义
让它作为这个id的类型
所以在前面一条语句里头
我们定义了一个结构
它用这个结构定义了一个变量叫anon-u
这个结构是没有名字的
然后下面定义了一个结构呢
它也没有名字
然后它里头成员id呢
类型是用前面那个没有名字的结构
来定义的
那我怎么知道那个类型呢
用的这个decltype这样的一个方式
让编译器从变量anon-u里头
去推导出它的这个类型来
所以这个是它的一个用的地方
那同理第二个结构呢
也定义了一个没有类型名字的
一个结构这个结构定义了一个数组
这个结构数组的每一个元素
都是这种结构类型
然后这个数组呢有一百个元素
就是anon-s这样的一个数组
它的名字类型的名字也没有
我们来看下面这个main函数里头
要定义一个as这个变量
那么这个as变量它类型是什么呢
你前面定义的两个结构都没有名字啊
没关系我们可以用这个decltype
这个关键字
让它去指挥编译器
从已有的这个变量anon-s这个变量
去结合上下文从这个已有的这个变量
去推导出它那个实际的类型
所以呢as它的类型跟anon-s
这个变量类型是一样的
它也是一百个元素组成的一个
结构变量所组成的一个数组
所以下面我们就可以对它进行操作
as(0)是吧它是个数组吗第0个元素
然后呢里头有一个这个结构成员
叫做id属于as-0.id这个id是什么呢
是根据anon-u这个结构变量
来定义的一个数据成员
所以呢它里头也有一个成员叫做name
属于你可以看到as(0).id.name
这些信息编译器都能够去获得
它可以按照你的关键字 的要求
自动的根据上下文去推导出来
这样的话你就省得去敲这个类型的名字
特别是在后面我们讲的
面向对象的程序设计里头
有些地方可能你并不知道
或者这个实际的变量的名
这个类型名字叫什么
那么你代码怎么写呢
可以通过这种方式
让编译器通过已有的变量
让它自己从这个已有变量的
这个类型里头去推导出
它需要的那种类型信息
这样的话才能完成你现在的
这个变量的定义
比方像我们这个代码里头
要定义这个as变量类型名字不知道
没关系可以用decltype这个关键字
让编译器从里头去推导
这就是一个变量的类型推导
那么下一个也跟变量有关系的
一个新的知识点呢
是对这个for循环语句的一种改进
这个实际上在很多别的语言里头
早就提供这种功能所以呢
我们现在的这个新的10:15
这个标准里头也增加了
对这个知识点的语法的支持
所谓的基于范围的for循环语句
那它的写法是在循环头这个地方啊
用冒号分成两部分
第一部分是那个用于迭代的变量
我们过去传统上把它称为循环变量
而第二部分呢是这个循环变量
它循环迭代的那个范围
这么说可能还比较抽象
那大家看下面这个代码就比较直观了
这个main函数里头定义了一个数组
arr它有三个元素分别是1 3 9
这三个整数
我为了对这个数组进行循环
那我可以写成是for圆括号int e
就是一个迭代变量它的名字叫做e
在什么范围去迭代呢
冒号arr这个冒号后面跟的是个数组名
那意思就是告诉编译器
e要去依次去等于
这个arr这个数组里头的每一个元素
这个数组有多大这个for循环
就循环多少次
所以这个就是变成了for int e:arr
让它去循环取遍arr这个数组里头的
每一个组成的元素
然后下面的循环体是cout这个e的值
所以你看这个地方看上去就比以前
你去写int i=0 i<3 i++然后呢cout
这个arr(i)要来得直观
一看就明白我要把arr这个数组里头
每一个元素都12:14 一遍
所以你看跟你的语言的叙述
是一一对应的
就没有像过去那样的写法拐很多弯
当然了一种更简捷的办法就是
你也不用去写inte冒号arr啦
可以直接写12:30 e冒号arr
就是说arr里头是什么
让编译器自己去确定
所以每一个这个迭代的这个元素e
它到底是什么类型
让编译器自己去找
那我写起来就比较普通就比较简单了
我不用去考虑这个类型的名字
我直接写把这个arr
这个数组里头的每一个元素都取到
至于这个每一个元素是什么
我不管我就写个12:55
这样的话就把这个12:59
自动变量的类型的这种方式
和for循环基于范围的这种for循环
结合起来就大大的
降低了你去编写这种循环语句的时候
这样的一个工作量
理解起来也比较方便也比较直观
所以这是一个基于范围的for循环语句
这个用的还是比较普遍的
所以我们在这里给大家介绍一下
-1.0 课程定位、教学内容
-1.0 课程定位、教学内容--作业
-1.1 编程环境与工具
--源程序拆分
-1.2 main函数的命令行参数
-作业一--作业
-2.1 变量定义
--变量定义
-2.2 变量的初始化、类型推导与基于范围的循环
-2.3 函数重载
--函数重载
-2.4 函数参数的缺省值与追踪返回类型的函数
-2.5 类的定义
--类的定义
-2.6 类成员的访问权限与友元
-第二讲 基础语法(1)--作业二
-3.1 构造函数析构函数
--构造函数析构函数
-3.2 赋值运算符重载
--赋值运算符重载
-3.3 流运算符重载
--流运算符重载
-3.4 函数运算符重载
--函数运算符重载
-3.5 下标运算符与自增减运算符重载
-3.6 静态成员与常量成员
-3.7 对象组合
--对象组合
-3.8 移动构造函数
--Video
--Video
-3.9 default修饰符
--Video
-第三讲 基础语法(2)--作业三
-4.1 继承
--Video
-4.2 函数重写
--Video
-4.3 虚函数
--Video
--Video
-4.4 自动类型转换
--Video
-4.5 禁止自动类型转换
--Video
-4.6 强制类型转换
--Video
-4.7 函数模板
--Video
-4.8 类模板
--Video
-4.9 成员函数模板
--Video
-4.10 模板特化
--Video
-作业四--作业
-5.0 引言
--Video
-5.1 从FOP到OOP
--Video
-5.2 对象在哪里
--Video
-5.3 接口在哪儿
--Video
-5.4 实现接口
--Video
-5.5 变与不变:多态的威力
--Video
-6.0 引言
--讨论
-6.1 从负载监视器的设计开始
-6.2 接口的分离与单一责任原则
-6.3 委托与接口的进一步分解
-6.4 分离不同层面的可变性
-7.0 引言
--Video
-7.1 迭代器
--Video
-7.2 迭代器的实现
--Video
-7.3 迭代器与模板
--Video
-7.4 算法与数据的解耦
--Video
-7.5 抽象结构与类模板
--Video
-7.6 函数对象与算法分解
--Video
-7.7 基于模板的策略模式
--Video
-8.0 引言
--Video
-8.1 已有资源的组合
--Video
-8.2 适当引入接口
--Video
-8.3 接口不变时的功能变化
--Video
-8.4 装饰
--Video
-8.5 责任的传递与责任链
--Video
-8.X 小结
--Video
-9.0 引言
--Video
-9.1 通过封装增加隔离、应对变化
--Video
--Video
-9.2 增加抽象层,应对变化
--Video
--Video
-9.3 相互关联对象的创建
--Video
-9.4 示例:自动组卷系统设计
--Video
-9.5 设计思路(上)
--Video
-9.6 设计思路(中)
--Video
-9.7 设计思路(下)
--Video
-9.X 小结
--Video
-课程总结
--Video
-期末考试--作业