C++primer第五版第五章学习笔记

  1. 在控制结构内定义的变量(只要不是在堆上申请空间的变量),其作用域仅限于其所在的控制结构内。需要注意这个时候如果控制结构没有显式地表明其结构范围,就会产生二义性或异常的行为:

     int i = 100;
     if(true):
         int i += 3; // 此时的变量i会覆盖if结构外的变量i
         // 这个if结构没有使用{}显式表明其结构范围,所以其范围限在了紧随其后的那条语句的分号为止
         // 下面的打印语句中的i就是if前的i变量。如果if前面没有定义变量i,这个时候cout中的i就是未定义的变量了
         // 如果再嵌套一层if-else的话,编译器就不知道两对if-else之间是怎么匹配的了(这就是二义性)
         cout << i << endl;

  2. switch-case控制结构:

    • 只有break可以中断switch。
    • 在switch控制结构下,程序会依次匹配每个case选项,匹配失败则继续往下匹配,成功的会执行相应的case分支,然后继续往下匹配直至遇到break语句或switch的结束。
    • case对应的值必须是整型常量表达式。
    • default不需要有对应的值,它匹配的是除去所有case分支以外的所有情况。
    • 每个case分支只能匹配一个值,如有需要匹配多个,可以不在case分支内写break来实现,但是除非是必须,一般情况下不提倡这样使用。
    • 同一组case对应的值不能有相同的。
    • continue只能用在循环控制结构中,switch/if都不能单独使用continue
    • switch控制结构中不能包含任何显示地或隐式的初始化语句

      #include <iostream>
       using std::cin;
       using std::cout;
      using std::endl;
      
      int main()
         {
             switch(2) {
                 case 0 :
                     {
                         // 此处的变量处于语句块{}内部,作用域仅在当前块内,
                         // 确保了后面的case都不在此作用域内,所以这里的变量即使初始化也不会报错
                         int k = 0;
                         string s2;
                         cout << "in case 0, k=" << k << ", s2=" << s2 << endl;
                     }
      
                     // 此处的变量处于语句块{}内部,作用域仅在当前块内,
                     // 确保了后面的case都不在此作用域内,所以此处就算声明了与下面重名的变量也不会报错
                     {
                         int i;
                     }
      
                     // 变量i的定义在case 1,所以此处的i仍属于未声明的变量,
                     // 编译报错:‘i’ was not declared in this scope
                     // i = 0;
                     cout << "in case 0" << endl;
                     break;
                 case 1 :
                     // 正确,结构体内的基本类型变量不会被默认初始化,
                     // 所以变量i只是定义了,不会被初始化,而且此定义在switch的结构体内该条语句后面都是有效的
                     int i;
      
                     // 错误,显式初始化为0,
                     // 编译报错:crosses initialization of ‘int j’,jump to case label [-fpermissive]
                     // int j = 0;
      
                     // 错误,隐式初始化为NULL,
                     // 编译报错:crosses initialization of ‘std::string s’,jump to case label [-fpermissive]
                     // string s;
      
                     cout << "in case 1" << endl;
                     break;
                 case 2 :
                     // 正确,此处只是赋值,不是初始化,而变量i在case2中就已经声明了,
                     //所以在其声明之后的后续代码中都是有效的(不管是否匹配进入case1,此处的变量i都是有效的)
                     i = 20;
                     cout << "in case 2, i=" << i << endl;
                     break;
                 case 3 :
                     cout << "in case 3" << endl;
                     // continue只能用在循环控制结构中,switch/if都不能单独使用continue,
                     // 编译报错:continue statement not within a loop
                     // continue
                     break;
                 default :
                     cout << "in default case" << endl;
             }
      
             return 0;
         }

  3. goto语句的代码可读性差,难以修改,不到必要时候不要使用。
  4. try-throw-catch:捕获异常,常见异常:
     #include <iostream>
     #include <stdexcept>
    
     using namespace std;
    
     int main()
     {
         try {
             int a = 0;
             int b = 1;
             if (a == 0) {
                 throw range_error("dividend can not be zero");
             }
    
             cout << "b / a: " << b / a << endl;
         } catch (range_error err) {
             cout << "range_error msg: " << err.what() << endl;
             return -1;
         } catch (...) {
             cout << "unknow error << endl;
             return -1;
         }
    
         return 0;
     }

你可能感兴趣的:(C++Primer)