1. 在所有用过的类类型中,IO类型可以用作条件,但vector类型和string类型一般不可用作条件。
2. 对于悬垂else语句,会普遍存在潜在的二义性,解决方法是通过将悬垂的else语句匹配给最后出现的尚未匹配的if子句。
3. 在switch语句中,程序不是只会执行匹配的case标号关联语句。实际上,程序会从该点开始执行,并跨越case边界继续执行其他语句,直到switch结束或者遇到break语句为止。
switch(ch)
{
case 'a':
++aCnt;
case 'e':
++eCnt;
case 'i':
++iCnt;
case 'o':
++oCnt;
case 'u':
++uCnt;
}
假设ch为‘i’,那么此时iCnt加1,之后oCnt,uCnt都会加1。
4. case语句的标号必须为整型常量表达式。
5. switch结构,只能在它的最后一个case标号或者default标号之后定义变量,这是为了避免出现代码跳过变量的定义和初始化的情况。
case true:
//error:declaration precedes a case label
string file_name = get_file_name()
break;
case false;
//..
如果需要为某个特殊的case定义变量,可以引入块语句,在该块语句中定义变量,可以保证这个变量在使用前被定义和初始化。
case true:
//ok
{
string file_name = get_file_name();
}
break;
case false:
//...
6. 循环条件中定义的变量在每次循环里都要经历创建和撤销的过程
7. while循环
int *source = arr1;
size_t sz = sizeof(arr1) / sizeof(*arr1);
int *dest = new int[sz];
while(source != arr1 + sz)
*dest++ = *source++;
8. for循环的init-statement部分可以定义多个对象,但是只能出现一个语句,因此所有的对象都必须具有相同的类型。
for(int i = 0, *pi = ia, &ri = val;;);
9. do-while语句是以分号结束的。
10. break语句只能出现在循环或者switch结构中,或者出现在嵌套于循环或switch结构的语句里。当break出现时,将会终止里层的switch或循环语句,而外层的switch语句或者循环不受影响。 continue语句导致最近的循环语句的当次迭代提前结束,continue语句只能出现在for,while或者do while循环中。
11.goto语句和获得所转移的控制权的带标号的语句必须位于同一个函数内。goto语句不能跨越变量的定义语句向前跳转:
//....
goto end;
int ix = 10;
end:
//error :code here could use ix but the goto bypassed its declaration
ix =42;
如果确实要在goto和跳转的标号之间定义变量,则必须引入块语句。
//....
goto end;
{
int ix = 10;
//code us ix
}
end:
// code can no longer use ix
向前跳转意味着变量可能在没有定义的情况下使用。而向后跳转回到一个变量定义之前,则会使系统撤销这个变量,然后再重新创建它。
12. 异常处理
if(!item1.same_isbn(item2))
throw runtime_error("...");
try{
//code
} catch(exception-specifier){
//handler
} catch(exception-specifier){
//handler
}
异常类型定义了what函数,它返回c风格的字符串,为抛出的异常提供更详细的文字描述
13.标准异常定义在四个头文件中
(1) exception头文件定义了最常见的异常类,这个类只通知异常的产生
(2) stdexcept头文件定义了几种常见的异常类,见下表
(3) new头文件定义了bad_alloc异常类型,提供因无法分配内存而由new抛出的异常
(4) type_info头文件定义了bad_case异常类型
exception | 最常见的问题 |
runtime_error | 运行时才能检测到的错误 |
range_error | 生成的结果超出有意义的值范围 |
overflow_error | 计算上溢 |
underflow_error | 计算下溢 |
logic_error | 逻辑错误:运行前检测到 |
domain_error | 参数的结果值不存在 |
invalid_error | 不合适的参数 |
length_error | 试图超出最大长度的对象 |
out_of_range | 使用超出有效范围的值 |
14. asset(expr)预处理宏 在预处理变量NDEBUG没有定义时 求解 expr的值
预处理器定义了四种在调试时有用的常量:
__FILE__ 文件名
__LINE__ 当前行号
__TIME__文件被编译时间
__DATE__文件被编译日期
使用它们可以输出相关信息