函数指针和指针函数虽然都涉及到指针,但它们的本质不同。其差别主要在于指针变量所指向的内容和使用方式。
1.指针函数
指针函数则是指返回指针类型的函数,它的返回值是一个指针。指针函数的声明形式为“返回类型 (*函数名称)(参数列表)”。如:
int* func(int a, int b); // 声明一个返回指向int类型的指针的函数,参数列表为两个int类型的参数。
常见的指针函数包括:
- int *max(int a[], int n):返回一个整型数组a中最大值的指针。
- char *str(char *s):返回一个指向字符串s的指针。
- void *malloc(size_t size):动态分配内存,返回指向分配的内存块的指针。
- int (*func)(int a, int b):返回一个指向函数的指针,该函数接受两个int类型的参数,并返回一个int类型的值。
#include <stdio.h>
// 返回一个整型数组a中最大值的指针。
int *max(int a[], int n) {
int *p = a;
for (int i = 0; i < n; i++) {
if (*p < a[i]) {
p = &a[i];
}
}
return p;
}
// 返回一个指向字符串s的指针。
char *str(char *s) {
return s;
}
// 动态分配内存,返回指向分配的内存块的指针。
void *malloc(size_t size) {
void *p = NULL;
if (size > 0) {
p = (void *)malloc(size);
}
return p;
}
// 这里用到的是函数指针,请看下面的说明!
//返回一个指向函数的指针,该函数接受两个int类型的参数,并返回一个int类型的值。
int add(int a, int b) {
return a + b;
}
int (*func)(int a, int b) = add;
int main() {
int a[5] = {1, 3, 2, 5, 4};
int *p_max = max(a, 5);
printf("最大值为:%d\n", *p_max);
char *s = "Hello world!";
printf("%s\n", str(s));
int *p_malloc = (int *)malloc(sizeof(int));
*p_malloc = 100;
printf("%d\n", *p_malloc);
int sum = func(1, 2);
printf("%d\n", sum);
return 0;
}
2. 函数指针
函数指针是指向函数的指针变量,可以用于调用函数。
函数指针是指向函数的指针变量。它存储的是函数的地址,函数指针可以用来调用函数,也可以作为函数参数传递给其他函数。
int (*func_ptr)(int, int); // 声明一个返回类型为int的函数指针,参数列表为两个int类型的参数
函数指针的几个应用:
-
回调函数:回调函数是一种常用的编程技巧,可以在程序中实现灵活的控制结构。它通常用函数指针作为参数,在某个事件发生时被调用。
-
动态链接库:动态链接库是可运行的代码和数据的集合,可以在程序运行时加载和卸载。函数指针可以用来在程序运行时动态地加载和调用库函数。
-
排序算法:常见的排序算法如快速排序、冒泡排序等都需要比较函数作为参数。使用函数指针可以在不修改排序算法本身的情况下改变比较方式。
-
系统调用:系统调用是操作系统提供给用户程序使用的接口。用户程序可以通过函数指针来调用系统调用,实现操作系统提供的功能。
函数指针的声明形式为“返回类型 (*指针名称)(参数列表)”。
例1:
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
int (*func_ptr)(int, int); // 声明函数指针变量
func_ptr = &add; // 给函数指针变量赋值
int result = (*func_ptr)(2, 3); // 使用函数指针调用函数
printf("Result: %d\n", result); // 输出结果
return 0;
}
这里定义了一个名为add
的函数用于计算两个整数的和。然后声明了一个指向函数的指针变量func_ptr
,并将其赋值为&add
,表示指针变量指向add
函数的内存地址。最后,使用(*func_ptr)(2, 3)
的形式调用函数,并将结果存储在变量result
中,并输出结果。
#include <stdio.h>
// 声明一个函数指针类型
typedef int (*FuncPtr)(int, int);
// 定义一个函数,用于计算两个整数之和
int sum(int a, int b) {
return a + b;
}
// 定义一个函数,用于计算两个整数之差
int sub(int a, int b) {
return a - b;
}
// 定义一个函数,用于执行函数指针并输出结果
void execute(FuncPtr func, int a, int b) {
int result = func(a, b);
printf("result = %d\n", result);
}
int main() {
int a = 4, b = 2;
execute(sum, a, b); // 输出 6
execute(sub, a, b); // 输出 2
return 0;
}
这里首先声明了一个函数指针类型 FuncPtr
,用于指向具有两个 int
类型参数和 int
返回值的函数。接着,定义了两个函数 sum
和 sub
,分别用于计算两个整数之和和差。在 execute
函数中,我们接受一个函数指针 func
,以及两个整数 a
和 b
,并执行函数指针,并输出结果。
在 main
函数中,我们定义了两个整数 a
和 b
,分别为 4 和 2,然后分别调用 execute
函数,传入 sum
和 sub
函数指针,输出计算结果。
运行上面的代码,输出结果如下:
result = 6
result = 2
上面使用了两种不同的调用方法