这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战
有了指针函数,我们就了解如何整理函数结构,将可复用代码保留也就是函数间共享部分,也可以理解为不变性,然后一些可变的,也就是独特非共享的部分交给使用者来实现。
指针函数,从字面上理解指针是修饰函数的,所以这个本质还是一个函数。也就是函数一种表示方式,接下来将分享什么是指针函数,如何定义一个指针函数以及如何使用指针函数。更重要的是要了解为什么在 c++ 中需要指针函数。
指针就是变量,在这个变量存储而是一个内存空间的地址,通过这个地址我们就可以访问该内存空间,提取内存空间的址。
int getNumber() {
return 5;
}
int main()
{
cout << getNumber();
system("pause>0");
return 0;
}
上面定义了返回 int 类型的函数 getNumber 然后调用函数输出数字 5。
cout << getNumber;
如何我们像上面这样调用一个函数则会返回一个地址,这个地址就是存储函数的地址。这样一来我们就可以定义函数指针,谈到指针就需要考虑指针指向数据的类型,这一次类型是一个函数。
int(*funcPtr)();
int getNumber() {
return 5;
}
int main()
{
int(*funcPtr)() = getNumber;
cout << funcPtr();
system("pause>0");
return 0;
}
int(*funcPtr)() = getNumber; 首先我们定义一个指针,指针也是一个变量,为了区别其他变量这里在指针变量前加一个星号 * 然后就是要定义指针指向函数返回值和参数int(*funcPtr)()。然后就是通过指针来调用函数 funcPtr()。接下来我们进一步演示如何定义指向带有参数函数 int add(int a,int b) 的指针,以及如何通过指针来调用该函数。
#include <iostream>
using namespace std;
int add(int a, int b) {
return a + b;
}
int main()
{
int(*addPtr)(int,int) = add;
cout << addPtr(2,3);
system("pause>0");
return 0;
}
接下来我们通过一个例子来带入介绍我们为什么需要指针函数, 其实所以用指针函数主要目的就是将函数作为其他函数参数,来将函数传入到其他函数,熟悉 js 或者其他支持函数式编程的语音应该对这个不难理解,这样可以轻松实现回调函数。
#include <iostream>
#include<vector>
using namespace std;
bool ascendingCompare(int a, int b) {
return a < b;
}
bool descendingCompare(int a, int b) {
return a > b;
}
void sortAscending(vector<int>& numbersVector) {
for (int startIndex = 0; startIndex < numbersVector.size(); startIndex++)
{
int bestIndex = startIndex;
for (int currentIndex = startIndex + 1; currentIndex < numbersVector.size(); currentIndex++)
{
if (ascendingCompare(numbersVector[currentIndex], numbersVector[bestIndex]))
bestIndex = currentIndex;
}
swap(numbersVector[startIndex], numbersVector[bestIndex]);
}
}
void sortDescending(vector<int>& numbersVector) {
for (int startIndex = 0; startIndex < numbersVector.size(); startIndex++)
{
int bestIndex = startIndex;
for (int currentIndex = startIndex + 1; currentIndex < numbersVector.size(); currentIndex++)
{
if (descendingCompare(numbersVector[currentIndex], numbersVector[bestIndex]))
bestIndex = currentIndex;
}
swap(numbersVector[startIndex], numbersVector[bestIndex]);
}
}
void printNumber(vector<int>& numbersVector) {
for (auto i : numbersVector)
{
cout << i << " ";
}
}
int main()
{
vector<int> myNumbers = { 2,3,1,5,7 };
sortAscending(myNumbers);
printNumber(myNumbers);
system("pause>0");
return 0;
}
上面代码有点长,我们还是一一道来,首先看
bool ascendingCompare(int a, int b) {
return a < b;
}
bool descendingCompare(int a, int b) {
return a > b;
}
ascendingCompare 和 descendingCompare 这两个函数比较简单,主要实现对比两个函数大小,第一个 ascendingCompare 当传入的第一个参数小于第二个参数时返回 True 否则返回 False。这里选择vector作为容器,接下里 sortAscending 和 sortDescending 函数主要是对列表进行升序和降序排列,我们看这两个函数 sortAscending 和 sortDescending 结构大概相同,只是比较大小时候用到不同比较函数而已。这时候我们指针函数就派上用场来解决这个问题。
也就是保留两个函数 sortAscending 和 sortDescending 共享部分,然后将变化,不同部分提取出来交给使用者来实现。
接下来我们定义函数 customSort 这个函数除了接受一个 vector 容器列表,还接受一个指针函数作为第二个参数 bool (*compareFuncPtr)(int ,int)
void customSort(vector<int>& numbersVector,bool (*compareFuncPtr)(int ,int)) {
for (int startIndex = 0; startIndex < numbersVector.size(); startIndex++)
{
int bestIndex = startIndex;
for (int currentIndex = startIndex + 1; currentIndex < numbersVector.size(); currentIndex++)
{
if (compareFuncPtr(numbersVector[currentIndex], numbersVector[bestIndex]))
bestIndex = currentIndex;
}
swap(numbersVector[startIndex], numbersVector[bestIndex]);
}
}
然后将函数比较两个元素大小函数换成传入指针函数,这样就是实现将函数作为参数传入到另一个函数的功能。
bool(*funcPtr)(int,int) = ascendingCompare;
customSort(myNumbers,funcPtr);