C语言 使用指针调用函数并在形参中传递它



假设我有一个指向函数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;
}

不需要任何参数

最新更新