C++_Primer_2021.11.29


第5章 语句

表达式语句:

一个表达式末尾加上分号,就变成了表达式语句。表达式语句的作用是执行表达式并丢弃掉求值结果。
;//空语句:语法上需要一条语句但逻辑上不需要,此时应该使用空语句。

简答语句:
复合语句(块):是指用花括号括起来的(可能为空的)语句和声明序列,复合语句也被称作块(block)。一块就是一个作用域。while或for的循环体必须是一条语句,但要做很多事情,就用花括号括起来,从而把语句序列转变成块。

块不以分号作为结束。

空块的作用等价于空语句

switch:

不能使用逗号,应该用:,ival不是const;

unsigned odd_cnt = 0;
unsigned ival=512, jval=1024, kval=4096;
unsigned bufsize;
unsigned swt = get_bufCnt();
switch(swt) {
case 1, 3, 5, 7, 9:
	++odd_cnt;
	break;
case ival:
	bufsize = ival * sizeof(int);
	break;
}
return 0;

5.4 迭代语句
while和for在执行循环体之前检查条件,do while语句先执行循环体,然后再检查条件。
当不确定要迭代多少次时,使用while循环比较合适。还有一种情况是想在循环结束后访问循环控制变量。

while循环特别使用与那种条件保持不变、反复执行操作的情况,如当未达到文件末尾时不断读取一个值。
for循环更像是按步骤迭代,它的索引值在某一个范围内一次变化。

5.6 TRY语句块和异常处理
异常处理机制为程序中异常检测和异常处理两部分的协作提供支持。

throw表达式:引发异常
try语句块(try block)和catch子句(catch clause),后者被称为异常处理代码(exception handler)
异常类(exception class):用于在throw表达式和相关的catch子句之间传递异常的具体信息。

5.6.1 throw表达式

包括关键字throw和紧随其后的一个表达式,其中表达式的类型就是抛出的异常类型,throw表达式后面通常紧跟一个分号,从而构成一条表达式语句。异常抛出将终止当前的函数,并把控制权转移给处理该异常的代码。

try{
throw runtime_error("Data must refer to same ISBN");
} catch(runtime_error err) {
cout << err.what();
}

类型runtime_error是标准库异常类型的一种,定义在stdexcept头文件中。

catch子句包括三部分:关键字catch、括号内一个(可能未命名的)对象的声明(称异常声明)以及一个块。

try语句块内声明的变量在块外部无法访问,特别是在catch子句内无法访问。

catch子句,若没有找到,就沿着程序的执行路径逐层回退,直到找到适当类型的catch子句。若最终还是没有找见,就转到terminate的标准函数,该函数的行为与系统有关,一般情况下,执行该函数将导致程序非正常退出。

如果一段程序没有try语句块且发生异常,系统会调用terminate函数并终止当前程序的执行。

在异常发生期间正常执行了“清理”工作的程序被称为异常安全的代码。然而经验表明,编写异常安全的代码非常困难,这部分知识也(远远)超出了本书的范围。

对于那些确实要处理异常并继续执行的程序,要加倍注意,必须时刻清楚异常何时发生,异常发生后程序如何确保对象有效、资源无泄漏、程序处于合理状态,等等。

5.6.3 标准异常
C++标准库定义了一组类,用于报告标准库函数遇到的问题,也可在用户编写的程序中使用,分别定义在4个头文件中:

  • exception头文件,定义通用异常类exception。只报告异常的发生,不提供任何额外信息
  • stdexcept头文件,定义了几种常用的异常类

exception 最常见的问题
runtime_error 只有在运行时才检查出的问题
range_error 运行时错误:生成的结果超出有意义的值域范围
overflow_error 运行时错误:计算上溢
underflow_error 运行时错误:计算下溢
logic_error 程序逻辑错误
domain_error 逻辑错误:参数对应的结果值不存在
invalid_argument 逻辑错误:无效参数
length_error 逻辑错误:试图创建一个超出该类型长度的对象
out_of_range 逻辑错误:使用一个超出有效范围的值

  • new头文件,定义了bad_alloc异常类型
  • type_info头文件定义了bad_cast异常类型

只能以默认初始化的方式初始化:exception、bad_alloc、bad_cast对象。其他异常类型应该使用string对象或C风格字符串初始化这些类型的对象,但是不允许使用默认初始化的方式。该初始值含有错误相关的信息。

相关