函数指针和指针函数的区别与使用(C语言小白也能看懂)
本文用“先结论后示例”的方式讲清 C 语言中最容易混淆的两个概念:函数指针和指针函数。你将学会如何快速区分两者、正确声明与调用、在回调和函数表中的实际用法,以及常见错误(类型不匹配、返回局部变量地址等)的规避方法。文末附可直接编译运行的完整示例。
函数指针和指针函数的区别与使用(C语言小白也能看懂) 很多同学第一次看到下面两行代码会懵:
int (*fp)(int, int);
int *func(int, int);它们看起来很像,但含义完全不同。本文带你一次讲透。
一、先记住核心区别
函数指针:本质是指针,这个指针指向一个函数。 指针函数:本质是函数,这个函数的返回值是一个指针。
一句话口诀:
`(*xxx)` 大概率是“xxx 是指针”(函数指针)
`xxx(...)` 大概率是“xxx 是函数”(指针函数)
二、函数指针:指向函数的指针
1)声明形式
返回类型 (*指针名)(参数列表);示例:
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
int (*fp)(int, int); // 函数指针
fp = add; // 或 fp = &add
printf("%d\n", fp(2, 3)); // 5
return 0;
}2)常见用途
回调函数(最常见) 函数分发(函数表) 策略切换(不同算法动态替换)
3)回调示例
#include <stdio.h>
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int calc(int x, int y, int (*op)(int, int)) {
return op(x, y);
}
int main() {
printf("add: %d\n", calc(10, 3, add)); // 13
printf("sub: %d\n", calc(10, 3, sub)); // 7
return 0;
}三、指针函数:返回指针的函数
1)声明形式
返回类型* 函数名(参数列表);示例:
#include <stdio.h>
int* getMaxPtr(int *a, int *b) { // 指针函数
return (*a > *b) ? a : b;
}
int main() {
int x = 10, y = 20;
int *p = getMaxPtr(&x, &y);
printf("max = %d\n", *p); // 20
return 0;
}2)常见用途
返回数组或缓冲区地址 返回结构体/链表节点指针 在数据结构中返回“找到的目标地址”
四、最容易混淆的写法对比
int (*fp)(int, int); // 函数指针:fp 是指针
int *func(int, int); // 指针函数:func 是函数,返回 int*关键是看变量名和谁先结合:
`fp` 被 `(*fp)` 包起来,说明它是指针;
`func` 后面直接是 `()`,说明它是函数。
五、推荐写法:typedef 提高可读性
函数指针原写法不好读,建议使用 `typedef`:
#include <stdio.h>
typedef int (*OpFunc)(int, int);
int mul(int a, int b) { return a * b; }
int divi(int a, int b) { return b == 0 ? 0 : a / b; }
int apply(int x, int y, OpFunc f) {
return f(x, y);
}
int main() {
printf("mul: %d\n", apply(12, 3, mul)); // 36
printf("div: %d\n", apply(12, 3, divi)); // 4
return 0;
}六、实战:函数指针数组做“迷你计算器”
#include <stdio.h>
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }
int divi(int a, int b) { return b == 0 ? 0 : a / b; }
int main() {
int (*ops[4])(int, int) = {add, sub, mul, divi};
const char *names[4] = {"add", "sub", "mul", "div"};
int x = 20, y = 5;
for (int i = 0; i < 4; i++) {
printf("%s(%d, %d) = %d\n", names[i], x, y, ops[i](x, y));
}
return 0;
}七、常见坑(面试和考试都爱问)
1)返回局部变量地址(危险)
int* wrong() {
int x = 10;
return &x; // 错误:x 是局部变量,函数结束后地址失效
}2)函数指针类型不匹配
int f(int a);
double (*p)(int); // 不能指向 f,返回类型不一致3)少了括号语义就变了
int *fp(int, int); // 指针函数
int (*fp)(int, int); // 函数指针八、总结
函数指针:指向函数,用来“把函数当参数传来传去”。 指针函数:返回地址,用来“把某块内存/对象地址返回给调用方”。 记忆重点:`()` 优先级高于 `*`,必要时用括号明确含义。 工程建议:函数指针优先搭配 `typedef`,代码更清晰、更易维护。
如果你是新手,建议先把文中的 4 个示例都自己敲一遍,再改参数和返回值做实验,理解会非常扎实。
评论 (1)
评论提交后公开展示可能会有延迟。
如填写邮箱,可选择接收评论通知。
提示
有点懂了