C语言函数指针 #
一、函数指针基础 #
1.1 什么是函数指针 #
函数指针是指向函数的指针变量。
c
int add(int a, int b) {
return a + b;
}
int (*p)(int, int) = add;
1.2 函数名与函数指针 #
函数名是函数的入口地址:
c
#include <stdio.h>
void hello() {
printf("Hello, World!\n");
}
int main() {
printf("函数地址: %p\n", (void*)hello);
printf("函数地址: %p\n", (void*)&hello);
void (*p)() = hello;
p();
return 0;
}
1.3 声明语法 #
c
返回类型 (*指针名)(参数类型列表);
示例:
c
int (*p1)(int);
int (*p2)(int, int);
void (*p3)(void);
char* (*p4)(const char*);
二、函数指针使用 #
2.1 基本使用 #
c
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
int (*p)(int, int) = add;
printf("直接调用: %d\n", add(10, 5));
printf("指针调用: %d\n", p(10, 5));
printf("指针调用: %d\n", (*p)(10, 5));
return 0;
}
2.2 函数指针赋值 #
c
#include <stdio.h>
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int main() {
int (*p)(int, int);
p = add;
printf("加法: %d\n", p(10, 5));
p = subtract;
printf("减法: %d\n", p(10, 5));
return 0;
}
2.3 typedef简化 #
c
#include <stdio.h>
typedef int (*Operation)(int, int);
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int main() {
Operation op = add;
printf("结果: %d\n", op(10, 5));
return 0;
}
三、函数指针数组 #
3.1 定义函数指针数组 #
c
#include <stdio.h>
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return a / b; }
int main() {
int (*operations[4])(int, int) = {add, subtract, multiply, divide};
char* names[] = {"+", "-", "*", "/"};
int a = 20, b = 4;
for (int i = 0; i < 4; i++) {
printf("%d %s %d = %d\n", a, names[i], b, operations[i](a, b));
}
return 0;
}
输出:
text
20 + 4 = 24
20 - 4 = 16
20 * 4 = 80
20 / 4 = 5
3.2 使用typedef #
c
#include <stdio.h>
typedef int (*Operation)(int, int);
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int main() {
Operation ops[] = {add, subtract};
for (int i = 0; i < 2; i++) {
printf("结果: %d\n", ops[i](10, 5));
}
return 0;
}
3.3 菜单系统 #
c
#include <stdio.h>
void menu_new() { printf("新建文件\n"); }
void menu_open() { printf("打开文件\n"); }
void menu_save() { printf("保存文件\n"); }
void menu_exit() { printf("退出程序\n"); }
int main() {
void (*menu[])(void) = {menu_new, menu_open, menu_save, menu_exit};
char* names[] = {"新建", "打开", "保存", "退出"};
int choice;
while (1) {
printf("\n===== 菜单 =====\n");
for (int i = 0; i < 4; i++) {
printf("%d. %s\n", i + 1, names[i]);
}
printf("请选择: ");
scanf("%d", &choice);
if (choice >= 1 && choice <= 4) {
menu[choice - 1]();
if (choice == 4) break;
} else {
printf("无效选择\n");
}
}
return 0;
}
四、回调函数 #
4.1 什么是回调函数 #
回调函数是作为参数传递给其他函数的函数指针。
4.2 基本回调 #
c
#include <stdio.h>
void process(int arr[], int size, void (*callback)(int)) {
for (int i = 0; i < size; i++) {
callback(arr[i]);
}
}
void print_value(int value) {
printf("%d ", value);
}
void print_square(int value) {
printf("%d ", value * value);
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
printf("原值: ");
process(arr, 5, print_value);
printf("\n");
printf("平方: ");
process(arr, 5, print_square);
printf("\n");
return 0;
}
4.3 qsort回调 #
c
#include <stdio.h>
#include <stdlib.h>
int compare_asc(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
int compare_desc(const void* a, const void* b) {
return (*(int*)b - *(int*)a);
}
void print_array(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int arr[] = {5, 2, 8, 1, 9, 3};
int size = sizeof(arr) / sizeof(arr[0]);
qsort(arr, size, sizeof(int), compare_asc);
printf("升序: ");
print_array(arr, size);
qsort(arr, size, sizeof(int), compare_desc);
printf("降序: ");
print_array(arr, size);
return 0;
}
4.4 查找函数 #
c
#include <stdio.h>
#include <stdbool.h>
int* find_if(int* start, int* end, bool (*predicate)(int)) {
while (start < end) {
if (predicate(*start)) {
return start;
}
start++;
}
return NULL;
}
bool is_even(int n) { return n % 2 == 0; }
bool is_positive(int n) { return n > 0; }
bool is_greater_than_10(int n) { return n > 10; }
int main() {
int arr[] = {-5, 3, 8, 2, 15, 7};
int size = sizeof(arr) / sizeof(arr[0]);
int* p = find_if(arr, arr + size, is_even);
if (p) printf("第一个偶数: %d\n", *p);
p = find_if(arr, arr + size, is_positive);
if (p) printf("第一个正数: %d\n", *p);
p = find_if(arr, arr + size, is_greater_than_10);
if (p) printf("第一个大于10的数: %d\n", *p);
return 0;
}
五、高级应用 #
5.1 策略模式 #
c
#include <stdio.h>
typedef int (*Strategy)(int, int);
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
typedef struct {
Strategy strategy;
char* name;
} Calculator;
int calculate(Calculator* calc, int a, int b) {
printf("%s: ", calc->name);
return calc->strategy(a, b);
}
int main() {
Calculator calculators[] = {
{add, "加法"},
{subtract, "减法"},
{multiply, "乘法"}
};
for (int i = 0; i < 3; i++) {
printf("%s\n", calculate(&calculators[i], 10, 5));
}
return 0;
}
5.2 事件处理 #
c
#include <stdio.h>
typedef void (*EventHandler)(int);
typedef struct {
EventHandler onClick;
EventHandler onHover;
EventHandler onKeyPress;
} Button;
void handle_click(int id) {
printf("按钮 %d 被点击\n", id);
}
void handle_hover(int id) {
printf("鼠标悬停在按钮 %d 上\n", id);
}
void handle_key(int id) {
printf("按钮 %d 接收到按键\n", id);
}
int main() {
Button btn = {handle_click, handle_hover, handle_key};
btn.onClick(1);
btn.onHover(1);
btn.onKeyPress(1);
return 0;
}
5.3 插件系统 #
c
#include <stdio.h>
typedef void (*PluginInit)(void);
typedef void (*PluginProcess)(int);
typedef void (*PluginCleanup)(void);
typedef struct {
PluginInit init;
PluginProcess process;
PluginCleanup cleanup;
char* name;
} Plugin;
void plugin_a_init() { printf("插件A初始化\n"); }
void plugin_a_process(int data) { printf("插件A处理: %d\n", data); }
void plugin_a_cleanup() { printf("插件A清理\n"); }
void plugin_b_init() { printf("插件B初始化\n"); }
void plugin_b_process(int data) { printf("插件B处理: %d\n", data * 2); }
void plugin_b_cleanup() { printf("插件B清理\n"); }
int main() {
Plugin plugins[] = {
{plugin_a_init, plugin_a_process, plugin_a_cleanup, "PluginA"},
{plugin_b_init, plugin_b_process, plugin_b_cleanup, "PluginB"}
};
int count = 2;
for (int i = 0; i < count; i++) {
plugins[i].init();
}
for (int i = 0; i < count; i++) {
plugins[i].process(10);
}
for (int i = 0; i < count; i++) {
plugins[i].cleanup();
}
return 0;
}
六、函数指针与结构体 #
6.1 方法模拟 #
c
#include <stdio.h>
typedef struct {
int value;
void (*set)(struct Number*, int);
int (*get)(struct Number*);
void (*print)(struct Number*);
} Number;
void number_set(Number* self, int value) {
self->value = value;
}
int number_get(Number* self) {
return self->value;
}
void number_print(Number* self) {
printf("值: %d\n", self->value);
}
Number create_number(int value) {
Number n = {value, number_set, number_get, number_print};
return n;
}
int main() {
Number n = create_number(10);
n.print(&n);
n.set(&n, 20);
printf("获取值: %d\n", n.get(&n));
return 0;
}
七、总结 #
函数指针语法 #
c
返回类型 (*指针名)(参数列表);
typedef简化 #
c
typedef int (*FuncType)(int, int);
FuncType p = add;
函数指针数组 #
c
int (*arr[])(int, int) = {add, subtract};
回调函数 #
c
void process(int arr[], int size, void (*callback)(int));
应用场景 #
| 场景 | 说明 |
|---|---|
| 回调函数 | 事件处理、异步操作 |
| 策略模式 | 运行时选择算法 |
| 插件系统 | 动态加载功能 |
| 菜单系统 | 函数映射 |
| 排序比较 | qsort比较函数 |
下一步,让我们学习数组!
最后更新:2026-03-26