假设我有一个指向函数theFunc
的指针。theFunc
取一个指向theFunc
存储地址的指针。这可能吗?
使用它看起来像这样:
funcPtr(funcPtr);
调用funcPtr所指向的函数,然后传递指针的地址。我不想使用void指针,因为我想改变funcPtr
指向的函数。
不能简单地定义一个接受自身作为参数的函数类型。也就是说,像这样的东西将不起作用:
/* Will cause a compilation error, MyFuncType used a parameter is not yet defined: */
typedef void(*MyFuncType)(MyFuncType);
然而,你仍然可以使用void*
来实现你想要的。typedef使用的是void*
,但是在函数内部,你可以将它强制转换为你的函数指针类型,修改它并调用它。
看到:
typedef void(*MyFuncType)(void*);
void f(void* pF)
{
if (pF)
{
MyFuncType ff = (MyFuncType)pF;
/* Change ff here if you need. */
/* Call it: */
ff(0);
}
}
int main()
{
f(f);
return 0;
}
更新:
在@ josephsibling - reinstatemonica下面的评论之后,我添加了2nd解决方案。它不涉及数据指针和函数指针之间的强制转换,但它需要另一个typedef
和一个强制转换,当它自己调用f
时:
typedef void(*FuncType1)(void);
typedef void(*MyFuncType)(FuncType1);
void f(MyFuncType pF)
{
if (pF)
{
/* Change pF here if you need. */
/* Call it: */
pF(0);
}
}
int main()
{
f((MyFuncType)f);
return 0;
}
是。这是可能的。C语言支持不完整的函数类型,声明的函数没有原型。例如:
int fun();
声明一个函数,该函数接受未指定数量的参数并返回int
。这允许定义一系列函数类型,这些函数类型接近所需的函数类型,该函数类型以指向自身的指针作为第一个参数。期望的类型达到无穷大,但对于实际类型安全来说,2-3个级别就足够了。
例如,即使在迂腐模式下,下面的代码编译也不会发出警告。
int foo(int(int()));
int main(void) {
int (*fptr)(int(int())) = foo;
return fptr(fptr);
}
见https://godbolt.org/z/1s1bGMd9P
theFunc
携带一个指向theFunc
所在地址的指针。这可能吗?
是的,这是可能的,但它也是100%毫无意义的。这类似于给自己写一封信,在信中写下你的邮政地址。当你已经在信中所述的实际地址时,你去把那封信放在你自己的邮箱里。这没有任何意义——既然你已经在那里了,你已经知道地址了,那么为什么要写这封信呢?程序设计原则1:不要因为你能做而做一些奇怪的事情。
C语言中的任何函数名在用于表达式时都可能衰减为函数指针。因此:
void theFunc (void)
{
uintptr_t address = (uintptr_t)theFunc;
}
不需要任何参数