函数、指针,这两个词仅仅交换了顺序,意义却大相径庭,这就是“指针函数”与“函数指针”常常让初学者感到困惑的原因。今天我们就来彻底厘清这两个核心概念,并通过代码示例直观地展示它们的区别与应用。
指针函数:返回指针的函数
指针函数,其本质是一个函数,只不过它的返回值是一个指针。理解它的关键在于操作符的优先级。
看看这个声明:
int *pfun(int, int);
由于 () 的优先级高于 *,所以 pfun 会先与 (int, int) 结合,表明 pfun 是一个函数。接着,前面的 * 再与 pfun(int, int) 结合,说明这个函数的返回值是一个指针。而最前面的 int 指明了这个指针指向整型数据。因此,pfun 是一个返回值为整型指针的函数。
下面是一个完整的指针函数示例程序:
#include <stdio.h>
// 指针函数的声明
int *pfun(int *arr, int n);
int main(void)
{
int array[] = {0, 1, 2, 3, 4};
int len = sizeof(array)/sizeof(array[0]);
int *p;
int i;
// 指针函数的调用,获取返回的指针
p = pfun(array, len);
for (i = 0; i < len; i++)
{
printf("array[%d] = %d\n", i, *(p+i));
}
return 0;
}
// 指针函数的定义:返回指向数组首地址的指针
int *pfun(int *arr, int n)
{
int *p = arr;
return p;
}
在这段代码中,pfun 函数接收一个数组首地址和长度,并直接将这个地址返回。主函数中通过调用 pfun 获得了指向数组的指针,进而遍历并打印了所有数组元素。
编译并运行上述程序,结果如下:

函数指针:指向函数的指针
与指针函数相反,函数指针的本质是一个指针变量,只不过这个指针指向了一个函数。C程序在编译时,每个函数都有一个入口地址,函数指针存储的就是这个地址。
声明一个函数指针的语法如下:
/* 声明一个函数指针 */
int (*fptr) (int, int);
/* 函数指针指向函数func */
fptr = func; // 或者 fptr = &func;
这里,fptr 就是一个指向“返回值为 int,且接受两个 int 型参数”的函数的指针。需要注意的是,函数名 func 和对其取地址 &func 都表示函数的入口地址,两者等价。
在调用时,既可以使用 (*fptr)(1, 2),也可以直接使用 fptr(1, 2),这两种方式也是等价的。
来看看函数指针的实际应用示例:
#include <stdio.h>
int add(int a, int b);
int main(void)
{
int (*fptr)(int, int); // 定义一个函数指针
int res;
fptr = add; // 函数指针fptr指向函数add
/* 通过函数指针调用函数 */
res = (*fptr)(1,2); // 等价于 res = fptr(1,2);
printf(“a + b = %d\n“, res);
return 0;
}
int add(int a, int b)
{
return a + b;
}
在这个例子中,我们定义了一个函数指针 fptr,让它指向加法函数 add,然后通过这个指针来调用函数,实现了计算并输出结果。

核心区别与应用场景
简单总结一下:
- 指针函数:重点在“函数”,它是一种返回类型为指针的函数。
- 函数指针:重点在“指针”,它是一个用来存放函数入口地址的变量。
两者最直观的区分方法是看 * 号被谁“管住”。在 int *func(...) 中,* 属于返回类型,所以是指针函数;在 int (*func)(...) 中,* 被括号与 func 绑定,func 首先是个指针,所以是函数指针。
函数指针在嵌入式开发等领域应用极为广泛,其主要用途有两个:
- 回调函数(Callback):将函数指针作为参数传递给另一个函数,在特定条件或事件发生时被调用。这在事件驱动、中断处理和模块解耦中非常常见。
- 实现函数表(Dispatch Table):用函数指针数组来根据不同的索引或命令调用不同的函数,常用于状态机、命令解析器等场景。
理解并熟练运用函数指针和指针函数,是深入掌握C语言编程,特别是进行系统级和嵌入式软件开发的关键一步。希望本文的梳理能帮助你清晰地区分它们。