指针—指针函数

259 阅读3分钟

这是我参与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);