使用指针调用函数并在参数中传递它
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);
}
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;
}
不需要任何参数。
假设我有一个指向函数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);
}
theFunc
takes along a pointer that points to the address wheretheFunc
is stored . Is this possible?
是的,这是可能的,但也是 100% 毫无意义的。这类似于给自己写一封信,在信中写下您的邮政地址。当您已经出现在信中所述的实际地址时,您会将该信放入自己的邮箱。这没有任何意义 - 你已经知道地址,因为你已经在那里了,那么为什么要先写这封信呢?程序设计规则 #1:不要仅仅因为你可以就做非常奇怪的事情。
在表达式中使用时,C 中的任何函数名称都可能衰减为函数指针。因此:
void theFunc (void)
{
uintptr_t address = (uintptr_t)theFunc;
}
不需要任何参数。