作者简介: 博 主 在 读 机 器 人 研 究 生 , 目 前 研 一 。 对 计 算 机 后 端 感 兴 趣 , 喜 欢 c + + , g o , p y t h o n , 目 前 熟 悉 c + + , g o 语 言 , 数 据 库 , 网 络 编 程 , 了 解 分 布 式 等 相 关 内 容 \textcolor{orange}{博主在读机器人研究生,目前研一。对计算机后端感兴趣,喜欢c++,go,python,目前熟悉c++,go语言,数据库,网络编程,了解分布式等相关内容} 博主在读机器人研究生,目前研一。对计算机后端感兴趣,喜欢c++,go,python,目前熟悉c++,go语言,数据库,网络编程,了解分布式等相关内容
个 人 主 页 : \textcolor{gray}{个人主页:} 个人主页: 小呆鸟_coding
支 持 : \textcolor{gray}{支持:} 支持: 如 果 觉 得 博 主 的 文 章 还 不 错 或 者 您 用 得 到 的 话 , 可 以 免 费 的 关 注 一 下 博 主 , 如 果 三 连 收 藏 支 持 就 更 好 啦 \textcolor{green}{如果觉得博主的文章还不错或者您用得到的话,可以免费的关注一下博主,如果三连收藏支持就更好啦} 如果觉得博主的文章还不错或者您用得到的话,可以免费的关注一下博主,如果三连收藏支持就更好啦 就 是 给 予 我 最 大 的 支 持 ! \textcolor{green}{就是给予我最大的支持!} 就是给予我最大的支持!
本文摘要
本专栏主要是对c++ primer这本圣经的总结,以及每章的相关笔记。目前正在复习这本书。同时希望能够帮助大家一起,学完这本书。 本文主要讲解第5章 语句 文章目录
- 第5章 语句
- 5.1 简单语句
- 5.2 语句作用域
- 5.3 条件语句
- 5.3.1 if 语句
- 5.3.2 switch 语句
- 5.4 迭代语句
- 5.4.1 while 语句
- 5.4.2 传统的for语句
- 5.4.3 范围for语句
- 5.4.4 do while 语句
- 5.5 跳转语句
- 5.5.1 break 语句
- 5.5.2 continue 语句
- 5.5.3 goto语句
- 5.6 try 语句块和异常处理
- 5.6.1 throw 表达式
- 5.6.2 try 语句块
- 5.6.3 标准异常
表达式语句
表达式语句
执行表达式并丢弃掉求值结果
ival + 3; //一条没有实际用处的表达式语句
cout << ival;//一条有用的表达式语句
空语句
用法
:
语法上需要一条语句但逻辑上不需要的地方
,此时用空语句使用空语句应该加上注释。
; //空语句
while (cin >> s && s != sought)
;//空语句
复合语句(块)
{}
(花括号)括起来的语句和声明的序列,复合语句也被称作块
用法
while (val <= 10)
{
sum += val;
++ val;
}
只能在内部使用一旦语句结束,变量不可以使用
条件语句分为俩种if
语句和 switch
语句。
使用 if 语句最好在所有的 if 和 else 之后都用花括号
。if else
语句中,如果if
比else
多时如何处理的问题。C++使用的方法是else
匹配最近没有配对的if
。整型表达式
的值,然后根据这个值从几条执行路径中选择一条。case 标签必须为整型常量表达式
。switch(ch){
case 'a': ++aCnt; break;
case 'b': ++bCnt; break;
}
int ival = 42;
switch(ch){
case 3.14; //错误
case ival; //错误
}
执行问题
:
从该 case 标签开始顺序执行所有case分支或者遇到break结尾
一条 case 后可以跟多条语句
,不必用花括号括起来。一般在每个 case标签后都有一条 break 语句
。如果需要两个或多个值共享同一组操作,可以故意省略掉 break 语句。unsigned vowlCnt = 0;
switch(ch){
case 'a':
case 'b':
case 'c':
++ vowelCnt;
break;
}
switch(ch){
case 'a': case 'b':
++Cnt;
break;
}
注意
:
一般不要省略 case 分支最后的 break 语句
。如果没有 break 语句,最好注释一下。如果要在 case 分支定义并初始化变量,应该定义在块内以约束其作用域
。迭代语句有三种:while语句、for语句(范围for语句)、do while语句
表达式
或者是一个带初始化的变量声明
。while (condition)
statement
for(init-statement; condition; expression)
statement;
声明语句
、表达式语句
或空语句
。只能有一条声明语句
,因此所有的变量基础类型必须相同。for (int i = 0, j = 0; i < n ;i++)
statement
for (int i = 0, char j = '0'; i < n ;i++) //错误
for(declaration : expression)
statement
遍历容器或其他序列的所有元素。
必须是一个序列
,可以是花括号括起来的初始值列表
。这些序列的共同的是都可以返回迭代器的 begin 和 end 成员。
写操作
,必须将循环变量声明成引用类型
。变量
(不是迭代器)。最简单的方法是使用 auto 类型说明符
。不能
改变序列的元素数量(增加、删除)。因为范围for预存了 end()
的值,改变元素数量后 end() 的值就可能失效了
。每次迭代都会重新定义循环控制变量,并将其初始化为序列的下一个值。
do
statement
while (condition);
do while
语句和while
语句的唯一区别是do while语句先执行循环体后检查条件。即至少执行一次循环。
不要忘了加分号。
break
、continue
、return
、go to
。while
、do while
、for
或者 switch
语句,并从这些语句之后的第一条语句开始执行。for
、while
、do while
中,比break少了一个switch
。goto 语句无条件跳转到同一函数内的另一条语句
。label : int a = 1;
goto label;
标识一条语句的标示符
如果 goto 语句跳回了一条变量的定义之前意味着系统将会销毁该变量,然后重新创建它。
不要使用 goto,它会令程序又难理解又难修改。
(它不需要处理异常,只需要用于检测异常)
异常检测
和异常处理
俩部分协同完成。throw 表达式:异常检测部分使用 throw 表达式来表示遇到了无法处理的问题。称为 throw 引发了异常。
try 语句块:异常处理部分使用 try 语句块处理异常。try 语句块以关键字 try 开始,并以一个或多个 catch 子句结束。
一套异常类:用于在 throw 表达式和相关的 catch 子句间传递异常的具体信息。
throw
和紧随其后的一个表达式
,表达式的类型就是抛出的异常类型。throw只是用来检测异常,并不处理,处理交给try和catch语句。
if (item1.isbn() != item2.isbn())
throw runtime_error("Data must refer to same ISBN");
cout << item1 + item2 << endl;
try
语句块的一开始是关键字try
,随后紧跟一个块。try
块后面的是一个或多个 catch 子句
。catch 子句包括三部分:关键字 catch
、括号内一个(可能未命名)的对象的声明(叫做异常声明)
、一个块
。块内
声明的变量在块外部无法访问
,特别是在catch子句也无法访问
。当 try 语句块中抛出了一个异常,如果该异常类型与 catch 子句括号中的异常类型相同,就会执行该 catch 子句
。每个标准库异常类都有一个 what 成员函数,它没有参数,返回初始化该对象时所用的 C 风格字符串。
while (cin >> item1 >> item2){}
try{
throw runtime_error("Data must be same as size");//try 语句块抛出了一个异常
}
catch(runtime_error err){//在 catch 后面的括号中声明了一个“runtime_error”类型的对象,与 try 抛出的异常类型相同,接下来执行此子句。
cout << err.what()
<< "\nTry Again? Enter y or n" << endl;
char c;
cin >> c;
if (!cin || c == 'n')
{
break; //跳出while循环
}
}
}
异常运行结果
err.what()就是为了输出上面错误的信息"Data must be same as size"
Data must refer to same ISBN
Try Again? Enter y or n
函数在寻找处理代码的过程中退出
嵌套的 try 语句块中或在 try 语句块中调用的某个函数内
。当异常被抛出,首先程序会从内到外一层层寻找相应类型的 catch 子句
。如果最后还是没找到,系统会调用 terminate 函数
并终止当前程序的执行。如果对于 throw 语句外就没有 try 语句块,也会执行 terminate 函数
。编写异常代码非常困难
有的程序执行完成有的程序执行到一半就中断了
,c此时会导致资源没有正常释放
,对象处于无效状态
等情况。异常安全的代码要求在异常发生时能正确执行清理工作。这个非常困难。C++ 标准库定义了一组异常类
,用于报告标准库函数遇到的问题。他们定义在 4 个头文件中
。
stdexcept 头文件
中的类型必须使用 string 对象或 C 风格字符串来初始化他们。不允许使用默认初始化方式
。只能默认初始化,不能提供初始值。
只有一个 what 成员函数
,该函数没有参数
,返回是一个 C 风格字符串的指针
,目的是提供关于异常的文本信息。exception | 异常类 exception 是最通用的异常类。它只报告异常 的发生,不提供额外信息。 |
---|---|
bad_alloc | 异常类 bad_alloc。在使用 new 分配动态内存失败时抛出 |
bad_cast | 异常类型 bad_cast。经常发生在使用 dynamic_cast 时发生 |
exception | |
runtime_error | 只有在运行时才能检测出的问题 |
range_error | 运行时错误:生成的结果超出了有意义的值域范围 |
overflow_error | 运行时错误:计算上溢 |
underflow_error | 运行时错误:计算下溢 |
logic_error | 程序逻辑错误 |
domain_error | 逻辑错误:参数对象的结果值不存在 |
invalid_argument | 逻辑错误:无效参数 |
length_error | 逻辑错误:试图创建一个超出该类型最大长度的对象 |
out_of_range | 逻辑错误:使用一个超出有效范围的值 |
exception头文件
定义了exception
。new头文件
定义了bad_alloc
。type_info头文件
定义了bad_cast
。stdexcept头文件
。上面的异常类之间存在继承关系,其中 exception 是所有其他类的基类,总的继承关系如下图
void StrBlob::check(size_type i, const string& msg)
{
if (i >= data->size())
throw out_of_range(msg);
}