Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C:如何访问存储在void指针(void*)中的函数指针?_C_Pointers_Function Pointers_Void Pointers_Typecasting Operator - Fatal编程技术网

C:如何访问存储在void指针(void*)中的函数指针?

C:如何访问存储在void指针(void*)中的函数指针?,c,pointers,function-pointers,void-pointers,typecasting-operator,C,Pointers,Function Pointers,Void Pointers,Typecasting Operator,对如何访问存储在void指针(void*)中的函数指针感到困惑 假设你有: void *functions[] = { &sqrt, // int ft_sqrt(int nb); &power, &logN, &factorial; }; // An array of void pointers, each storing a function pointer. 如果我想访问sqrt函数,我的猜测如下: (

对如何访问存储在void指针(void*)中的函数指针感到困惑


假设你有:

void *functions[] =
{
    &sqrt,         // int ft_sqrt(int nb);
    &power,
    &logN,
    &factorial;
};

// An array of void pointers, each storing a function pointer.

如果我想访问
sqrt
函数,我的猜测如下:

(int(*)(int))函数[0](x)

但我的猜测是错误的:

错误:调用的对象类型“void*”不是函数或函数指针


那么如何访问这些函数呢?

问题在于:函数调用操作符的优先级高于强制转换操作符

这意味着您的表达式
(int(*)(int))函数[0](x)
实际上等于
(int(*)(int))(函数[0](x))

您需要在正确的位置显式添加括号以强制转换指针:
((int(*)(int))函数[0])(x)


更好的解决方案是使用指向函数的指针数组,因此数组元素已经是正确的类型:

typedef int (*function_ptr)(int);

function_ptr functions[] = { ... };
然后不需要强制转换:
函数[0](x)


那么您也可以避免中提到的问题。

严格来说,您不能。无法在函数指针和
void
指针之间进行转换
void*
从来不是函数指针的通用指针类型,只适用于对象指针。它们是不兼容的类型

实际上,任何指针都很可能具有系统地址总线所需的大小,因此对象指针和函数指针很可能具有相同的表示形式。然而,标准并不能保证这一点,而且有些异国情调的系统中,这种等价性并不成立。因此,您可以在
void*
和函数指针之间进行强制转换,但会发生未定义的行为。您将依赖于特定于系统的非标准扩展


稍微好一点的方法是使用函数指针类型,例如
void(*)(void)
,作为通用指针。您可以在不同的函数指针之间进行转换,所发生的是特定于编译器的(实现定义的行为)。也就是说,代码仍然是不可移植的,但至少不会因为调用未定义的行为而导致程序崩溃。

为什么要将函数指针存储在指向void的指针数组中?特别是如果你要尝试调用它们。idk,也许这不是实现这一点的方法,但我在想,如果你有不同返回类型和/或采用不同参数的函数。。你可以将它们全部存储在一个数组中。如果你不知道某个函数的返回类型,你会如何有意义地调用它?谢谢你的回答和有用的提示一些程序员,@Lundin。它现在可以工作了,至少在我的系统上。。但肯定会考虑到可移植性的问题并改变它。明白了。。。至于“转换到不同的函数指针/从不同的函数指针转换”,这将按照您所解释的方式进行。谢谢对面安全吗?从函数指针转换为void*指针?@thysultan“Between”表示两种方式都无效。如果X与Y不兼容,则Y与X不兼容。