函数指针数组:定义、用法和优点

发布时间:2023-05-21

一、函数指针数组定义

函数指针数组其实就是一个数组,里面的每一个元素都是一个指针,而这个指针指向的是一个函数的地址。

int (* func_ptr_arr[])(int, int);

上面的代码定义了一个函数指针数组,数组的每一个元素都是一个指向两个int参数的函数指针。

二、函数指针数组怎么定义

函数指针数组的定义格式如下:

返回值类型 (* 数组名[数组长度])(参数列表);

其中,返回值类型是函数的返回值类型,数组名是你自己定义的数组名称,在 [] 中指定数组长度,参数列表是函数的参数类型列表。

三、函数指针数组用法

函数指针数组最主要的用途在于可以使用函数指针数组来调用不同的函数。

#include <stdio.h>
int add(int a, int b){ return a + b; }
int sub(int a, int b){ return a - b; }
int mul(int a, int b){ return a * b; }
int main(){
    int (* func_ptr_arr[])(int, int) = {add, sub, mul};
    int a = 10, b = 5;
    int result = func_ptr_arr[0](a, b);
    printf("add: %d\n", result);
    result = func_ptr_arr[1](a, b);
    printf("sub: %d\n", result);
    result = func_ptr_arr[2](a, b);
    printf("mul: %d\n", result);
    return 0;
}

上面的代码演示了如何定义一个函数指针数组,然后使用这个数组来调用三个不同的函数,并输出结果。在这个例子中,函数指针数组可以很方便地切换函数的调用。

四、函数指针数组实例

函数指针数组可以应用于很多不同的场景,比如在数据结构中,可以使用函数指针数组来实现多态。

#include <stdio.h>
typedef struct{
    void (* show)(void *);
    void (* update)(void *, int);
    void * data;
}Shape;
void show_shape(Shape * sp){
    sp->show(sp->data);
}
void update_shape(Shape * sp, int val){
    sp->update(sp->data, val);
}
typedef struct{
    int width;
    int height;
}Rect;
void show_rect(void * ptr){
    Rect * rp = (Rect *)ptr;
    printf("Rect: %d, %d\n", rp->width, rp->height);
}
void update_rect(void * ptr, int val){
    Rect * rp = (Rect *)ptr;
    rp->width += val;
    rp->height += val;
}
typedef struct{
    int radius;
}Circle;
void show_circle(void * ptr){
    Circle * cp = (Circle *)ptr;
    printf("Circle: %d\n", cp->radius);
}
void update_circle(void * ptr, int val){
    Circle * cp = (Circle *)ptr;
    cp->radius += val;
}
int main(){
    Rect rect = {10, 20};
    Circle circle = {5};
    Shape shapes[] = {
        {show_rect, update_rect, &rect},
        {show_circle, update_circle, &circle}
    };
    for(int i=0; i<2; i++){
        show_shape(&shapes[i]);
        update_shape(&shapes[i], 5);
        show_shape(&shapes[i]);
    }
    return 0;
}

上面的代码演示了如何使用函数指针数组来定义Shape这个数据结构,并在其中存储Rect和Circle两种图形类型。通过定义不同的函数指针来实现show和update的多态效果。

五、函数指针数组问题

虽然函数指针数组有很多优点,但是也存在一些问题。最常见的问题就是函数指针数组容易出现数组溢出、空指针等问题,需要特别注意指针的判断。

六、函数指针参数

函数指针也可以作为函数参数进行传递。

#include <stdio.h>
void print_numbers(int * arr, int len){
    for(int i=0; i<len; i++){
        printf("%d ", arr[i]);
    }
    printf("\n");
}
void process_numbers(int * arr, int len, int (* process)(int)){
    for(int i=0; i<len; i++){
        arr[i] = process(arr[i]);
    }
}
int add_five(int num){ return num + 5; }
int subtract_one(int num){ return num - 1; }
int main(){
    int arr[] = {1, 2, 3, 4, 5};
    int len = sizeof(arr) / sizeof(arr[0]);
    print_numbers(arr, len);
    process_numbers(arr, len, add_five);
    print_numbers(arr, len);
    process_numbers(arr, len, subtract_one);
    print_numbers(arr, len);
    return 0;
}

上面的代码演示了如何定义process_numbers函数,并在其中传入一个函数指针作为处理函数进行数值处理。

七、函数指针数组的优点

函数指针数组的最大优点在于可以实现函数的动态调用。 比如,在开发一个多线程网络程序时,可能需要在不同的线程中使用不同的函数进行处理,这个时候就可以使用函数指针数组来实现程序的灵活处理。 此外,使用函数指针数组还可以减少程序中的重复代码,使程序更加简洁和易读。

八、函数指针数组性能和速度

函数指针数组的性能和速度与普通函数调用相比稍微慢一些,但是这种差距很小,在实际使用中影响不大。

九、函数指针数组如何使用

要使用函数指针数组,首先需要明确要调用的函数类型和参数类型,然后定义一个指针数组,将函数指针存储在其中,通过数组下标来实现函数调用。 需要注意内存分配和指针判断等问题,避免出现数组溢出等风险。