function自我回归
是否可以声明一些返回该类型的函数类型func_t
, func_t
?
换句话说,函数是否可能返回自身?
// func_t is declared as some sort of function pointer func_t foo(void *arg) { return &foo; }
或者我是否必须使用void *
和类型转换?
不,你不能在C中声明递归函数类型。除了在结构(或联合)内部,在C中声明递归类型是不可能的。
现在对于void *
解决方案, void *
仅保证保存指向对象的指针而不保存指向函数的指针。 能够转换函数指针和void *
仅作为扩展名提供。
结构的可能解决方案:
struct func_wrap { struct func_wrap (*func)(void); }; struct func_wrap func_test(void) { struct func_wrap self; self.func = func_test; return self; }
用gcc -Wall
编译没有给出任何警告,但我不确定这是否是100%可移植的。
你不能将函数指针强制转换为void*
(它们可以是不同的大小),但这不是问题,因为我们可以转换为另一个函数指针类型并将其强制转换为获取原始值。
typedef void (*fun2)(); typedef fun2 (*fun1)(); fun2 rec_fun() { puts("Called a function"); return (fun2)rec_fun; } // later in code... fun1 fp = (fun1)((fun1)rec_fun())(); fp();
输出:
Called a function Called a function Called a function
换句话说,函数是否可能返回自身?
这取决于你自己的意思; 如果你的意思是指向自己的指针,那么答案是肯定的! 虽然函数无法返回其类型,但函数可以返回指向自身的指针,然后可以在调用之前将此指针转换为适当的类型。
有关详细信息,请参阅comp.lang.c faq:可以返回指向同一类型函数的指针的函数。
查看我的答案了解详情。
这样的事情怎么样:
typedef void* (*takesDoubleReturnsVoidPtr)(double); void* functionB(double d) { printf("here is a function %f",d); return NULL; } takesDoubleReturnsVoidPtr functionA() { return functionB; } int main(int argc, const char * argv[]) { takesDoubleReturnsVoidPtr func = functionA(); func(56.7); return 0; }
假设函数定义
T f(void) { return &f; }
f()
返回类型为T
的值,但表达式&f
的类型是“指向函数返回T
指针”。 无论T
是什么,表达式&f
将始终是不同的, 不兼容的类型T (*)(void)
。 即使T
是一个指向函数的指针类型,如Q (*)(void)
,表达式&f
也将成为“指向函数的指针返回 – 指向函数的指针”,或Q (*(*)(void))(void)
。
如果T
是一个足以容纳函数指针值的整数类型, 并且从T (*)(void)
为T
并返回到T (*)(void)
在您的平台上有意义,那么您可能能够逃脱有类似的东西
T f(void) { return (T) &f; }
但我至少可以想到几种根本无法发挥作用的情况。 老实说,与使用像查找表这样的东西相比,它的效用会非常有限。
C只是设计用于处理与任何其他数据项一样的函数,并且指向函数的指针不能与指向对象类型的指针互换。
有一种方法,你试试这个:
typedef void *(*FuncPtr)(); void *f() { return f; } int main() { FuncPtr f1 = f(); FuncPtr f2 = f1(); FuncPtr f3 = f2(); return 0; }
如果您使用的是C ++,则可以创建一个State
对象类型(假设状态机示例用法),其中您声明一个operator()
,它通过引用或指针返回State
对象类型。 然后,您可以将每个状态定义为State
的派生类,该类从其operator()
实现中返回每个适当的其他派生类型。