开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情
6.5.3 调试帮助
assert预处理宏
所谓预处理宏就是一个预处理变量,类似于内联函数。
NDEBUG预处理变量
如果定义了NDEBUG,assert什么也不做
$ CC -D NDEBUG main.C 等价于在main.c文件一开始写#define NDEBUG
6.6 函数匹配
1、选定本次调用对应重载函数集,集合中的函数称为候选函数
2、考察本次调用提供的实参,然后从候选函数中选出能被实参调用的函数,新选出的函数称为可行函数
3、从可行函数中寻找本次调用最匹配的函数
匹配成功的条件:
- 该函数每个实参的匹配都不劣于其他可行函数需要的匹配
- 至少有一个实参的匹配优于其他可行函数提供的匹配
6.7 函数指针
bool (*pf)(const string&, const string&); //未初始化
(*pf)两端的括号必不可少,不然就是一个返回值为bool指针的函数
函数指针形参
形参可以是指向函数的指针
返回指向函数的指针
using F = int(int*, int); //F是函数类型,不是指针
using PF = int(*)(int*, int); //PF是指针类型
法1:
PF f1(int);
F f1(int); //err 不可以返回一个函数
F *f1(int);
法2:
int (*f1(int))(int*, int);
法3:尾置返回
auto f1(int) -> int (*)(int*, int);
//be类型由编译器决定
//b表示v的第一个元素, e表示v尾元素的下一位置
auto b = v.begin(), e = end(); //b e 类型相同
特殊情况下如果容器为空,则begin和end返回同一个迭代器
标准容器迭代器的运算符
| *iter | 返回迭代器iter所指元素的引用 |
|---|---|
| iter->mem | 解引用iter并获取该元素的名为mem的成员,等价于*(iter).mem |
| ++iter | 令iter指示容器中下一个元素 |
| --iter | 令iter指示容器中上一个元素 |
| iter1 == iter2 | 两个迭代器相等,返回1 |
| iter != iter2 | 不相等返回1 |
注意:end返回的迭代器并不实际指示某一个元素,所以不能对其进行递增或解引用的操作
迭代器的类型分为:iterator, const_iterator。其中const_iterator只能读不能写
begin和end返回的具体类型由对象是否是常量决定
const vector<int> cv;
auto it1 = cv.begin(); //it1的类型是const_iterator
vector<int> v;
auto it2 = v.cbegin();//it2的类型是const_iterator 不论v是不是常量
对于成员访问操作,在实际使用中遇到以下问题,在这里标记记录一下
vector<string> str{"helloworld"};
auto itStr = str.begin();
if (itStr->empty()) cout << "空" << endl;
//对于vector<int>的迭代器,不可以使用empty
vector<int> nums{1,2,3,4};
auto itNums = nums.begin();
if (itNums->empty()) cout << "空" << endl; //err
警告:但凡是使用了迭代器的循环体,都不可以向迭代器所属的容器添加元素因为一旦改变了vector对象容量,都会使vector对象的迭代器失效。