假设某人想要创建一个可以容纳多个函数指针和不同类型的数组。.他会怎么做?也许无效指针数组可以工作?...事实证明,没有,因为要使用存储在无效指针中的函数,您必须将它们(无效指针)转换/广播回函数指针,然后...
“不可能在函数指针和void指针之间进行转换。void *从来不是用于函数指针的泛型指针类型,仅用于对象指针。它们不是兼容类型。
[...]您可以在void *和函数指针之间进行强制转换,但是会发生未定义的行为。您将依赖于系统特定的非标准扩展。”
-@ Lundin(here)
相反...
稍好一点的是将函数指针类型(例如void(*)(void))用作通用指针。您可以转换为不同的函数指针或从不同的函数指针转换为,这将是编译器特定的(实现定义的行为)。也就是说,代码仍将是不可移植的,但是至少您不会因调用未定义的行为而冒着程序崩溃的风险。
-@ Lundin(here)
也就是说,从一个函数指针转换为另一个函数指针是什么意思?
有人可以解释。也许有一个例子。
答案 0 :(得分:6)
这意味着如果您有两种不同的函数指针类型,例如:
int (*i)(int);
void (*v)(void);
然后,您可以使用显式强制转换将一种类型转换为另一种类型:
v = (void(*)(void))i;
这是允许的,但是调用v()
无效。该标准说明了这一点,C17 6.3.2.3§8:
指向一种类型的函数的指针可以转换为指向另一种类型的函数的指针,并且 再次回来;结果应等于原始指针。如果将转换后的指针用于 调用其类型与引用的类型不兼容的函数,其行为是不确定的。
因此,如果尝试通过v();
调用该函数,则可能是未定义的行为。但是,您可以转换回原始类型int(*)(int)
而不会丢失信息。
这允许您将特定的函数指针类型用作“通用类型”。而不是使用here中所讨论的void*
。
值得注意的是,如果使用typedef,所有带有函数指针的代码都将更易于阅读:
typedef int int_func (int);
typedef void void_func (void);
int main()
{
int_func* i;
void_func* v;
v = (void_func*) i;
i = (int_func*) v;
}