具有不同函数的函数指针数组返回值(以C为单位)

时间:2016-09-11 10:34:07

标签: c arrays function-pointers

我已经看过一些函数指针数组的例子(例如here

在示例中,我看到数组包含具有相同类型返回值的函数(例如,所有int,或者所有void' s)。

但是我想知道你能拥有一个包含不同类型函数指针的数组吗?

下一个代码不会编译:

#include <stdio.h>

void Empty_Funcion()
{
    ;
}
int funcAdd(int a, int b){
    return a+b;
}

int main()
{
    int ret = 0;

    void *array[5] = {&Empty_Funcion, &funcAdd, &Empty_Funcion, &funcAdd, &Empty_Funcion};

    ret = (*array[1])(5,7);

    printf("%d\n", ret);

    return 0;
}

它说问题在于赋值ret = ...&#34; void值不被忽略,因为它应该是&#34;。

3 个答案:

答案 0 :(得分:2)

你可以这样做:

ret = ( ( int (*)(int,int) ) array[1] )(5,7);

你需要使用正确的签名转换为指向函数类型的指针。

答案 1 :(得分:2)

  

但是我想知道你能拥有一个包含不同类型函数指针的数组吗?

Anatoly's answer所述,您的代码无法正常工作,因为您的数组要声明包含返回void的指针到函数,但是您尝试将其作为指针调用 - to-function返回int。这些是不兼容的类型,因此需要显式强制转换。并且,如ISO C99标准的第6.3.2.3/8节所述,允许将函数指针转换为不同的函数指针类型并再次返回:

  

指向一种类型的函数的指针可以转换为指向另一种类型的函数的指针,然后再返回;结果应该等于原始指针。如果转换的指针用于调用类型与指向类型不兼容的函数,则行为未定义。

那就是说,我没有看到这样做的任何意义。函数指针强制转换是静态强制转换(编译器已知的强制转换)而不是动态强制转换,因此必须手动跟踪数组中哪些元素的类型void (*)()和属于int (*)(int, int)的类型。相反,为每个函数指针类型设置一个单独的数组更简单,并且避免完全抛出。这样做会更不容易出错,因为你不会冒险将函数指针调用为错误的类型(这将是未定义的行为)。

更新: 您已更改了问题,因此array现在是void*指针数组。请注意,尽管可以在void*之间自由地转换普通指针,但对于函数指针,这是 not true(尽管在许多实现中它被认为是常见的扩展)。

答案 2 :(得分:0)

您的数组未声明为函数指针数组,它被声明为指向void的指针数组。

要将数组声明为函数指针数组,您可以这样做:

int (*)(int,int) array[5] = ...

或为了清楚起见:

typedef int (*my_function_pointer_type)(int,int);

my_function_pointer_type array[5] = ... 

理论上,你不能调用一个返回void的函数并期望它返回一些东西。这违反了C标准。在实践中,如果你这样做,你很可能会得到一个不可预测的值,但在某些情况下(例如尝试返回一个结构)与一些ABI,你可能会崩溃。

最好的方法是将“虚拟”函数的类型与放入数组中的其他函数的类型相匹配。