如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。而且函数名表示的就是这个地址。既然是地址我们就可以定义一个指针变量来存放,这个指针变量就叫作函数指针变量,简称函数指针。
获取函数指针:函数的地址就是函数名,要将函数作为参数进行传递,必须传递函数名。
声明指针时,必须指定指针指向的数据类型,同样,声明指向函数的指针时,必须指定指针指向的函数类型,这意味着声明应当指定函数的返回类型以及函数的参数列表。
函数指针作为参数进行传递时:
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是数组首地址
数组指针的长度必须与指向的数组的长度保持一致。
指针数组指针的数组可以理解为“指针的数组”,即数组中所有元素都是指针类型的。
语法:数据类型* 指针组名[元素量];
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)