电子产业一站式赋能平台

PCB联盟网

搜索
查看: 301|回复: 0
收起左侧

面试题--函数指针的五大作用

[复制链接]

397

主题

397

帖子

2463

积分

三级会员

Rank: 3Rank: 3

积分
2463
发表于 2023-12-5 21:00:00 | 显示全部楼层 |阅读模式

xalscvpqbuu6401888206.png

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

    04xxrd5ysym6401888306.png

    # X# U6 Y, a! _/ @

    5s54u3qbp3t6401888407.png

    5s54u3qbp3t6401888407.png

    * r% u# U+ M/ v" V* ^

    tmhociviqjo6401888507.png

    tmhociviqjo6401888507.png
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表