c++ primer知识点-第6章 语句

2009年1月03日    分类:C++, 原创   浏览次数:13 

目录

6.1 简单语句

6.2 声明语句

6.3 复合语句(块)

6.4 语句作用域

6.5 if语句

6.6 switch语句

6.7 while语句

6.8 for循环语句

6.9 do while语句

6.10 break语句

6.11 continue语句

6.12 goto语句

6.13 try块和异常处理

6.14 使用预处理器进行测试

 

6.1 简单语句

  C++中,大多数语句以分号结束。

6.2 声明语句

6.3 复合语句

  复合语句,通常被称为块,是用一对花括号括起来的语句序列。块标识了一个作用域,在块中引入的名字只能在该块内部或嵌套在块中的子块里访问。

6.4 语句作用域

  有些语句允许在它们的控制结构中定义变量,但仅在定义它们的块语句结束前有效,其作用域局限在语句内部。

while (int i =get_num())
	cout << i << endl;
i = 0; //error: i is not accessable outside the loop

6.5 if语句

  if语句的条件表达式可以是初始化声明语句,其中,变量必须初始化,因为已初始化的变更值要转换为bool值用于判断。

6.6 switch语句

6.6.1 使用switch

  如果条件表达式与其中一个标号的值匹配,则程序将从该标号后面的第一个语句开始依次执行各个语句,直到switch结束或遇到break语句为止。

6.6.2 switch中的控制流

  为了安全起见,最好在每个后面提供一个break语句,即使是最后一个标号也一样。如果希望省略;case后面的break语句,可以将几个case语句写在一行,可以令代码更加清晰。

6.6.3 default标号

  如果所有的case标号与switch表达式的值都不匹配,并且default标号存在,则执行default标号后面的语句。

6.6.4 switch表达式与case标号

  switch求解表达式可以是定义和初始化一个变量。

switch(int ival = get_response());

ival的值将要与每个case标号比较。

6.6.5 switch内部的变量定义

  在switch内部,要为某个特殊的case定义变量,则可以引入块语句,在该语句中定义变量,从而保证这个变量在使用前被定义和初始化。

6.7 while语句

  while循环内的赋值操作是一种常见的用法。

6.8 for循环语句

  应该谨记:在for语句头定义的任何对象限制在for循环体里可见。

6.8.1 省略语句头的某些部分

  可以省略初始化语句、循环语句和表达式中的任何一个,但是分号不能省略。

6.8.2 for语句头中的多个定义

  可以在for语句的初始化语句中定义多个对象,但是不管怎么样,该处只能出现一个语句,因此所有的对象必须具有相同的一般类型。

6.9 do while语句

6.10 break语句

  break用于结束最近的while、do while、for或switch语句,并将程序的执行权传递给紧接在被终止语句之后的语句。break只能出现在循环或switch结构中,或者出现在嵌套于循环或switch结构中的语句里。

6.11 continue语句

  continue语句导致最近的循环语句的当次迭代提前结束。对于while和do while语句,继续求解循环条件,而对于for循环,程序流程接着求解for语句头中的expression表达式。

6.12 goto语句

  尽量不要使用。

6.13 try块和异常处理

  C++的异常处理包括:

1. throw表达式,错误检测部分使用这种表达式来说明遇到了不可处理的错误。

2. try块,错误处理部分使用它来处理异常。try语句块以try关键字开始,并以一个或多个catch子句结束。在try块中执行的代码所抛出的异常,通常会被其中一个catch子句处理。

3. 由标准库定义的一组异常类,用来在throw和相应的catch之间传递有关的错误信息。

6.13.1 throw表达式

  系统通过throw表达式抛出异常。throw表达式由关键字throw以及尾随的表达式组成,通常以分号结束。

6.13.2 try块

  try块的通用语法形式是:

try {
    program-statements
} catch (exception-specifier) {
    handler-statements
} catch (exception-specifier) {
    handler-statements
}

1. 编写处理代码

2. 函数在寻找处理代码的过程中退出

  寻找处理代码的过程与函数调用链刚好相反。抛出一个异常时,首先要搜索的是抛出异常的函数。如果没有找到匹配的 catch,则终止这个函数的执行,并在调用这个函数的函数中寻找相配的 catch。如果仍然找到相应的处理代码,该函数同样要终止,搜索调用它的函数。如此类推,继续按执行路径回退,直到找到适当类型的 catch 为止。
如果不存在处理该异常的 catch 子句,程序的运行就要跳转到名为 terminate 的标准库函数,该函数在 exception 头文件中定义。这个标准库函数的行为依赖于系统,通常情况下,它的执行将导致程序非正常退出。
在程序中出现的异常,如果没有经 try 块定义,则都以相同的方式来处理:毕竟,如果没有任何 try 块,也就没有捕获异常的处理代码(catch 子句)。此时,如果发生了异常,系统将自动调用 terminate 终止程序的执行。

6.13.3 标准异常

  C++标准库定义了一组类,用于报告在标准库中的函数遇到的问题。

1. exception头文件定义了最常见的异常类,它的类名是exception。这个类只通知异常的产生,但不会提供更多的信息。

2. stdexcept头文件定义了几种常见的异常类。表中列出了头文件中定义的标准异常类。

exception 最常见的问题
runtime_error 运行时错误:仅在运行时才能检测到的问题
range_error 运行时错误:生成的结果超出了有意义的值域范围
overflow_error 运行时错误:计算上溢
underflow_error 运行时错误:计算下溢
logic_error 逻辑错误:可在运行前检测到的问题
domain_error 逻辑错误:参数的结果值不存在
ivalid_argument 逻辑错误:不合适的参数
length_error 逻辑错误:试图生成一个超出该类型最大长度的对象
out_of_range 逻辑错误:使用一个超出有效范围的值

6.14 使用预处理器进行调试

  可用NDEBUG预处理变量实现有条件的调试代码:

int mian()
{
  #ifndef NDEBUG
    cerr << "starting main" << endl;
  #endl
  //...

 

开发完成后,可通过定义NDEBUG预处理变量,删除这些调试语句。

  预处理器还定义了其余四种在调试时非常有用的常量:

_ _FILE_ _ 文件名

_ _LINE_ _ 当前行号

_ _TIME_ _ 文件被编译的时间

_ _DATE_ _ 文件被编译的日期

if (word.size() < threshold)
    cerr << "Error: " << _ _FILE_ _
         << " :line " << _ _LINE_ _ << endl
         << "       Compiled on " << _ _DATE_ _
         << " at " << _ _TIME_ _ << endl
         << "       Word read was " << word
         << ":  LENGTH too shor" << endl;

  另一种调试技术是使用NDEBUG预处理变量以及asset(断言)预处理宏。assert宏是在cassert头文件中定义的。

assert(expr)

 

  只要NDEBUG未定义,assert宏就求解条件表达式expr,如果结果为false,assert输出信息并且终止程序的执行。如果该表达式有一个非零值,则assert不做任何操作。在测试过程中,assert等效于检验数据是否总是具有预期的大小,一旦程序完成,并且定义了NDEBUG,assert语句就不做任何工作。assert仅用于检查确实不可能的条件。

标签: ,      订阅此文  

本文地址:http://klniu.com/post/c-primer-knowledge-6/

相关文章

  1. c++ primer知识点-第5章 表达式
  2. c++ primer知识点-第4章 数组和指针
  3. c++ primer知识点-第3章 标准库类型
  4. c++ primer知识点-第2章 变量和基本类型
  5. c++ primer知识点-第1章 快速入门


28 queries in 0.466 秒.