跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C 语言回调函数
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{DISPLAYTITLE:C语言回调函数}} == 简介 == '''回调函数'''是C语言中一种重要的编程技术,它允许函数作为参数传递给另一个函数,并在特定事件或条件发生时被调用。这种机制在事件驱动编程、异步操作和模块化设计中广泛应用。 回调函数的本质是: * 一个函数的指针被传递给另一个函数(通常称为"高阶函数") * 高阶函数在适当的时候通过这个指针调用传递进来的函数 * 实现调用方与被调用方之间的松耦合 == 基本概念 == === 函数指针 === 回调函数的基础是函数指针,即指向函数的指针变量。其声明语法为: <syntaxhighlight lang="c"> 返回类型 (*指针变量名)(参数列表); </syntaxhighlight> 例如: <syntaxhighlight lang="c"> int (*func_ptr)(int, float); // 声明一个函数指针 </syntaxhighlight> === 回调函数的工作原理 === <mermaid> sequenceDiagram participant A as 调用函数 participant B as 回调函数 A->>B: 注册回调函数(传递函数指针) A->>A: 执行某些操作 A->>B: 在特定条件下调用回调函数 B->>A: 返回结果或执行操作 </mermaid> == 基本示例 == === 简单回调示例 === <syntaxhighlight lang="c"> #include <stdio.h> // 回调函数类型定义 typedef void (*Callback)(int); // 高阶函数,接受回调函数作为参数 void processNumbers(int arr[], int size, Callback callback) { for (int i = 0; i < size; i++) { callback(arr[i]); // 调用回调函数 } } // 具体的回调函数实现 void printNumber(int num) { printf("Number: %d\n", num); } void squareNumber(int num) { printf("%d squared is %d\n", num, num * num); } int main() { int numbers[] = {1, 2, 3, 4, 5}; int size = sizeof(numbers) / sizeof(numbers[0]); printf("Printing numbers:\n"); processNumbers(numbers, size, printNumber); printf("\nCalculating squares:\n"); processNumbers(numbers, size, squareNumber); return 0; } </syntaxhighlight> '''输出:''' <pre> Printing numbers: Number: 1 Number: 2 Number: 3 Number: 4 Number: 5 Calculating squares: 1 squared is 1 2 squared is 4 3 squared is 9 4 squared is 16 5 squared is 25 </pre> == 高级应用 == === 带上下文数据的回调 === 有时回调函数需要访问额外的数据(称为上下文或状态),可以通过以下方式实现: <syntaxhighlight lang="c"> #include <stdio.h> // 带上下文的回调函数类型 typedef void (*ContextCallback)(int, void*); void processWithContext(int arr[], int size, ContextCallback callback, void* context) { for (int i = 0; i < size; i++) { callback(arr[i], context); } } // 回调函数示例 void accumulate(int num, void* context) { int* sum = (int*)context; *sum += num; } int main() { int numbers[] = {1, 2, 3, 4, 5}; int size = sizeof(numbers) / sizeof(numbers[0]); int total = 0; processWithContext(numbers, size, accumulate, &total); printf("Total sum: %d\n", total); // 输出: Total sum: 15 return 0; } </syntaxhighlight> === 回调链 === 多个回调函数可以串联起来形成处理流水线: <syntaxhighlight lang="c"> #include <stdio.h> typedef int (*Transformer)(int); int applyTransformers(int value, Transformer transformers[], int count) { for (int i = 0; i < count; i++) { value = transformers[i](value); } return value; } int addOne(int x) { return x + 1; } int doubleIt(int x) { return x * 2; } int square(int x) { return x * x; } int main() { Transformer transforms[] = {addOne, doubleIt, square}; int result = applyTransformers(3, transforms, 3); printf("Result: %d\n", result); // 输出: Result: 64 ((3+1)*2)^2 return 0; } </syntaxhighlight> == 实际应用场景 == === 事件处理系统 === 在GUI或游戏开发中,回调函数常用于处理用户输入事件: <syntaxhighlight lang="c"> typedef void (*EventHandler)(int eventType, void* eventData); struct Button { EventHandler onClick; }; void buttonClick(struct Button* btn, int eventType, void* eventData) { if (btn->onClick) { btn->onClick(eventType, eventData); } } void handleLoginClick(int eventType, void* eventData) { printf("Login button clicked!\n"); // 处理登录逻辑... } int main() { struct Button loginButton; loginButton.onClick = handleLoginClick; // 模拟按钮点击 buttonClick(&loginButton, 1, NULL); return 0; } </syntaxhighlight> === 排序算法中的比较函数 === C标准库的qsort函数使用回调来决定排序顺序: <syntaxhighlight lang="c"> #include <stdio.h> #include <stdlib.h> // 比较回调函数 int compareInts(const void* a, const void* b) { return (*(int*)a - *(int*)b); } int compareStrings(const void* a, const void* b) { return strcmp(*(const char**)a, *(const char**)b); } int main() { // 整数排序 int numbers[] = {5, 2, 9, 1, 5}; qsort(numbers, 5, sizeof(int), compareInts); // 字符串排序 const char* names[] = {"John", "Alice", "Bob", "Zoe"}; qsort(names, 4, sizeof(const char*), compareStrings); return 0; } </syntaxhighlight> == 数学表示 == 回调函数可以形式化表示为高阶函数的应用: <math> \text{高阶函数 } H : (A \rightarrow B) \times A \rightarrow B \\ \text{其中 } H(f, x) = f(x) </math> == 最佳实践 == 1. '''类型定义''':使用typedef为回调函数类型创建别名,提高代码可读性 2. '''参数检查''':在调用回调函数前检查指针是否为NULL 3. '''上下文传递''':需要额外数据时使用void*参数传递上下文 4. '''文档说明''':明确说明回调函数的预期行为和参数要求 5. '''错误处理''':考虑回调函数可能失败的情况 == 常见问题 == === 为什么使用回调函数而不是直接调用? === * 实现模块间的松耦合 * 允许调用方自定义行为 * 支持事件驱动和异步编程模型 * 提高代码的复用性和灵活性 === 回调函数与普通函数调用的区别 === {| class="wikitable" |- ! 特性 !! 普通函数调用 !! 回调函数 |- | 调用时机 || 编译时确定 || 运行时确定 |- | 控制流向 || 直接调用 || 反向调用(控制反转) |- | 耦合度 || 紧耦合 || 松耦合 |} == 总结 == 回调函数是C语言中实现灵活、可扩展架构的强大工具。通过将函数作为参数传递,我们可以: * 创建通用的处理框架 * 实现事件驱动编程 * 构建高度可配置的系统 * 促进代码复用和模块化设计 掌握回调函数是成为熟练C程序员的重要一步,它为理解更高级的概念如闭包、函数式编程等奠定了基础。 [[Category:编程语言]] [[Category:C]] [[Category:C 语言函数]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)