Default Arguments
函数可以有默认的参数,如果不指定参数的话,就会使用它们。
如果某一个参数有默认值,那跟随的参数也必须有默认值。
参数的默认值可以不使用,也可以使用一部分;但是不能跳过前面的默认值,只使用后面的默认值。
所以最好将最常更改的参数放置在最左边。
本地变量不会用来做默认参数,即使它让外部的变量不可见:
sz wd = 80;
char def = ' ';
sz ht();
string screen(sz = ht(), sz = wd, char = def);
string window = screen(); // screen(ht(), 80, ' ');
void f2()
{
def = '*';
sz wd = 100
window = screen(); // screen(ht(), 80, '*');
}
----------------
inline & constexpr
使用函数有很多好处:
• 便于阅读和理解;
• 保证了统一的性能;
• 便于修改;
• 可重复使用,而不是重复编写。
使用函数也有缺点:
• 函数对于表达式来说,耗费了更多的资源。
如果一个函数被定义成inline,那么它在编译时就会按照表达式的规则展开。
这样它既具备了函数的优点,又具备了表达式的优点。
函数前面添加inline关键字,是告诉编译器此请求,编译器会根据实际情况决定是否inline。
一般来说,inline是为了优化小的、直接的、常被调用的函数。
编译器通常不会inline一个递归函数,一个75行的函数几乎肯定不会被inline。
constexpr函数能够用在constant表达式中。
constexpr函数有着严格的限制,它的返回值类型和参数类型必须是literal类型。
constexpr函数的函数体,必须仅仅包含一条return指令,而不是多处return。
总而言之,编译器必须在编译时就能够确定constexpr函数的值。
constexpr肯定是隐式的inline。
constexpr的函数体可以包含其他的语句,但这些语句不能产生任何runtime的操作。
constexpr函数可以返回非constant的值,这和它的参数相关。
inline和constexpr函数可能在程序中被定义很多次。
因为编译器需要它的定义,而不仅仅是声明,因此它们通常被定义在头文件里。
----------------
Aids for Debugging
为了调试的方便,通常会在开发版本里增加debug信息,而在正式版本里去掉。
要实现这个功能,可以使用:assert/NDEBUG。
assert是一种预定义的宏:
assert(expr);
expr的值会被计算,如果它为false,则assert会写一个消息并结束程序的执行。
如果它为true,则什么也不做。
assert定义在cassert头文件里。
预定义的名字有预处理器而不是编译器来管理,因此无需使用using或者std::assert。
NDEBUG决定了assert的开关,如果NDEBUG被定义了,则assert不会做任何事。
一般来说,NDEBUG不会被默认定义,因此assert会进行run-time检查。
可以在文件中#define NDEBUG,也可以把它添加在编译命令中:
$CC -D NDEBUG main.c
记住assert不适合用在运行时候的功能逻辑中的错误检查。
__func__可以表示所在的函数名称。
在main函数里执行:
cout << __func__ << endl;
则会打印:
main
另外还有:
__FILE__ // 文件名称
__LINE__ // 行数
__TIME__ // 文件被编译的时间
__DATE__ // 文件被编译的日期
文章评论(0条评论)
登录后参与讨论