|
xalscvpqbuu6401888206.png
1 B; s: U9 \0 _1 A
1,回调函数机制函数指针常用于实现回调函数。通过将函数指针作为参数传递给另一个函数,可以在特定事件发生时调用预定义的函数。这种机制在事件处理、异步编程等场景中很常见。例如,图形用户界面(GUI)库中的按钮点击事件处理函数就是通过回调函数实现的。
. Q$ T+ q- U+ @) K1 g$ v* ~#include
" o' }3 g5 |! V; Z8 m// 回调函数类型typedef void (*CallbackFunction)(int);0 _' M! f9 U7 K) E
// 执行回调函数的函数void performCallback(CallbackFunction callback, int value) { callback(value);}// 回调函数1void callback1(int value) { printf("Callback 1: %d
6 I6 H- k4 t0 |( F5 Q", value);}
0 d; l' m+ ?: }' @9 ?* P// 回调函数2void callback2(int value) { printf("Callback 2: %d
5 u+ X. } n- L2 S9 M", value * 2);}. j4 g# o$ [/ u _* s+ B# _
int main() { // 使用回调函数1 performCallback(callback1, 5);
' m; H4 t& {! v" z! q // 使用回调函数2 performCallback(callback2, 10);
3 T& i9 v9 ]9 ~; R return 0;}2,动态函数调用函数指针允许在运行时动态地选择要调用的函数。这在需要根据条件选择不同实现的情况下很有用,可以增加程序的灵活性和可扩展性。例如,可以根据用户输入的选项调用不同的处理函数。
3 m0 \4 p* [- U9 Y4 Q) p#include / \; q$ N9 f/ d5 ?
// 函数类型typedef void (*FunctionPointer)();// 函数1void function1() { printf("Function 1 ~/ Z, [+ ~% x8 X$ B" L
");}// 函数2void function2() { printf("Function 2$ |% V2 M Y- J6 ^7 {5 l
");}
# b4 n: Y. y7 ^; \int main() { // 函数指针 FunctionPointer funcPtr; // 根据条件选择要调用的函数 if (condition) { funcPtr = function1; } else { funcPtr = function2; } // 调用选择的函数 funcPtr();
9 s4 B3 H# H! A5 [9 Y: D# p return 0;}3,函数指针数组可以创建一个函数指针数组,每个元素是一个指向特定函数的指针。这样的数组可以用于实现状态机、菜单驱动程序等。例如,可以用一个函数指针数组来实现一个简单的命令行菜单系统。
% V' w2 f; v; z* b" a0 p8 D; q#include ' p7 S) a! ?: A! n) P
// 函数类型typedef void (*MenuFunction)();
- g8 Y6 S$ N* m! s2 P& a// 函数1void function1() { printf("Option 16 c0 c U8 T2 o. o
");}// 函数2void function2() { printf("Option 2" b. w' l9 \5 D4 _/ ?! y, `7 Z
");}2 h% }) J$ f. w. T1 q8 |: Z' x
int main() { // 函数指针数组 MenuFunction menu[] = {function1, function2};: }. B% Q0 A5 B5 c) J: f# J5 Y
// 用户选择的菜单项 int choice; // 获取用户输入 printf("Enter your choice (1 or 2): "); scanf("%d", &choice);
& `( R/ {0 P9 ^0 F ^' N9 A // 调用选择的函数 if (choice >= 1 && choice 2) { menu[choice - 1](); // 数组索引从0开始,需要减1 } else { printf("Invalid choice* X- ] Y$ N8 |3 `
"); }
, y8 {3 p1 M# X) w) T5 E0 Y! R return 0;}4,动态库加载在动态库加载的情景中,函数指针用于获取动态库中的函数地址。这样,你可以在运行时决定是否加载某个库,以及调用库中的哪些函数。- m& J( W) B- |% C: m5 x$ P
#include #include
/ B! w' I7 M9 R- Wtypedef void (*LibraryFunction)();3 H7 O/ F8 R- t8 h( {- ?
int main() { // 加载动态库 void *libHandle = dlopen("mylibrary.so", RTLD_LAZY);* k3 c I! Q8 e9 y( U! x' g
if (libHandle) { // 获取动态库中的函数地址 LibraryFunction libFunction = dlsym(libHandle, "myFunction");+ A# {) `9 T0 I, ~2 S
if (libFunction) { // 调用动态库中的函数 libFunction(); } else { fprintf(stderr, "Error: Function not found# J4 `! A" S# V- j; Z
"); } // 关闭动态库 dlclose(libHandle); } else { fprintf(stderr, "Error: Unable to load library
% C8 g, L9 F3 w0 P- `( S, `% Z& l"); }
- A. [; Z( F3 S# c! D) R return 0;}5,函数指针作为参数函数指针可以作为函数的参数,这样可以将函数作为另一个函数的参数传递,实现更灵活的函数组合。#include // 函数类型typedef int (*OperationFunction)(int, int);
2 x! g9 U1 \8 Z: n, l// 加法函数int add(int a, int b) { return a + b;}// 减法函数int subtract(int a, int b) { return a - b;}// 执行操作的函数int performOperation(OperationFunction operation, int a, int b) { return operation(a, b);}
+ {9 J+ O8 ?; W6 ~int main() { // 使用加法函数 int resultAdd = performOperation(add, 5, 3); printf("Result of addition: %d
' S) M4 ]: _- v( n1 G$ [. z5 \", resultAdd);2 R* T4 ?* j$ b2 W0 D
// 使用减法函数 int resultSubtract = performOperation(subtract, 5, 3); printf("Result of subtraction: %d* }) M8 _% {/ h, K9 c. a7 @4 \
", resultSubtract);
( g$ U& H; y% F7 k0 _/ L5 J return 0;}
2 L: ]& a5 v6 v# {8 p, h1 P( g& W==========) K2 C1 U+ H' J2 I9 S" `( P% _
往期回顾:中值滤波的原理和C代码% R- r/ B) `5 X3 W
移动平均滤波的原理和C代码MOS管防反接电路( _- W2 ^4 H# a) w$ v% W
STM32的看门狗原理和示例代码
) K, q% Z1 R" n. k" O3 ?" E6 P. W==========
4 a! b$ M& `/ S, j ]
04xxrd5ysym6401888306.png
# X# U6 Y, a! _/ @
5s54u3qbp3t6401888407.png
* r% u# U+ M/ v" V* ^
tmhociviqjo6401888507.png
|
|