函数指针,就是指向函数的指针啦!(废话)
函数的入口地址
c语言中,一个函数包含了一段代码,这段代码占据了一段内存区域,而函数的名称就是这个内存区域的首地址,也叫做入口地址。
例如下面这个简单的求和函数
int sum(int a, int b)
{
return (a+b);
}
定义之后,sum这个符号就代表了这个函数的入口地址。可以使用printf(“%p\n”, sum);语句将它显示出来
于是,可以把这个入口地址赋值给一个指针变量
函数指针
定义一个函数指针的格式如下
类型名 (* 指针变量名)(参数1, 参数2….);
本例中的指向sum函数的指针可以这样声明
int (* pointer_to_sum)(int a, int b);
这个语句说明,pointer_to_sum是一个函数指针,指向的函数的返回值是int类型,第一个参数是int,第二个参数也是int类型。
之后可以把sum赋值给指针
pointer_to_sum = sum;
然后就可以像使用sum函数一样使用pointer_to_sum了。使用方法是 函数指针(参数); (还可以(*指针)(参数))
函数指针的作用
上面举的例子可能看起来比较奇怪,本来直接用函数名字调用函数就可以了呀,为什么还要弄个指针,在通过指针来调用呢?
确实,在普通调用函数的时候没必要弄函数指针。那么函数指针有什么用呢
函数指针数组或结构体内的函数指针
将许多函数指针放到一个数组中,可以实现在程序运行的时候选择执行哪些函数。将函数指针放到结构体中,可以实现类似c++中类的效果
回调函数
函数指针除了可以调用函数之外,还有一个特别的作用,那就是当做函数的参数,把一个函数传入另一个函数里面,又叫做回调函数。在一些图形库中经常见到啦。这次要说的快排函数qsort也需要一个函数指针参数。
qsort函数
我们先看一下qsort函数的声明。它是在stdlib.h库中的
void qsort( void *ptr, size_t count, size_t size, int (*comp)(const void *, const void *) );
这个函数的功能是对一个数组进行排序。相应的4个参数
- ptr 指向数组的首地址
- count 数组的元素个数
- size 数组的每个元素的大小
- comp 函数指针,说明怎么比较两个元素。也就是两个元素哪个应该在前面,哪个在后面。
这个比较函数的声明应该是这样的
int myCompare(void *a, void *b);
这个函数的输入参数是数组中的两个元素,返回值:
- 如果a排在b的后面,返回正整数
- 如果a排在b的前面,返回负整数
- 如果a和b顺序怎么都可以,返回0
qsort将整形数组按照个位数排序程序示例
这个示例调用了qsort函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include <stdio.h> #include <stdlib.h> int myCompare(void *a, void *b); int main(void) { int i; int a[9] = {34, 54, 65, 6, 21, 11, 32, 79, 39}; qsort(a, 9, sizeof(int), myCompare); for (i = 0; i < 9; ++i) { printf("%d ", a[i]); } return 0; } int myCompare(void *a, void *b) { int n1 = *(int *)a; int n2 = *(int *)b; return (n1 % 10 - n2 %10); } |
该程序运行结果如下