【c++ primer, 5e】特殊用途语言特性
【默认实参】
1、注意点:函数的默认实参可以在函数的声明中添加,但是后续声明只能添加默认参数而不能改变先前声明的默认参数。(函数的声明通常是定义在头文件上的,多次声明同一个函数是合法的)
2、默认实参必须为全局变量,但是允许在局部改变这些变量的值,如果在局部重新声明将作为默认实参的变量,将不会有任何影响。
练习
6.40
b 顺序错误,默认参数应该在位置参数的右边。
6.41
a 非法,没有给第一个位置参数赋值。
c 合法但是背离初衷,原因是'*'会作为整型数赋值给参数wd而不是参数bckgrnd。
6.42
#include <iostream> #include <string> using namespace std; string make_plural(size_t ctr, const string &word, const string &ending = "s") { return (ctr > 1) ? word + ending : word; } int main() { string word1 = "success"; string word2 = "failure"; cout << make_plural(1, word1) << '\n' << make_plural(2, word1, "es") << endl; cout << make_plural(1, word2) << '\n' << make_plural(2, word2) << endl; return 0; }
【内联函数和constexpr函数】
1、为什么使用内联函数?避免函数调用的开销,在编译时在调用点内联的展开。
2、注意点:内联函数通常声明连同定义在头文件内!
3、为什么使用constexpr函数?用作常量表达式。(常量表达式可以用于数组的初始化、常量初始化等)
4、constexpr函数的特点:被隐式声明为内联函数,在编译时其调用就被替换为对应结果值。
练习
6.43
a 放在.h文件中
b.放在.cpp文件中
6.44
inline bool isShorter(const string &s1, const string &s2) { return s1.size() < s2.size(); }
6.45
略
6.46
不能。不能保证isShorter的实参是常量表达式。
【调试帮助】
1、预处理器定义的5个很有用的名字。p216
2、NDEBUG的用法。
假如有一段这样的代码:
#include <iostream> #include <string> #include <cassert> using namespace std; int main() { #ifndef NDEBUG cout << __func__ << endl; cout << __FILE__ << endl; cout << __LINE__ << endl; cout << __TIME__ << endl; cout << __DATE__ << endl;#endif return 0; }
默认状态下编译运行:
$ g++ prog1.cpp -std=c++11 -o prog1 $ prog1 main prog1.cpp 10 9:3:23 Apr 1 2017
关闭DEBUG模式编译运行:
$ g++ -D NDEBUG prog1.cpp -std=c++11 -o prog1 $ prog1 # 输出为空!
3、assert。
assert 英[əˈsɜ:t]
美[əˈsɜ:rt]
vt. 声称,断言
例如:
#include <iostream> #include <string> #include <cassert> using namespace std; int main() { cout << "hi" << endl; assert(1); cout << "my name is" << endl; assert(0); cout << "xkfx" << endl; return 0; }
输出:
$ hi my name is Assertion failed: 0, file prog1.cpp, line 10 This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.
练习
6.47
#include <iostream> #include <vector> using namespace std; void vectorPrinter(vector<int>::iterator beg, vector<int>::iterator end) { if (beg != end) { cout << *beg << endl; vectorPrinter(beg+1, end); return; } else return; } int main() { vector<int> ivec = {1, 2, 3, 4, 5}; #ifndef NDEBUG cout << "size=" << ivec.size() << endl; #endif vectorPrinter(begin(ivec), end(ivec)); return 0; }
关闭调试模式只需要在编译时加上-D NDEBUG就可以了。
6.48
string s; while (cin >> s && s != ".") {} // 不断读入字符串,直到碰到一个要找的字符串就终止(这里用"."替代)。 assert(cin); // cin是一个对象,单独出现在条件语句的时候结果值为1。所以assert什么也不做。