3

使用函数指针数组有什么好处?除了减少 C 中函数原型的数量。

4

4 回答 4

3

正如许多人所指出的,函数指针可用于模拟 C 中的面向对象编程。

例如,可以使用简单的索引来选择适当的方法(也称为虚拟方法)。

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

typedef void (*menu_function_t)();

void menu_error()
{
    printf("Invalid menu choice\n");
}

void menu_exit()
{
    exit(0);
}

void menu_function1()
{
    printf("You have selected 1\n");
}

void menu_function2()
{
    printf("You have selected 2\n");
}

menu_function_t menu_ptr[] = {
    menu_function1, menu_function2,  menu_exit, menu_error
};

int menu_num = sizeof(menu_ptr) / sizeof(menu_ptr[0]);

int validate_choice(int a)
{
    if(a < 0 || a > menu_num - 2) { return 3; }

    return a;
}

int main()
{
    int choice = 0;

    while(1)
    {
        printf("Choose item: \n");
        printf("0) Function 1\n");
        printf("1) Function 2\n");
        printf("2) Exit\n");
        scanf("%d", &choice);

        menu_ptr[ validate_choice(choice) ]();
    }

    return 0;
}
于 2012-09-23T21:32:59.237 回答
2

保存函数指针的数组(或其他数据结构)有多种用例。通常,这种类型的机制允许您的程序根据运行时标准动态调用几个不同函数之一。

例如,您可以使用函数指针数组来实现类似于 OO 语言的接口。该数组将保存一个指向该接口的每个实现的指针。数组索引将用于根据某些标准选择所需的实现。

于 2012-09-23T21:23:32.270 回答
2

如果您想将数值与操作相关联,您可以使用函数指针数组,尽管它实际上被称为映射。它会节省有一个大的switch声明。

array[CMD_OPEN] = OpenFunction;
array[CMD_CLOSE] = CloseFunction;

ETC

void HandleCommand(int aCommand)
{
    array[aCommand]();
}
于 2012-09-23T21:31:13.293 回答
1

一个例子(很多存在)是当你想实现一系列可变的“方法”时:

typedef struct tag_IMAGEFORMAT
{
        struct tag_IMAGEFORMAT *next;
        const char      *name;
        IMAGEDETECTOR   *detect_routine;
        int             (*open_routine)         (DISKIMAGE *img, diskimgflags_t flags);
        size_t          (*read_routine)         (DISKIMAGE *img);
        int             (*close_routine)        (DISKIMAGE *img);
} IMAGEFORMAT;

C 中的面向对象编程。然后调用 eg object->open_routine(..),其实现可以在运行时动态更改(在此示例中,取决于图像格式)。

在此示例中,几种图像格式共享一个通用 API;各种“检测器”一个接一个地运行,第一个匹配的将其指针复制到“通用图像”对象。之后,您可以操作图像而无需担心其实现细节(JPG、GIF、PNG 等)。

同样,如果您需要实现一个函数的几种不同变体(例如图像过滤器),您可以将所有指针保存在一个数组中,并通过数组中的索引选择合适的指针。

于 2012-09-23T21:24:45.503 回答