簡體   English   中英

帶括號的typedef像“ typedef int(f)(void)”是什么意思? 它是功能原型嗎?

[英]What does a typedef with parenthesis like “typedef int (f)(void)” mean? Is it a function prototype?

typedef int (fc_name) (void);

fc_name是任何有效的C符號。

這與函數指針typedef有何不同?

它是函數類型的typedef 目的是將其用於函數指針,但在這種情況下,使用的語法為:

int bar(void);

fc_name* foo = bar; /* Note the * */

更新:如對Jonathan Leffler的回答的評論中所述, typedef可用於聲明函數。 一種用途是聲明一組回調函數:

typedef int (callback)(int, void*);

callback onFoo;
callback onBar;
callback onBaz;
callback onQux;

第一個括號是多余的-等效於:

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的黑暗角落確實很模糊。

有趣! 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 ++標准中弄清楚這一點!

我從未見過對typedef名稱執行此操作,但是在函數名稱周圍加括號可防止將其擴展為相同名稱的類似函數的宏。 例如,將ctype.h中的isxxx函數定義為函數和宏。 這樣一來,您可以將指針指向isalpha 但是C庫如何定義離線isalpha 大概是這樣的:

#include <ctype.h>

int
(isalpha)(int c)
{
    return isalpha(c);
}

函數主體中isalpha的使用將擴展為宏,而函數標頭中的使用則不是。

  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沒有太大的意義。 這些用作樣式標准或只是故意創建混淆;-)

正確的形式是:

typedef int (*myfunc)(void);

您可以定義如下函數:

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

然后定義一個指向該函數的變量:

myfunc hw_func;
hw_func = helloworld;

並通過函數指針調用該函數:

int ret = (*hw_func)();

我們需要函數指針的原因是C語言沒有預定義的函數指針,而在C語言中使用void *指針調用函數是非法的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM