C 中的函数指针转换

Function Pointers Casting in C

为什么我需要删除函数指针转换才能使用如下所示的函数?

此编译:

#include <stdio.h>

int print_int(int i){
    printf("%d", i);
    return i;
}
typedef int (*print_int_func) (int);

int main(){
    void** p = malloc(1*sizeof(print_int_func*));
    p[0] = (print_int_func*)print_int;

    ((print_int_func)p[0])(2); // This Compiles
    ((print_int_func*)p[0])(2); // This does NOT
    
    return 0;
}

声明 typedef int (*print_int_func) (int); 声明 print_int_func 是指向特定类型函数的指针。所以 (print_int_func)p[0]p[0] 转换为这样一个指向函数的指针,但是 (print_int_func*)p[0]p[0] 转换为一个指向函数指针的指针。因此,结果是指向对象的指针(该对象是指向函数的指针)。由于是对象,不是函数(或指向函数的指针),所以不能像函数一样调用。

此外,避免使用 void * 作为函数指针。 void *是指向对象的指针,C标准没有定义指向对象的指针和指向函数的指针之间的转换。要创建指向函数的“通用”指针,只需选择任何函数类型并使用指向该类型的指针:

  • 存储指针时转换为所选类型。
  • 调用函数类型时转换为实际函数类型

例如,您可以声明任意类型:

typedef void (*CommonFunctionPointer)(void);

并制作一个数组:

CommonFunctionPointer *p = malloc(N * sizeof *p);,

然后你可以在数组中存储任何函数指针:

p[i] = (CommonFunctionPointer) print_int;

并通过将其转换回正确的类型来使用数组中的指针:

((int (*)(int)) p[i])(2);.