通过指针定义函数
Defining a function through a pointer
我有以下代码:
typedef void (*func_type)(int a, int b);
func_type func;
int main()
{
func = (func_type)GetProcAddress(NULL, "func");
}
此代码工作正常,但我想将 func_type func;
更改为 void func(int a, int b);
(因为代码完成在键入参数时显示“func_type”而不是“func”)。
但是当我试图改变它时,编译器告诉我在主函数中“表达式必须是一个可修改的左值”。我试着上网,但没有找到问题的答案。
代码变成这样:
typedef void (*func_type)(int a, int b);
void func(int a, int b);
int main()
{
func = (func_type)GetProcAddress(NULL, "func");
}
typedef void (*func_type)(int a, int b);
将 func_type
声明为指向函数的指针类型。然后 func_type func;
声明 func
是一个指针。您提出的替代方案 void func(int a, int b);
声明 func
是一个函数。
因为您可以分配给指针,所以 func = …;
适用于第一个声明。由于您不能分配给函数,因此 func = …;
不适用于第二个声明。
要在不使用 typedef
的情况下将 func
声明为指向函数的指针,请使用 void (*func)(int, int);
.
C 中的函数类似于数组。它们都衰减为指针。每当使用函数名称时,它都会自动衰减为 指向此函数的指针。 &
和 sizeof
运算符除外。运算符 sizeof
不接受函数作为操作数。这就是为什么 foo
和 &foo
是等价的。
函数本身不可通过设计修改。任何修改它的尝试,即通过 memcpy
-ing 到函数指针是 未定义的行为。
令人惊讶的是,函数调用运算符 ()
不会 将函数作为操作数,而是 指向函数的指针 。
因此,函数调用
foo(1);
实际上是
(&foo)(1);
因为 foo
在计算函数调用之前衰减到 &foo
。
这就是为什么可以在函数调用操作数中互换使用函数和函数指针的原因。
void foo(int) { ... }
void (*bar)(int);
foo(1); // foo decays to &foo which is a function pointer
bar(2); // bar is already a function pointer
为了解决最初的问题,我建议将 func
保留为函数指针,它最初指向某个专用函数,但稍后可以覆盖它:
typedef void func_type(int,int);
void default_func(int a, int b) { ... }
funt_type* func = default_func; // decays to &default_func !
int main()
{
func(1,2); // calls default_func
func = (func_type*)GetProcAddress(NULL, "func");
func(3,4); // calls func from dll/so
}
我决定使用有点不正统的函数类型(不是函数指针类型)。 IMO,它使语法在视觉上更令人愉悦,并且更容易被人类解析。而且,什么是指针什么不是指针是明确的。
我有以下代码:
typedef void (*func_type)(int a, int b);
func_type func;
int main()
{
func = (func_type)GetProcAddress(NULL, "func");
}
此代码工作正常,但我想将 func_type func;
更改为 void func(int a, int b);
(因为代码完成在键入参数时显示“func_type”而不是“func”)。
但是当我试图改变它时,编译器告诉我在主函数中“表达式必须是一个可修改的左值”。我试着上网,但没有找到问题的答案。
代码变成这样:
typedef void (*func_type)(int a, int b);
void func(int a, int b);
int main()
{
func = (func_type)GetProcAddress(NULL, "func");
}
typedef void (*func_type)(int a, int b);
将 func_type
声明为指向函数的指针类型。然后 func_type func;
声明 func
是一个指针。您提出的替代方案 void func(int a, int b);
声明 func
是一个函数。
因为您可以分配给指针,所以 func = …;
适用于第一个声明。由于您不能分配给函数,因此 func = …;
不适用于第二个声明。
要在不使用 typedef
的情况下将 func
声明为指向函数的指针,请使用 void (*func)(int, int);
.
C 中的函数类似于数组。它们都衰减为指针。每当使用函数名称时,它都会自动衰减为 指向此函数的指针。 &
和 sizeof
运算符除外。运算符 sizeof
不接受函数作为操作数。这就是为什么 foo
和 &foo
是等价的。
函数本身不可通过设计修改。任何修改它的尝试,即通过 memcpy
-ing 到函数指针是 未定义的行为。
令人惊讶的是,函数调用运算符 ()
不会 将函数作为操作数,而是 指向函数的指针 。
因此,函数调用
foo(1);
实际上是
(&foo)(1);
因为 foo
在计算函数调用之前衰减到 &foo
。
这就是为什么可以在函数调用操作数中互换使用函数和函数指针的原因。
void foo(int) { ... }
void (*bar)(int);
foo(1); // foo decays to &foo which is a function pointer
bar(2); // bar is already a function pointer
为了解决最初的问题,我建议将 func
保留为函数指针,它最初指向某个专用函数,但稍后可以覆盖它:
typedef void func_type(int,int);
void default_func(int a, int b) { ... }
funt_type* func = default_func; // decays to &default_func !
int main()
{
func(1,2); // calls default_func
func = (func_type*)GetProcAddress(NULL, "func");
func(3,4); // calls func from dll/so
}
我决定使用有点不正统的函数类型(不是函数指针类型)。 IMO,它使语法在视觉上更令人愉悦,并且更容易被人类解析。而且,什么是指针什么不是指针是明确的。