语句(switch,异常,NDEBUG,assert)
- while(cin >>xxx) 可以输入后立即判
- switch
- default语句,即使没有什么要执行的,也要加上,后面用空语句填上,
告诉读者这种情况已经考虑到了,只是没有必要执行。
- case后必须是整型常量
- 对于 switch 结构,只能在它的最后一个 case 标号或 default 标号后面定义变量:
回顾变量的作用域,变量从它的定义点开始有效,直到它所在块结束为止。现在
考虑如果在两个 case 标号之间定义变量会出现什么情况。 该变量会在块结束之
前一直存在。对于定义该变量的标号后面的其他 case 标号,它们所关联的代码
都可以使用这个变量。如果 switch 从那些后续 case 标号开始执行,那么这个
变量可能还未定义就要使用了。
在这种情况下,如果需要为某个特殊的 case 定义变量,则可以引入块语句,在
该块语句中定义变量,从而保证这个变量在使用前被定义和初始化。
加{}后,后序的case再定义该变量时不会出现重定义。 - 用while和指针赋值数组
-
编写一个小程序,从标准输入读入一系列 string 对象,
寻找连续重复出现的单词。程序应该找出满足以下条件的
单词的输入位置:该单词的后面紧跟着再次出现自己本
身。跟踪重复次数最多的单词及其重复次数。输出重复次
数的最大值,若没有单词重复则输出说明信息。例如,如
果输入是:
how, now now now brown cow cow
则输出应表明“now”这个单词出现了三次。1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 string cur, pre,store; 6 int cur_cnt = 0, max_cnt = 0; 7 while (cin >> cur && cur != "exit") 8 { 9 if (cur == pre) 10 { 11 ++cur_cnt; 12 if (cur_cnt > max_cnt) 13 { 14 max_cnt = cur_cnt; 15 store = cur; 16 } 17 } 18 else 19 { 20 cur_cnt = 1; 21 pre = cur; 22 } 23 } 24 cout << store <<":" << max_cnt; 25 return 0; 26 }
-
try 块和异常处理
http://c.biancheng.net/view/422.html - throw
抛出异常
1 // first check that data is for the same item 2 if (!item1.same_isbn(item2)) 3 throw runtime_error("Data must refer to same ISBN"); 4 // ok, if we're still here the ISBNs are the same 5 std::cout << item1 + item2 << std::endl;
- try
处理异常
try { program-statements } catch (exception-specifier(异常说明符)) { handler-statements } catch (exception-specifier) { handler-statements } //...
-
catch(...)捕捉任何异常,其后面所有的catch都无效了,所以要放在其他catch后面
-
1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 int m,n; 6 cin >> m >> n; 7 try 8 { 9 if(n == 0) 10 throw -1; 11 else 12 throw 1.0; 13 } 14 catch(int i) 15 { 16 cout << " catch(int)" <<endl; 17 } 18 catch(...) 19 { 20 cout << "catch(...)" <<endl; 21 } 22 cout << "finished"<<endl; 23 return 0; 24 }
如果catch(...)放在前面,报错 -
bad_cast:类型转换不安全时抛出,如从多态基类对象(或引用)到派生类的引用的强制类型转换
1 #include <iostream> // std::cout 2 #include <typeinfo> // std::bad_cast 3 4 class Base {virtual void member(){}}; 5 class Derived : Base {}; 6 7 int main () { 8 try 9 { 10 Base b; 11 Derived& rd = dynamic_cast<Derived&>(b); 12 } 13 catch (std::bad_cast& bc) 14 { 15 std::cerr << "bad_cast caught: " << bc.what() << '\n'; 16 } 17 return 0; 18 }
- bad_alloc:申请内存空间失败时抛出此类异常
1 // bad_alloc example 2 #include <iostream> // std::cout 3 #include <new> // std::bad_alloc 4 5 int main () { 6 try 7 { 8 int* myarray= new int[10000000000000000000000000]; 9 } 10 catch (std::bad_alloc& ba) 11 { 12 std::cerr << "bad_alloc caught: " << ba.what() << '\n'; 13 } 14 return 0; 15 }
- out_of_range:下标越界异常
1 对于vector v; 2 非空时,v[i]与v.at(i)等价 3 下标越界时,v.at(i)可抛出out_of_range异常,
1 #include <iostream> 2 #include <stdexcept> 3 #include <vector> 4 #include <string> 5 using namespace std; 6 int main() 7 { 8 vector<int> v(10); 9 try { 10 v.at(100) = 100; //拋出 out_of_range 异常 11 } 12 catch (out_of_range & e) { 13 cerr << e.what() << endl; 14 } 15 string s = "hello"; 16 try { 17 char c = s.at(100); //拋出 out_of_range 异常 18 } 19 catch (out_of_range & e) { 20 cerr << e.what() << endl; 21 } 22 return 0; 23 }
- 在 <stdexcept> 头文件中定义的标准异常类
-
exception 最常见的问题。 runtime_error 运行时错误:仅在运行时才能检测到问题 range_error 运行时错误:生成的结果超出了有意义的值域范围 overflow_error 运行时错误:计算上溢 underflow_error 运行时错误:计算下溢 logic_error 逻辑错误:可在运行前检测到问题 domain_error 逻辑错误:参数的结果值不存在 invalid_argument 逻辑错误:不合适的参数 length_error 逻辑错误:试图生成一个超出该类型最大长度的对象 out_of_range 逻辑错误:使用一个超出有效范围的值 -
异常类型只定义了一个名为 what 的操作。这个函数不需要任何参数,并且 返回 const char* 类型值。 what 函数所返回的指针指向 C 风格字符数组的内容,这个数组的内容依赖 于异常对象的类型。对于接受 string 初始化式的异常类型,what 函数将返回 该 string 作为 C 风格字符数组。对于其他异常类型,返回的值则根据编译器 的变化而不同
- NDEBUG 和 assert()
1 #include<iostream> 2 #include <cassert> 3 using namespace std; 4 int main() 5 { 6 #ifndef NDEBUG 7 cerr << "starting main" << endl; 8 #endif 9 int x, y; 10 cin >> x >> y; 11 assert(y != 0);//表达式true,不执行,否则终止 12 13 #ifndef NDEBUG 14 cerr << "end" << endl; 15 #endif 16 return 0; 17 }
-
定义NDEBUG后,以上assert无效
1 在开头加#define NDEBUG后
可见assert失效,开头和结尾的语句消失
-
预处理器还定义了其余四种在调试时非常有用的常量: __FILE__ 文件名 __LINE__ 当前行号 __TIME__ 文件被编译的时间 __DATE__ 文件被编译的日期 可使用这些常量在错误消息中提供更多的信息
1 #define NDEBUG 2 #include<iostream> 3 #include <cassert> 4 using namespace std; 5 int main() 6 { 7 #ifndef NDEBUG 8 cerr << "starting main" << endl; 9 #endif 10 int x, y; 11 cin >> x >> y; 12 if (y == 0) 13 { 14 cout << __FILE__ << endl 15 <<__LINE__<< endl 16 << __DATE__ << endl 17 << __TIME__ << endl; 18 } 19 20 #ifndef NDEBUG 21 cerr << "end" << endl; 22 #endif 23 return 0; 24 }
1 //习题6.26 2 string s; 3 while (cin >> s) { 4 assert(cin); 5 // process s 6 } 7 //习题6.27 8 string s; 9 while (cin >> s && s != sought) { } // empty body 10 assert(cin); 11 // process S