【问题标题】:what does void(*) void and int(*) int mean in C? [duplicate]void(*) void 和 int(*) int 在 C 中是什么意思? [复制]
【发布时间】:2018-05-05 11:06:38
【问题描述】:

谁能用C解释这两行代码:

void (*pfs)(void) = &fs;        
long int (*pfact)(int) = &fact; 

【问题讨论】:

标签: c pointers function-pointers declaration function-declaration


【解决方案1】:

为了让这些声明更清晰

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 函数指示符是具有函数类型的表达式。 除非它是 sizeof operator65) 的操作数或一元 & 运算符,类型为“函数返回类型”的函数指示符 转换为具有“函数指针”类型的表达式 返回类型''。

【讨论】:

  • 事实上,我发现了一个 OpenGL ES 头文件(在 Khronos 官方网站中)可以做到这一点。
  • 这是一种将 typedef 用于函数指针的不寻常方式。更常见的是:typedef void (*voidFnVoid_t)( void ) ; 然后voidFnVoid_t pfs = fs。在此处FUNC1 的typedef 中,您不能声明FUNC1 类型的对象,只能声明FUNC1*,因此拥有“函数类型”而不是“函数指针类型”是没有用的。跨度>
  • @Clifford 该帖子与您的意见声明中的平常或不寻常无关。这篇文章是关于如何理解声明的。
  • @VladfromMoscow :这不是批评,只是给读者的一个注释,以避免任何混淆。 OP 不理解原来的语法,很可能会遇到我建议的形式并对此感到困惑。我建议他不太可能遇到您的表格-仅此而已。如果我有一个更好的答案,我会发布它。
  • @Clifford 我没注意。我刚刚阅读了“typedefs”并写了评论。
【解决方案2】:

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

void a() {
    //do something
}

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

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

使用函数指针的主要原因是制作回调函数和“跳转表”(这是在引号中,因为函数指针数组不是真正的跳转表。真正的跳转表只能用汇编语言制作)。

【讨论】:

    【解决方案3】:

    它们是函数指针。在您的示例中:

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

    您正在创建一个名为“pfs”的变量。此变量具有不接受任何参数且不返回任何内容的函数类型。

    以下内容使您的示例更加清晰。

    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);
    
    }
    

    【讨论】:

      【解决方案4】:

      void(* ) (void) 和 int(* ) (int) 在 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 。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-03
        • 2011-04-12
        • 2014-02-20
        • 1970-01-01
        • 2012-03-11
        • 1970-01-01
        • 2018-03-16
        相关资源
        最近更新 更多