《C++ Primer》读书笔记-第五章 语句
简单语句
- 表达式语句
- 空语句
- 复合语句
- 语句作用域
条件语句
- if
- switch
迭代语句
- while
- for
- 范围for
- do while
跳转语句
- break
- continue
- goto
- return
try语句和异常处理
- try语句
- throw表达式
异常类
表达式语句
表达式末尾加上分号就成了表达式语句
作用是执行表达式并丢弃掉求值结果
空语句
//空语句使用的常见情况是,当循环的全部工作在条件部分就可以完成,我们通常会用到空语句
//重复读取数据直至达到文件末尾或某次输入的值等于sought
while (cin >> s && s != sought)
;//空语句
只含有一个单独的分号,如果我们多写了一个分号
int i = 0;;
实际是两句语句,后面一个分号是空语句
这种情况不会有什么影响,但是
while( i < 10 ) ;
++i;
空语句构成了while循环的循环体,导致死循环
复合语句(块)
用花括号括起来的语句和声明序列,也称为块
//块不以分号结束
while (val <= 10)
{
sum += val;
++val;
}
while (cin >> s && s!= sought)
{
//空块
}
## ##
## 语句作用域 ##
一个块就是一个作用域
if、switch、while、for内定义的变量都属于局部作用域
## 条件语句 ##
MZF: 多加花括号会使事情变得简单很多
### if ###
if语句可以嵌套
if(condition)
if(condition)
statement
else
if(condition)
statement
else if(condition)
statement
我们会通过缩进来给if...else进行配对,实际上,if的个数多余else的情况,称为悬垂else问题,else总是和离它最近的未匹配的if匹配
所以第一个else实际和内层的if匹配,整个语句开始变得复杂和难以理解
多加花括号会使事情变得简单
if(condition)
{
if(condition)
{
//do something
}
}
else
{
if(condition)
{
//do something
}
else if(condition)
{
//do something
}
}
花括号内的语句只有块作用域,所以对第一个else来说,内层的if是不可见的,它会和第一个if进行匹配,这也正是我们希望的
### switch ###
case标签必须是整型常量表达式
一种简单明了的写法
switch (i)
{
case 0:
{
//do something
}
break;
case 1:
{
//do something
}
break;
default:
{
//do something
}
break;
}
如果某个case标签匹配成功,将从该标签开始往后顺序执行所有case分支,除非显式地中断这一过程
因此多加花括号和break,事件会变得简单
## 迭代语句 ##
* while
* for
* 范围for
* do while
这些语句我们都不陌生了,再把书看看就行
for语句头能省略掉init-statement、condition和expression中的任何一个(或者全部)
do while语句是先执行循环体再检查条件,因此无论条件是否为真,循环体至少会执行一次
注意do while不是以花括号结束的,应当在后面加上分号
do
{
//do something
} while (condition);
## 跳转语句 ##
* **break负责终止离它最近的while、do while、for或switch语句**
* **continue终止当前这次迭代并立即开始下一次迭代**
* 只有当switch嵌套在迭代语句内部时,才能在switch里使用continue
* 不要在程序中使用goto语句
goto语句的作用是从goto语句无条件跳转到同一函数内的另一条语句。语法形式如下:
goto label; //label为一个语句标签
* 1
label是用于标识一条语句的标识符。带标签语句是一种特殊的语句,在它之前有一个标识符以及一个冒号:
end: return; //一条带标签语句
* 1
和switch语句类型,goto语句也不能将程序的控制权从变量的作用域之外转移到作用域之内,比如
goto end;
int ix = 10;
end:
ix = 42; //错误,跳过了变量的初始化语句
* 1
* 2
* 3
* 4
向后跳过一个已经执行的定义时合法的,跳到变量定义之前意味着系统将销毁该变量,然后重新创建它。
begin:
int sz = get_size();
if(sz < 0)
{
goto begin; //从作用域内跳到作用域外是合法的
}
* 1
* 2
* 3
* 4
* 5
* 6
在实际编程中应该尽量少使用goto语句,因为这使程序难理解而且不宜修改。
## try语句和异常处理 ##
异常是指程序运行时的反常行为,这些行为超出了函数正常功能的范围,有的时候也超出了程序员的意料
通常情况下,异常会导致整个程序的终止
可以使用try语句块来处理异常。
try语句块以关键字try开始,并以一个或多个catch子句结束
try语句块中抛出的异常有机会被catch子句处理
我们程序员也可以主动的抛出异常,比如当检测程序中的数据库连接断开了,我们可以抛出异常来通知程序的其他部分进行处理
使用throw表达式抛出异常
要完成异常处理,除了try语句块和throw表达式外,我们还需要异常类,它负责携带异常的具体信息
标准库定义了一些异常类,不过多数情况下我们需要自定义自己的异常类
Sales_item item1,item2;
// 首先检查item1和item2是否表示同一种书籍的
while(cin >> item1 >> item2)
{
try{
if(item.isbn() != item2.isbn())
{
//该异常类型是runtime_error异常。
throw runtime_error("Data must refer to same ISBN");
}
// 如果执行到这里说明两个ISBN是相同的。
cout << item1+item2 << endl;
}
catch(runtime_error err)
{
//提示用户两个ISBN必须一致,询问是否重新输入
//err类型是runtime_error,因此能推断出what是runtime_error类的一个成员函数。
cout << err.what() <<"\n Try Again? Enter y or n" << endl;
char c;
cin >> c;
if(!cin || c == 'n')
break; // 跳出while循环。
}
}
还没有评论,来说两句吧...