函数指针+回调函数+点云鼠标点选和框选

函数指针+回调函数+点云鼠标点选和框选,第1张

C++函数指针

如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。而且函数名表示的就是这个地址。既然是地址我们就可以定义一个指针变量来存放,这个指针变量就叫作函数指针变量,简称函数指针。

获取函数指针:函数的地址就是函数名,要将函数作为参数进行传递,必须传递函数名。

声明指针时,必须指定指针指向的数据类型,同样,声明指向函数的指针时,必须指定指针指向的函数类型,这意味着声明应当指定函数的返回类型以及函数的参数列表。

函数指针作为参数进行传递时:

void call(int(*callback)(int),int a)  //函数指针作为参数传递的正确写法
void call(int *(callback)(int),int a) //这不是函数指针的声明,这种写法本质上是声明了一个函数叫做callback,其返回值是int数据类型的指针,就是所谓的指针函数。

使用函数指针调用函数:

#include 

int add(int a, int b)
{

	return a + b;
}

void call(int (*callback)(int ,int ),int a ,int b)
{

	std::cout << a << " b: " << b << std::endl;
	std::cout << callback(a, b) << std::endl;
}

int main()
{

	int a = 10;
	int b = 20;
	call(add, a, b);      //函数指针作为参数传递

	int (*p)(int, int);   //声明一个函数指针
	p = add;              //使用指针调用函数,函数名就是函数地址
	std::cout << (*p)(a, b) << std::endl;  //结果是30

	return 0;
}

例程2:

#include 
#include 
#include 

using namespace std;
double* f4(double[], int n);    //声明一个函数,返回值是double数据类型的指针

int main(int argc, char* argv[])
{
	double a[3] = { 12.1, 3.4, 4.5 };

	double* (*p)(double[], int n) = f4;   //声明函数指针,指向f4
	cout << *p(a, 0) << endl; 
	cout << *(*p)(a, 0) << endl;
	cout << (*p)(a, 0) << endl;
	return 0;
}

double* f4(double arr[], int n)
{
	return arr + n;
}

输出结果:

这说明p(a, 0)等价于(*p)(a,0)

指针函数:int* fun(int x,int y);
指针函数本质是一个函数,其返回值为指针。

函数指针:int (*fun)(int x,int y);
函数指针本质是一个指针,其指向一个函数。

再次梳理

int func(int* a, int b)这是一个函数func,参数列表是(int* a,int b),返回值是int数据类型。那么,这个指向这个函数的函数指针可以写成int (p)(int a,int b)。调用这个函数指针可以写成(*p)(&a,b),此时返回的是int类型,按道理可以进一步写成int c = (*p)(&a,b)。

如果返回的不是一个int类型的数据,而是一个函数指针。假如一个函数是func,其参数列表为(int)类型,其返回值是函数指针int (p)(int a,int b)。
使用别名,将PF定义成指向函数类型的指针。

using PF = int (*)(int* a,int b);

那么func的声明就可以写成

PF func(int c);

func需要return一个函数指针,所以先定义这个函数指针。

int f1(int* a, int b)
{
	std::cout << "a: " << &a << " b: " << b << std::endl;
	return b;
}
int (*p)(int *a,int b) = f1; //定义函数指针指向函数f1

此时,就可以写出func的定义:

PF func(int c)
{
	std::cout << "c:" << c << std::endl;
	return *p;  //返回函数指针
}

于是在main函数中可以写成:

int main()
{	
	int c = 10;
	int d = 12
	int e = 13;
	func(c); //输出 c: 10  其实由于func返回的是一个函数指针,而函数指针可以直接(*p)(&a,b)来实现调用。
	int (*p2)(int *,int) = func(c);
	//下列两个等价
	p2(&d,e);
	func(c)(&d,e);

	return 0;
}
数组指针

如果一个数组中的元素有几千个,则一个个的声明指针并赋值显得非常的麻烦和不方便
而数组指针是一种专门用于数组的一种指针。 指针指向一个数组的首地址。

定义数组指针变量:
语法:数据类型 (*数组指针变量名)[元素量];

将数组的地址储存到数组指针变量中:
语法:数组指针变量名 = &数组;

double a[3] = {1.2, 1.3, 1.4};
double*p[3] = a;     //error 错误 这是指针数组的声明方式
double (*p)[3] = a;  //error 错误 a是数组的首个元素首地址
double (*p)[4] = &a; //error 错误 数组指针和数组的长度不相等
double(*p)[3] = &a;  //正确       &a是数组首地址

数组指针的长度必须与指向的数组的长度保持一致。

指针数组

指针的数组可以理解为“指针的数组”,即数组中所有元素都是指针类型的。
语法:数据类型* 指针组名[元素量];

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/2889507.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-14
下一篇 2022-09-14

发表评论

登录后才能评论

评论列表(0条)

保存