迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > C语言 >

C 语言中的函数指针

作者:迹忆客 最近更新:2023/03/27 浏览次数:

本文将介绍如何在 C 语言中使用函数指针。


在 C 语言中使用 void (*func)() 符号来定义函数指针

函数指针是 C 语言程序设计中的又一个结构,它实现了动态函数调用、结中包含自己的方法等高级功能,类似于面向对象设计、类型通用程序设计等。需要注意的是,函数指针的声明可能有复杂的语法,即 void(*func)(void) 记号声明了指向 void 函数的指针,该函数不需要参数。虽然在下面的例子中,我们将取单一 int 参数的 printInt 函数的地址分配给 void(*func)(void) 型函数指针。一旦定义了名为 func 的函数指针,就可以用通常的函数调用符号 func(arg) 或用 dereferencing 运算符 (*func)(arg) 来调用它。

#include <stdio.h>
#include <stdlib.h>

void printInt(int x)
{
    printf("printed from printInt: %d\n", x);
}

int main() {
    int input1 = 10233;

    void (*func)(int) = printInt;

    func(input1);
    (*func)(input1);

    exit(EXIT_SUCCESS);
}

输出:

printed from printInt: 10233
printed from printDouble: 11.234000

另外,我们也可以使用 typedef 为函数指针定义一个新的类型别名,使代码更易读。注意,不同的函数类型需要单独的 typedef 语句。在下面的代码示例中,我们定义了一个没有任何参数的 void 函数指针,尽管如此,printIntprintDouble 函数地址都存储在类型为 FuncPtr 的变量中。需要注意的是,特定函数的地址可以通过显式的&运算符或函数名本身的隐式赋值来获取,这在下一个例子中有所体现。

#include <stdio.h>
#include <stdlib.h>

typedef void (*FuncPtr)();

void printInt(int x)
{
    printf("printed from printInt: %d\n", x);
}

void printDouble(double x)
{
    printf("printed from printDouble: %f\n", x);
}

int main() {
    int input1 = 10233;
    double input2 = 11.234;

    FuncPtr func1 = printInt;
    FuncPtr func2 = printDouble;

    func1(input1);
    func2(input2);

    exit(EXIT_SUCCESS);
}

输出:

printed from printInt: 10233
printed from printDouble: 11.234000

使用函数指针数组实现类型通用编程特性

像其他对象一样,可以用括号 [] 符号定义一个函数指针数组。在运行时可以利用这个数组方便地选择和调用特定的函数。

注意 ,我们使用的是关键字 _Generic,它是 switch 一样的表达式,让用户根据控制表达式的类型评价来选择具体的情况。

因此,我们实现了下面的代码示例,根据 switch 条件中传递的变量类型,调用相应的 print 函数。请注意,enum 类型也被用来定义不同情况下的常量值。

#include <stdio.h>
#include <stdlib.h>

enum TYPE {INTEGER, DOUBLE, INVALID};

#define typename(x) _Generic((x), \
          int: INTEGER, \
        double: DOUBLE, \
      default: INVALID)

typedef void (*FuncPtr)();

void printInt(int x)
{
    printf("printed from printInt: %d\n", x);
}

void printDouble(double x)
{
    printf("printed from printDouble: %f\n", x);
}

int main() {
    int input1 = 10233;
    double input2 = 11.234;

    FuncPtr func_ptrs[] = {printInt, printDouble};

    switch (typename(input1)) {
        case INTEGER: func_ptrs[INTEGER](input1); break;
        case DOUBLE: func_ptrs[DOUBLE](input1); break;
        case INVALID: printf("No corresponding type found!\n");
        default: break;
    }

    switch (typename(input2)) {
        case INTEGER: func_ptrs[INTEGER](input2); break;
        case DOUBLE: func_ptrs[DOUBLE](input2); break;
        case INVALID: printf("No corresponding type found!\n");
        default: break;
    }

    exit(EXIT_SUCCESS);
}

输出:

printed from printInt: 10233
printed from printDouble: 11.234000

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 C 语言中使用 typedef enum

发布时间:2023/05/07 浏览次数:181 分类:C语言

本文介绍了如何在 C 语言中使用 typedef enum。使用 enum 在 C 语言中定义命名整数常量 enum 关键字定义了一种叫做枚举的特殊类型。

C 语言中的静态变量

发布时间:2023/05/07 浏览次数:151 分类:C语言

本文介绍了如何在 C 语言中使用静态变量。在 C 语言中使用 static 变量在函数调用之间保存变量值

C 语言中生成随机数

发布时间:2023/05/07 浏览次数:64 分类:C语言

本文演示了如何在 C 语言中生成随机数。使用 rand 和 srand 函数在 C 语言中生成随机数

C 语言中的 i++ 与++i

发布时间:2023/05/07 浏览次数:83 分类:C语言

本文演示了如何在 C 语言中使用前缀增量与后缀增量运算符。C 语言中++i 和 i++ 记号的主要区别

C 语言中获取当前工作目录

发布时间:2023/05/07 浏览次数:182 分类:C语言

本文演示了如何在 C 语言中获取当前工作目录。使用 getcwd 函数获取当前工作目录的方法

C 语言中的位掩码

发布时间:2023/05/07 浏览次数:126 分类:C语言

本文介绍了如何在 C 语言中使用位掩码。使用 struct 关键字在 C 语言中定义位掩码数据

C 语言中的排序函数

发布时间:2023/05/07 浏览次数:181 分类:C语言

本文演示了如何在 C 语言中使用标准库排序函数。使用 qsort 函数对 C 语言中的整数数组进行排序

C 语言中的 extern 关键字

发布时间:2023/05/07 浏览次数:114 分类:C语言

本文介绍了如何在 C 语言中使用 extern 关键字。C 语言中使用 extern 关键字来声明一个在其他文件中定义的变量

C 语言中的 #ifndef

发布时间:2023/05/07 浏览次数:186 分类:C语言

本文介绍了如何在 C 语言中使用 ifndef。在 C 语言中使用 ifndef 保护头文件不被多次包含 C 语言中的头文件用于定义同名源文件中实现的函数的接口。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便