-
在控制结构内定义的变量(只要不是在堆上申请空间的变量),其作用域仅限于其所在的控制结构内。需要注意这个时候如果控制结构没有显式地表明其结构范围,就会产生二义性或异常的行为:
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;
-
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; }
- 有goto语句的代码可读性差,难以修改,不到必要时候不要使用。
- 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第五版第五章学习笔记
最新推荐文章于 2023-02-16 20:22:40 发布