本问题已经有最佳答案,请猛点这里访问。
任何人都可以在C中解释这两行代码:
void (*pfs)(void) = &fs;
long int (*pfact)(int) = &fact;
这些是函数指针
请参阅C中的函数指针如何工作?
C中的"void(* f)(void)"是什么意思应该搜索SO而不是google;)
此语法定义函数指针。您可以像这样使用它们:
void a() {
//do something
}
int main() {
void (*functionPointer)();
functionPointer = a;
//or
functionPointer = &a;
//call the funcion pointer as you would a regular function
functionPointer();
}
使用函数指针的主要原因是使回调函数和"跳转表"(这是引号,因为函数指针数组实际上不是跳转表。真正的跳转表只能用汇编语言编写)。
使这些声明更清楚
void (*pfs)(void)=&fs;
long int (*pfact)(int)=&fact;
例如,您可以为函数声明引入typedef名称
typedef void FUNC1( void );
typedef long int FUNC2( int );
然后写
FUNC1 *pfs = &fs;
FUNC2 *pfact = &fact;
因此,原始声明声明指向指定类型的函数的指针,并使用给定函数的地址初始化它们。
这是一个示范计划
#include
typedef void FUNC1( void );
typedef long int FUNC2( int );
void fs( void )
{
puts("Hello Islacine" );
}
long int fact( int x )
{
return x;
}
int main(void)
{
FUNC1 *pfs = &fs;
FUNC2 *pfact = &fact;
pfs();
printf("sizeof( long int ) = %zu
", sizeof( pfact( 0 ) ) );
return 0;
}
它的输出可能看起来像
Hello Islacine
sizeof( long int ) = 8
考虑到而不是
FUNC1 *pfs = &fs;
FUNC2 *pfact = &fact;
或者代替
void (*pfs)(void)=&fs;
long int (*pfact)(int)=&fact;
你甚至可以写
FUNC1 *pfs = fs;
FUNC2 *pfact = fact;
要么
void (*pfs)(void) = fs;
long int (*pfact)(int) = fact;
因为在极少数例外的表达式中,函数指示符被转换为指向函数的指针。
你甚至可以写:)
FUNC1 *pfs = *****fs;
FUNC2 *pfact = *****fact;
要么
void (*pfs)(void) = *****fs;
long int (*pfact)(int) = *****fact;
来自C标准(6.3.2.1 Lvalues,数组和函数指示符)
4 A function designator is an expression that has function type.
Except when it is the operand of the sizeof operator65) or the unary &
operator, a function designator with type ‘‘function returning type’’
is converted to an expression that has type ‘‘pointer to function
returning type’’.
事实上,我发现了一个OpenGL ES头文件(在官方Khronos网站上)。
这是将typedef用于函数指针的一种不寻常的方式。更常见的是:typedef void (*voidFnVoid_t)( void ) ;然后voidFnVoid_t pfs = fs。在这里的FUNC1的typedef中,你不能声明一个FUNC1类型的对象,只能声明FUNC1*,所以它没有任何意图拥有"函数类型"而不是"函数指针类型"。
@Clifford这个帖子在您的意见声明中并不常见或不常见。这篇文章是关于如何理解声明的。
@VladfromMoscow:这不是批评,只是为了避免任何混淆而给读者留言。 OP不理解语法,并且可能会遇到我建议的形式,并且也会被它混淆。我建议他不太可能遇到你的表格 - 就是这样。如果我有一个基本上更好的答案我会发布它。
@ Cppplus1:实际上OpenGL头文件使用typedef作为我建议的函数指针,而不是在这个答案中显示(虽然隐藏在宏层之下)。
@Clifford这就是我的意思 - typedef。
@ Cppplus1:你误解了我的观点; Vlad的typedef与OpenGL中的类型不同。要清楚它不是我所指的命名约定,而是typedef void FUNC1( void ) vs typedef void (*FUNC1)(void)来使用Vlad的命名风格。
@Clifford我没注意那个。我刚读了"typedefs"并写了评论。
@Clifford您可以使用typedef来声明函数。
@VladfromMoscow:的确,我的错误。然而,这也许是不寻常的 - 我无法看到一个用例。但正如你所说,也许这是不重要的。
@Clifford例如在C ++中,这可以用于声明静态成员函数。
它们是函数指针。在你的例子中:
void (*pfs)(void)=&fs;
您正在创建名为"pfs"的变量。此变量具有不带参数且不返回任何参数的函数类型。
以下内容使您的示例更加清晰。
return_type (*variable_name) (argument_list)
如果您了解上半部分,那么=符号的右侧非常容易。
我们所做的就是将函数"fs"的位置分配给我们的函数指针(变量)"pfs"。
以下是演示上述解释的完整示例。
#include
void my_print_method(int number) {
printf("The number is: %d", number);
}
int main() {
// Declare our function pointer variable
void (*printer)(int);
// Assign our function pointer 'printer' to the method 'my_print_method'
printer = &my_print_method
// We can also assign the method to our function pointer as such:
printer = my_print_method
// Use our function pointer as if it were a function
(*printer)(55);
// Keep in mind that that in C we can simply write the function call as such:
printer(55);
}
what does void(* ) (void) and int(* ) (int) mean in C?
它们只是指向函数的指针,该函数采用void参数并返回void。
void (*pfs)(void)=&fs;
pfs是一个指向函数的指针,它将void作为参数并返回void。
这已初始化为具有相同签名类型的功能,即此处为fs。
long int (*pfact)(int)=&fact;
pfact是一个指向函数的指针,它将int作为参数并重新引入long int。
赋值后pfact指向函数事实。
附加说明:
有阅读复杂声明的工具。其中之一是https://cdecl.org/。
此外,正如其他人已经指出更好的方法来使用指向函数的指针是typdef他们。