C++ primer 第五章-语句

Hi!这里是山幺幺的c++ primer系列。写这个系列的初衷是,虽然在学校学习了c++,但总觉得对这门语言了解不深,因此我想来啃啃著名的c++ primer,并在这里同步记录我的学习笔记。由于我啃的是英文版,所以笔记是中英文夹杂的那种。另外由于已有一定的编程基础,所以这个系列不会含有太基础的知识,想入门的朋友最好自己啃书嘻嘻~

简单语句


expression statement

  • 表达式后加上分号即变为了expression statement
  • Expression statements cause the expression to be evaluated and its result discarded

null statement

; // null statement

Compound Statements (Blocks)

  • a block is a scope: Names introduced inside a block are accessible only in that block and in blocks nested inside that block

条件语句


if

switch

  • switch括号中的值会转换为integral value
  • 可以通过break语句跳出switch
  • case labels must be integral constant expressions
  • 如果没有break语句,会从第一个case开始continues across all the remaining cases
  • 多个case共用一个操作:
switch (ch) {
  // any occurrence of a, e, i, o, or u increments vowelCnt
  case 'a':
  case 'e':
  case 'i':
  case 'o':
  case 'u':
    ++vowelCnt;
    break;
}
  • 常见bug
switch (ch) {
  case 'a':
    ++aCnt; // oops: should have a break statement
  case 'e':
    ++eCnt; // oops: should have a break statement
  case 'i':
    ++iCnt; // oops: should have a break statement
  case 'o':
    ++oCnt; // oops: should have a break statement
  case 'u':
    ++uCnt;
}

PS:ch = 'e'时,实际发生的是:Execution jumps to the code following the case 'e' label, which increments eCnt. Execution continues across the case labels, incrementing iCnt, oCnt, and uCnt as well.

  • default:switch括号中的值不匹配任一case时,跳到default处
switch (ch) {
  case 'a': case 'e': case 'i': case 'o': case 'u':
    ++vowelCnt;
    break;
  default:
    ++otherCnt;
    break;
}

PS:若写了default case却没有需要做的,那么the default label must be followed by a null statement or an empty block

  • case中若要定义变量,最好加上花括号,保证该变量只对该case可见
case true:
// this switch statement is illegal because these initializations might be bypassed
  string file_name; // error: control bypasses an implicitly initialized variable
  int ival = 0; // error: control bypasses an explicitly initialized variable
  int jval; // ok: because jval is not initialized
  break;
case false:
// ok: jval is in scope but is uninitialized
  jval = next_num(); // ok: assign a value to jval
  if (file_name.empty()) // file_name is in scope but wasn't initialized
  // ...

// 应该改成
case true:
{
  // ok: declaration statement within a statement block
  string file_name = get_file_name();
  // ...
}

循环语句


while

for

  • traditional for和range for
for (auto &r : v) 
  r *= 2;
// 等价于
for (auto beg = v.begin(), end = v.end(); beg != end; ++beg)
{
  auto &r = *beg; 
  r *= 2; 
}
  • 不能用range for来add elements to a vector (or other container):在range for中,the value of end() is cached. If we add elements to (or remove them from) the sequence, the value of end might be invalidated

跳转语句


return

第六章会讲

break

  • 结束the nearest enclosing while, do while, for, or switch

continue

  • 只出现在for, while, or do while中,影响the nearest enclosing loop

goto

  • labeled statement
end: return; // end是label
  • goto语句的语法:goto label;
  • Label identifiers are independent of names used for variables and other identifiers. Hence, a label may have the same identifier as another entity in the program.
  • goto语句和对应的label语句必须在同一方程中
  • goto cannot transfer control from a point where an initialized variable is out of scope to a point where that variable is in scope
goto end;
int ix = 10; // error: goto bypasses an initialized variable definition
end:
// error: code here could use ix but the goto bypassed its declaration
ix = 42;
  • Jumping back to a point before a variable is defined destroys the variable and constructs it again
begin:
int sz = get_size();
if (sz <= 0) {
  goto begin;
}

try


Exception Handling

  • 程序的一部分作为detecting part,若这部分无法continue,就认为检测到了错误,交给另一部分代码即handling part处理

  • 包含:

    • throw expressions:a throw raises an exception,detecting part用throw来表示它检测到了错误
    • try blocks:其中有很多catch clauses(即exception handlers),在try block中执行的代码throw出的exception会交由其中一个catch clause来处理
    • exception classes:在throw和对应的catch之间传递信息

throw expression

  • Throwing an exception terminates the current function and transfers control to a handler that will know how to handle this error.
if (item1.isbn() != item2.isbn())
throw runtime_error("Data must refer to same ISBN");
// if we're still here, the ISBNs are the same
cout << item1 + item2 << endl;

PS:runtime_error is one of the standard library exception types,定义在头文件stdexcept中

try block

  • 一般格式
try {
program-statements
} catch (exception-declaration) {
handler-statements
} catch (exception-declaration) {
handler-statements
} 
  • 当一个catch被选中处理一个exception时,对应的catch clause被执行。catch clause执行结束后,从最后一个catch clause后面紧跟的语句开始执行
  • try block对catch是不可见的
  • 栗子
while (cin >> item1 >> item2) {
    try {
        // execute code that will add the two Sales_items
        // if the addition fails, the code throws a runtime_error exception
    }  catch (runtime_error err) {
          cout << err.what() << "Try Again? Enter y or n" << endl;
          char c;
          cin >> c;
          if (!cin || c == 'n') {
              break; // break out of the while loop
          }
    }
}

PS:若是上上上段代码throw exception,则会打印Data must refer to same ISBN Try Again? Enter y or n

  • 含有try block的函数调用另一个含有try block的函数并抛出异常时,查找catch clause的顺序是:The search for a handler reverses the call chain. When an exception is thrown, the function that threw the exception is searched first. If no matching catch is found, that function terminates. The function that called the one that threw is searched next. If no handler is found, that function also exits. That function’s caller is searched next, and so on back up the execution path until a catch of an appropriate type is found.
  • 如果没找到对应类型的catch clause,或者程序遇到异常却不在try block中,那么execution is transferred to a library function named terminate. The behavior of that function is system dependent but is guaranteed to stop further execution of the program.

exception的类型

  • 头文件exception:定义了exception类型,It communicates only that an exception occurred but provides no additional information.
  • 头文件stdexcept:
  • 头文件new:定义了bad_alloc类型
  • 头文件type_info:定义了bad_cast类型

各exception类型支持的操作

  • We can create, copy, and assign objects of any of the exception types.
  • exception, bad_alloc, and bad_cast objects只能default initialize;其他类型不能default initialize,只能且必须用string初始化
  • what():返回const char*;what返回的内容取决于exception的类型。For the types that take a string initializer, the what function returns that string. For the other types, the value of the string that what returns varies by compiler.
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 5.1 简单语句 C++ 中大部分语句都以分号结束,一个表达式末尾加上分号就变成了 表达式语句(expressio...
    卖渔翁阅读 437评论 0 0
  • 条件语句 if、if else语句:if else语句:注意嵌套的合法性,建议使用花括号进行流程控制。悬垂else...
    HungweeHou阅读 388评论 0 0
  • Hi!这里是山幺幺的c++ primer系列。写这个系列的初衷是,虽然在学校学习了c++,但总觉得对这门语言了解不...
    山幺幺阅读 480评论 0 1
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,728评论 1 51
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,985评论 16 22

友情链接更多精彩内容