第六章_函数_6.5 特殊用途语言特性

6.5 特殊用途语言特性

6.5.1 默认实参

形参在函数的多次调用中都被赋予一个相同的值,把这个反复出现的值称为函数的默认实参(default argument)。

调用含有默认实参的函数时,可以包含该实参,也可以省略该实参。

typedef string::size_type sz;
string screen(sz ht = 24, sz wid = 80, char backgrnd = ' ');

一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值。

使用默认实参调用函数

使用默认实参,只要在调用函数的时候省略该实参就可以了。

string window;					
window = screen();				// 等价于 screen(24, 80, ' ')
window = screen(66);			// 等价于 screen(66, 80, ' ')
window = screen(66, 256);		// 等价于 screen(24, 256, ' ')
window = screen(66, 256, '#');	// 等价于 screen(24, 256, '#')

函数调用时实参按其位置解析,默认实参负责填补函数调用缺少的尾部实参(靠右侧位置)。

默认实参声明

在给定的作用域中一个形参只能被赋予一次默认实参。函数的后续声明只能为之前那些没有默认值的形参添加默认实参,而且该形参右侧的所有形参必须都有默认值。

string screen(sz, sz, char = ' ');
string screen(sz, sz, char = '*');		// 错误:重复声明
string screen(sz = 24, sz = 80, char);	// 正确:添加默认实参

默认实参初始值

局部变量不能作为默认实参。除此之外,只要表达式的类型能转换成形参所需的类型,该表达式就能作为默认实参。

用作默认实参的名字在函数声明所在的作用域内解析,而这些名字的求值过程发生在函数调用时。

6.5.2 内联函数和 constexptr 函数

内联函数可避免函数调用的开销

将函数制定为内联函数(inline),通常就是将它在每个调用点上“内联地”展开。

inline const string &shorterString(const string &s1, const string &s2);

如下调用

cout << shorterString(s1, s2) << endl;

将在编译过程中展开为

cout << (s1.size() <= s2.size() ? s1 : s2) << endl;

constexpr 函数

constexpr 函数是指能用于常量表达式的函数。

定义 constexptr 函数需要遵循:函数的返回类型及所有形参的类型都得是字面值类型,而且函数体中必须有且仅有一条 return 语句。

constexpr int new_sz() { return 42; }
constexpr int foo = new_sz();

constexpr 函数体内也可以包含其他语句,只要这些语句在运行时不执行任何操作就行。

允许 constexptr 函数的返回值并非一个常量

constexpr size_t scale(size_t cnt) { return new_sz() * cnt; }

把内联函数和 constexptr 函数放在头文件内

6.5.3 调试帮助

assert 预处理宏

assert 宏使用一个表达式作为它的条件:

assert(expr);

首先对expr求值,如果表达式为假,assert 输出信息并终止程序的执行;如果表达式为真,assert 什么也不做。

assert 宏常用与检查“不能发生”的条件。

NDEBUG 预处理变量

assert 的行为依赖于一个名为 NDEBUG 的预处理变量的状态。如果定义了 NDEBUG,则 assert 什么也不做。默认状态下没有定义 NDEBUG,此时 assert 将执行运行时检查。

预处理器定义了几个用于程序调试的名字:

_ _func_ _ 存放函数的名字
_ _FILE_ _ 存放文件名的字符串字面值
_ _LINE_ _ 存放当前行号的整型字面值
_ _TIME_ _ 存放编译时间的字符串字面值
_ _DATE_ _ 存放编译日期的字符串字面值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值