将介绍三种函数相关的语言特性:
默认实参,内敛函数,constexpr函数
6.5.1 默认实参
某些函数有这样一种形参,在函数的很多次调用中,都被赋予相同值,重复出现的值称为函数的 默认实参(default argument)。调用有默认实参的函数,可以省略实参
typedef string::size_type sz;
string screen(sz ht = 24, sz wid =80,char backgrnd = '');
一旦某个形参被赋予了默认值,它后面的形参都必须有默认值
使用默认实参调用函数
如果要用默认实参,调用的时候省略实参即可
但是要按顺序(即不可以省略前面的跳到后面去)
尽量让不使用默认值的形参出现在前面
默认实参声明
不能再声明给有默认值的形参赋值,但是可以给前面没有默认实参的形参赋值
通常,应该再函数声明中指定默认实参,并将该声明放在合适的头文件中。
默认实参初始值
局部变量不能作为默认实参
就是可以改变默认实参的值。
6.5.2 内联函数和constexpr函数
内联函数可避免函数调用的开销
把函数指定为内联函数(inline),
在函数返回类型之前加上 inline就可以将它声明成内联函数了
Note:内联说明指示编译器发出的一个请求,编译器可以选择忽略这个请求。
一般来说,内联机制用于优化规模小,流程直接,频繁调用的函数。很多编译器不支持内联递归函数
constexpr函数
constexpr函数是指能用于常量表达式的函数。
函数的返回类型及所有形参的类型都得是字面值类型
函数体中有且只有一条return语句。
constexpr被隐式定义成内联函数
Note: constexpr函数不一定返回常量表达式
把内联函数和constexpr函数放在头文件内
对于给定的内联函数和constexpr函数来说,它的多个定义必须完全一致,所以内联函数和constexpr函数通常定义在头文件中。
6.5.3 调试帮助
assert预处理宏
assert是一种预处理宏(preprocessor marco):预处理一个变量和内联函数类似。
assert(expression);
如果expression为假(即0),assert输出信息并终止程序的执行。
如果表达式为真(非0),assert什么也不做。
assert宏定义在cassert头文件中。
NDEBUG预处理变量
assert的行为依赖于一个名为NDEBUG的预处理变量的状态。
如果定义了NDEBUG,则assert什么也不做,默认没定义NDEBUG,此时assert将执行运行时检查。
可以用一个#define 定义NDEBUG
如果NDEBUG未定义,将执行#ifndef和#endif之间的代码,如果定义了这些代码会被忽视
void print(const int ia[],size_t size)
{
#ifndef NDEBUG
cerr << _ _func_ _ << ":array size is" << size << endl;
#endif // NDEBUG
}
_ _func_ _ 是编译器定义的一个局部静态变量,用于存放函数的名字
_ _FILE_ _ 存放文件名的字符串字面值
_ _LINE_ _ 存放当前行号的整型字面值
_ _TIME_ _ 存放文件编译时间的字符串字面值
_ _DATE_ _ 存放文件编译日期的字符串字面值