使用指针调用函数并在参数中传递它

Call a function using a pointer and pass it along in the parameters

假设我有一个指向函数theFunc的指针。 theFunc 带有一个指针,指向存储 theFunc 的地址。这可能吗?

使用它看起来像这样:

funcPtr(funcPtr);

即调用funcPtr指向的函数,然后传递指针地址。我不想使用 void 指针,因为我想更改 funcPtr.

指向的函数

您不能简单地键入定义接受自身作为参数的函数类型。 IE。这样的事情是行不通的:

/* 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;
}

更新:
根据下面@JosephSible-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();

声明一个函数,该函数采用未指定数量的参数和 returns int。这允许定义一系列函数类型,这些函数类型接近所需的函数类型,该函数类型将指向自身的指针作为第一个参数。所需类型达到无穷大,但 2-3 级足以实现实际类型安全。

例如,即使在迂腐模式下,下面的代码也可以在没有警告的情况下编译。

int foo(int(int()));

int main(void) {
  int (*fptr)(int(int())) = foo;
  return fptr(fptr);
}

https://godbolt.org/z/1s1bGMd9P

theFunc takes along a pointer that points to the address where theFunc is stored . Is this possible?

是的,这是可能的,但也是 100% 毫无意义的。这类似于给自己写一封信,在信中写下您的邮政地址。当您已经出现在信中所述的实际地址时,您会将该信放入自己的邮箱。这没有任何意义 - 你已经知道地址,因为你已经在那里了,那么为什么要先写这封信呢?程序设计规则 #1:不要仅仅因为你可以就做非常奇怪的事情。

在表达式中使用时,C 中的任何函数名称都可能衰减为函数指针。因此:

void theFunc (void)
{
  uintptr_t address = (uintptr_t)theFunc;
}

不需要任何参数。