1.复合语句:简单语句用分号;作为结尾,复合语句,也称为块,用一对花括号表示。
空块就是{},里面没有分号。
2.悬垂else问题:if-else语句中包含的if子句多于else子句时,对于每一个else,究竟归属哪一个if语句。若不是很明确,需要加花括号来进行匹配。
3.switch语句:如果swith(expr)表达式的值和case标号相同,则程序从该标号后面的第一个语句开始依次执行,直到switch结束或者遇到break语句为止。如果没有匹配的case标号,则程序从switch后面的第一条语句开始执行。就是说,如果没有break语句,后面的case均会执行。所以swich结构还是需要每个switch都有break语句。
swtich(ch)
{ case 'a': ++aCnt;break;
case 'e': ++eCnt;break;
case 'i': ++iCnt;break;
case 'o': ++oCnt;break;
case 'u': ++uCnt;break;
default: ++otherCnt;brea;
}
如果所有case都不匹配,那么执行default标号后面的语句。
case标号必须是整型常量表达式。
只能在最后一个case标号或default标号定义变量,如果在之前定义变量,很可能程序会跳过定义,直接使用变量导致错误。
4.do-while总是以;结尾:不接受while(condition)中的条件中定义变量。
do{}while();
5.break语句:只能存在于循环结构或者switch语句中。
6.continue语句:导致最近的循环语句的档次迭代提前结束,会继续求解循环条件,或者求解expr表达式。只是跳出当前迭代。
7.异常机制
(1)throw表达式:抛出异常,提供异常检测和异常处理之间的通信。
if(!item1.same_isbn(item2))
throw runtime_error("Data must refer to same ISBN");
(2)try块:允许后面是一个或多个catch子句用来处理不同的异常。try块当中是正常的程序,如果该语句出现异常,则去找处理这个异常的catch语句,如果没有就结束函数执行。
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
bitset<100> bs;
for(size_t ix = 0;ix!=bs.size();++ix)
bs[ix] = 1;
try{
bs.to_ulong();
}catch(runtime_error err){
cout<< err.what()<<endl;
}
system("pause");
return 0 ;
}
(3)标准异常:异常类型定义了e.what()的成员函数,返回C风格字符串。
exception定义了最常见的问题。
stdexcept定义了几种常见的异常:runtime_error是指仅在运行时才能检测到的问题。range_error, overfow_error, logic_error, domain_error, length_error, out_of_range, invalid_argument.
new定义了bad_alloc异常,提供因无法分配内存而由new抛出的异常。
type_info定义了bad_cast异常。
8.使用预处理器进行调试
(1)NDEBUG:程序开发阶段保持NDEBUG未定义就会执行调试语句,开发完成后定义NDEBUG,删除这些调试语句。
int main()
{
#ifndef NDEBUG
cerr<<"starting main"<<endl;
#endif
...
}
(2)预处理宏:assert,在cassert头文件中定义。是用来检验测试不可能发生的条件。跟异常不同,异常用于处理程序执行时预期要发生的错误。