void(*) void 和 int(*) int 在 C 中是什么意思?

what does void(*) void and int(*) int mean in C?

谁能解释一下C:

中的这两行代码
void (*pfs)(void) = &fs;        
long int (*pfact)(int) = &fact; 

使这些声明更加清晰

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 <stdio.h>

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\n", 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 左值、数组和函数指示符)

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’’.

此语法定义了一个函数指针。您可以像这样使用它们:

void a() {
    //do something
}

int main() {
    void (*functionPointer)();
    functionPointer = a;
    //or
    functionPointer = &a;

    //call the funcion pointer as you would a regular function
    functionPointer();
}

使用函数指针的主要原因是制作回调函数和"jump-tables "(这里加引号是因为函数指针数组不是真正的跳转表,真正的跳转表只能用汇编语言制作)。

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 指向函数 fact.

补充说明:

有阅读复杂声明的工具。其中之一是 https://cdecl.org/。 同样正如其他人指出的那样,使用指向函数的指针的更好方法是 typdef them 。

它们是函数指针。在你的例子中:

void (*pfs)(void)=&fs;

您正在创建一个名为 "pfs" 的变量。此变量具有不接受任何参数且 returns 不接受任何参数的函数类型。

下面的示例使您的示例更加清晰。

return_type (*variable_name) (argument_list)

现在,如果你理解了前半部分,= 号的右边就很容易了。

我们所做的就是将函数 "fs" 的位置分配给我们的函数指针(变量)"pfs"。

这里有一个完整的例子来演示上面的解释。

#include <stdio.h>
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);

}