C —— 函数指针

在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。

定义函数指针

因为指针存储的值是一块内存地址,而函数也是在内存的某个地址中,所以,当一个指针指向的内存地址指的是一个函数的话,这种指针被称为函数指针

定义一个函数指针取决于被指向的函数的函数返回类型和参数列表。例如,有函数的定义如下:

int max(int x, int y) {
	return x > y ? x : y
}

则定义一个指针指向该函数的写法是:

int (*p)(int, int) = &max;

声明函数指针需要注意的事项:

  1. 指针对应的数据类型必须与函数返回值一致
  2. 指针参数列表必须与函数参数列表中的数据类型的顺序一致,不需要形参

直接看一个案例,会更容易理解函数指针的定义

#include<stdio.h>

// 声明函数
int fun1();
int fun2(int x, double y);
double fun3(int x, double y, int z, long i);
void fun4(int x);
void fun5(double x, int* p);
int* fun6(int x);

int main() {
	// 声明函数指针
	int (*p1)() = &fun1;
	int (*p2)(int, double) = &fun2;
	double (*p3)(int, double, int, long) = &fun3;
	void (*p4)(int) = &fun4;
	void (*p5)(double, int*) = &fun5;
	int* (*p6)(int) = &fun6;	
	return 0;
}

// 定义函数
int fun1(){return 0;}
int fun2(int x, double y){return 0;}
double fun3(int x, double y, int z, long i){return 0.0;}
void fun4(int x){}
void fun5(double x, int* p){}
int* fun6(int x){return NULL;}

把函数指针看作是一个函数的影子,使其以变量的形式存在于程序中,进而可以到处被传递或者运用。换句话说,函数指针既能像函数一样被使用,又能像变量那样被传递。如下例所示:

#include<stdio.h>

void print(const char * cs) {
	printf("%s\n", cs);
}

int main() {
	void (*p)(const char*) = &print;
	p("Hello World!");
	return 0;
}

执行结果:

Hello World!

再来一个有返回的小案例:

#include<stdio.h>

int max(int x, int y);

int main() {
	int rm, rp, a = 10, b = 3;
	int (*p)(int, int) = &max;	
	
	rm = max(a, b);
	printf("max(%d, %d) = %d\n", a, b, rm);
	
	rp = p(a, b);
	printf("p(%d, %d) = %d\n", a, b, rp);
	
	return 0;
}

int max(int x, int y) {
	return x > y ? x : y;
}

执行结果:

max(10, 3) = 10
p(10, 3) = 10

函数指针作为某个函数的参数

一旦某个指针指向了一个函数后,当该指针以变量的形式传递到某个函数中,那么是能够在目标函数内调用该指针指向的函数的。案例代码如下所示:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define SIZE 6

/**
 * 求两个数的最大值
 */
int max(int x, int y);
/**
 * 得到一个随机的数组指针
 */
int * randArray();
/**
 * 求一个数组中最大的数字
 * @param array 指针数组
 * @param size 数组大小
 * @param *p 求最大值的函数
 */
int maxInArray(int *array, int size, int (*p)(int, int));


int main() {
	int i, mv;
	int * (*p)() = &randArray;
	int (*m)(int, int) = &max;
	// p() 等价于 randArray();
	int *ns = p();
	for(i = 0; i < SIZE; i++, ns++) {
		printf("*ns[%d]=%d.\n", i, *ns);
	}
	// 当遍历结束后, ns 指向的是数组最后一个元素, 需要将其重置到索引为零的指针处
	for(i = SIZE; i > 0; i--) {
		ns--;
	}
	// mv = maxInArray(ns, SIZE, &max);
	mv = maxInArray(ns, SIZE, m);
	printf("max number is %d in array.\n", mv);
	
	return 0;
}


/**
 * 求两个数的最大值
 */
int max(int x, int y) {
	return x > y ? x : y;
}
/**
 * 得到一个随机的数组指针
 */
int * randArray() {
	static int nums[SIZE];
	
	srand((unsigned)time(NULL));
	for(int i = 0; i < SIZE; i++){
		nums[i] = rand();
	}
	return nums;
}
/**
 * 求一个数组中最大的数字
 * @param array 指针数组
 * @param size 数组大小
 * @param *p 求最大值的函数
 */
int maxInArray(int *array, int size, int (*p)(int, int)) {
	int m = 0, i = 0;
	for(int i = 0; i < size; i++, array++) {
		// p(1, 2) 等价于 max(1, 2)
		m = p(m, *array);
	}
	return m;
}

执行结果:

*ns[0]=13213.
*ns[1]=23737.
*ns[2]=15703.
*ns[3]=17692.
*ns[4]=14498.
*ns[5]=26241.
max number is 26241 in array.

本例中,指针 p 和指针 m 都是函数指针,函数指针 p 在 main 函数中被调用,并返回一个数组指针,最后将返回的数组指针 和指针 m 都传递到 maxInArray 函数中,并在函数 maxInArray 中调用指针 m 指向的函数得到最终的结果。

  • 57
    点赞
  • 215
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值