代码之家  ›  专栏  ›  技术社区  ›  Hemanth

带圆括号的typedef像“typedef int(f)(void)”是什么意思?它是函数原型吗?

  •  27
  • Hemanth  · 技术社区  · 14 年前
    typedef int (fc_name) (void);
    

    在这里 fc_name 是任何有效的C符号。

    这和函数指针有什么不同 typedef ?

    6 回复  |  直到 6 年前
        1
  •  34
  •   Community CDub    8 年前

    这是一个 typedef 函数类型。其目的是将其用于函数指针,但在这种情况下,使用它的语法是:

    int bar(void);
    
    fc_name* foo = bar; /* Note the * */
    

    更新: 如评论所述 Jonathan Leffler's answer , the 类型定义 可用于声明函数。一种用途是声明一组回调函数:

    typedef int (callback)(int, void*);
    
    callback onFoo;
    callback onBar;
    callback onBaz;
    callback onQux;
    
        2
  •  17
  •   Community CDub    8 年前

    第一个括号是多余的-它相当于:

    typedef int fc_name(void);
    

    我不认为这有什么用,尽管我不能让GCC自己抱怨。

    这意味着 fc_name 是不带参数并返回 int . 虽然您可以声明,例如, rand() 功能使用:

    fc_name rand;
    

    您不能使用 typedef 在函数定义中。

    指向函数typedef的指针将读取:

    typedef int (*fc_name)(void);
    

    此代码显示不带星号的typedef不是函数指针(用于处理现已删除的可选答案):

    static int function(void)
    {
        return 0;
    }
    
    typedef int   fc_name1 (void);
    typedef int  (fc_name2)(void);
    typedef int (*fc_name3)(void);
    
    fc_name1 x = function;
    fc_name2 y = function;
    fc_name3 z = function;
    

    编辑时,“GCC”说:

    gcc -Wextra -Wall -pedantic -c -O x.c
    x.c:10:1: error: function ‘x’ is initialized like a variable
    x.c:11:1: error: function ‘y’ is initialized like a variable
    

    这段代码说明您确实可以使用 fc_name *var = funcname; 正如建议的那样 jamesdlin :

    static int function(void)
    {
        return 0;
    }
    
    typedef int   fc_name1 (void);
    typedef int  (fc_name2)(void);
    typedef int (*fc_name3)(void);
    
    fc_name1  x_0 = function;
    fc_name1 *x_1 = function;
    fc_name2  y_0 = function;    // Damn Bessel functions - and no <math.h>
    fc_name2 *y_1 = function;    // Damn Bessel functions - and no <math.h>
    fc_name3  z   = function;
    

    使用y0,y1生成gcc警告:

    x.c:12:11: warning: conflicting types for built-in function ‘y0’
    x.c:13:11: warning: built-in function ‘y1’ declared as non-function
    

    并且,基于 schot :

    static int function(void)
    {
        return 0;
    }
    
    typedef int   fc_name1 (void);
    typedef int  (fc_name2)(void);
    typedef int (*fc_name3)(void);
    
    fc_name1  x_0 = function;   // Error
    fc_name1 *x_1 = function;   // x_1 is a pointer to function
    fc_name1  x_2;              // Declare int x_2(void);
    fc_name1 *x_3 = x_2;        // Declare x_3 initialized with x_2
    
    fc_name2  y_0 = function;   // Damn Bessel functions - and no <math.h>
    fc_name2 *y_1 = function;   // Damn Bessel functions - and no <math.h>
    fc_name1  y_2;              // Declare int y_2(void);
    fc_name1 *y_3 = x_2;        // Declare y_3 initialized with y_2
    
    fc_name3  z   = function;
    

    有趣的是,C的暗角确实很暗。

        3
  •  1
  •   nickhar    12 年前

    很有趣!typedef声明是以typedef作为存储类的声明。

    typedef int   fc_name1 (void);   
    // this defines a function type called fc_name1 
    // which takes no parameter and returns int
    

    稍后,您可以定义如下函数:

    fc_name1 myFunc;
    // this is equivalent to the next line
    // int myFunc(void);
    

    你应该能够从C/C++标准中理解这一点!

        4
  •  1
  •   zwol    8 年前

    我以前从没见过这样对 类型名称 ,但在 功能 用于防止其扩展为类似于同名宏的函数。例如, isxxx 功能在 ctype.h 定义为函数和宏。所以你可以用指针指向 isalpha . 但是C图书馆怎么办 定义 脱线 是否字母 ?可能是这样:

    #include <ctype.h>
    
    int
    (isalpha)(int c)
    {
        return isalpha(c);
    }
    

    使用 是否字母 在函数体被扩展为宏时,函数头中的用法不是。

        5
  •  0
  •   diabloneo 1077    14 年前

    正确的形式是:

    typedef int (*myfunc)(void);
    

    您可以定义如下函数:

    int helloword(void) {
        printf("hello, world\n");
    }
    

    然后定义此函数的变量点:

    myfunc hw_func;
    hw_func = helloworld;
    

    并通过函数指针调用函数:

    int ret = (*hw_func)();
    

    我们需要函数指针的原因是C语言没有预定义的函数指针并使用 void * 调用函数的指针在C语言中是非法的。

        6
  •  0
  •   Jonathan Leffler    6 年前
      1 #include <stdio.h>
      2 
      3 
      4 typedef int (fc_name)(void);
      5 
      6 
      7 
      8 int test_func1 ()
      9 {
     10     printf("\n test_func1 called\n");
     11 
     12     return 0;
     13 }
     14 
     15 int test_func2 (void)
     16 {
     17     printf("\n test_func2 called\n");
     18     return 0;
     19 }
     20 
     21 int handler_func(fc_name *fptr)
     22 {
     23     //Call the actual function
     24     fptr();
     25 }
     26 
     27 int main(void)
     28 {
     29     fc_name  *f1, *f2;
     30 
     31     f1 = test_func1;
     32     f2 = test_func2;
     33 
     34     handler_func(f1);
     35     handler_func(f2);
     36 
     37     printf("\n test complete\n");
     38 
     39     return 0;
     40 }
    

    输出:

     test_func1 called
    
     test_func2 called
    
     test complete
    

    所以我质疑的typedef(这里是第4行)代表 函数类型和与函数指针typedef不同。 这种typedef没有多大意义。这些被用作 样式标准或只是有意创建混淆;-)