【发布时间】:2011-04-10 02:33:48
【问题描述】:
typedef int (fc_name) (void);
这里 fc_name 是任何有效的 C 符号。
这与函数指针 typedef 有何不同?
【问题讨论】:
typedef int (fc_name) (void);
这里 fc_name 是任何有效的 C 符号。
这与函数指针 typedef 有何不同?
【问题讨论】:
这是一个函数类型的typedef。目的是将它用于函数指针,但在这种情况下,使用它的语法是:
int bar(void);
fc_name* foo = bar; /* Note the * */
更新:
正如Jonathan Leffler's answer 的cmets 中所述,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
这段代码表明你确实可以按照jamesdlin的建议使用fc_name *var = funcname;:
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 作为存储类的声明。
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 name 这样做过,但是 function 名称周围的括号有助于防止将其扩展为类似函数同名宏。例如,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没有太大意义。这些被用作 样式标准或只是故意制造混淆;-)
【讨论】:
int handler_func2(fc_name fptr) { return fptr(); },因为 'function' 参数会自动被视为(转换为)函数指针。
正确的形式是:
typedef int (*myfunc)(void);
你可以定义如下函数:
int helloword(void) {
printf("hello, world\n");
}
然后定义一个变量指向这个函数:
myfunc hw_func;
hw_func = helloworld;
并通过函数指针调用函数:
int ret = (*hw_func)();
我们需要函数指针的原因是C语言没有预定义函数指针,使用void *指针调用函数在C语言中是非法的。
【讨论】: