typedef一个函数接口(不是函数指针)

时间:2014-04-14 14:10:48

标签: c function-pointers typedef

如果我这样输入:

typedef int (read_proc_t)(char *page, char **start, off_t off,
                          int count, int *eof, void *data);

定义为here

这种技术叫做什么?

如果我以这种方式输入,这意味着我创建了一个类型read_proc_t;之后,我创建了自己的read-proc-t版本,即my_read_proc,我有一个这样的结构:

struct test {
    read_proc_t read_proc;
} 

struct test t;

我可以这样做:

t.read_proc_t = my_read_proc;

这是对的吗?通常,如果我将read_proc_t作为函数指针输入:

typedef int (*read_proc_t)(char *page, char **start, off_t off,
                          int count, int *eof, void *data);

我必须将my_read_proc函数地址分配给函数指针,如下所示:

(*t.read_proc_t) = &my_read_proc;

在哪种情况下我选择一个?

4 个答案:

答案 0 :(得分:4)

不同之处在于,在第一种情况下,类型read_proc_t没有获得隐式指针语义,而在第二种情况下,它变为指针类型。

两者之间的区别在于,在大多数情况下无法创建第一种类型的变量。例如,定义struct是违法的:

struct test {
    // This causes an error in C99:
    // field ‘read_proc’ declared as a function
    read_proc_t read_proc;
};

您需要一个星号才能使其有效:

struct test {
    read_proc_t *read_proc;
};

但是,read_proc_t可用于声明函数参数:

void read_something(read_proc_t rd_proc) {
    rd_proc(...); // Invoke the function
}

read_proc_tread_proc_t*之间存在一定程度的互换性:例如,您可以像这样调用上述函数:

read_proc_t *rd = my_read_01;
read_something(rd); // <<== read_proc_t* is passed to read_proc_t

通常,您应该更喜欢第一个声明来保持函数指针语义显式,因为它更易于阅读。如果您使用第二个声明(带星号),您应该以一种告诉读者它是指针的方式命名该类型,例如,如下所示:

typedef int (*read_proc_ptr_t)(char *page, char **start, off_t off,
                      int count, int *eof, void *data);

答案 1 :(得分:3)

它必须是一个指针。所以,如果你像这样输入:

typedef int (read_proc_t)(char *page, char **start, off_t off,
                          int count, int *eof, void *data);

你像这样使用它

read_proc_t *read_proc = my_read_proc;

如果你像这样输入:

typedef int (*read_proc_t)(char *page, char **start, off_t off,
                           int count, int *eof, void *data);

你像这样使用它

read_proc_t read_proc = my_read_proc;

答案 2 :(得分:3)

typedef int (read_proc_t)(char *page, char **start, off_t off,
                      int count, int *eof, void *data);

这会将read_proc_t定义为函数类型,您可以定义指向它的指针,例如read_proc_t *read_proc,但您无法定义此类型的变量。你struct test无效。

答案 3 :(得分:3)

绝大多数情况下你都应该选择使用

typedef int (read_proc_t)(char *page, char **start, off_t off,
                          int count, int *eof, void *data);

而不是

typedef int (*read_proc_t)(char *page, char **start, off_t off,
                          int count, int *eof, void *data);

因为第二种情况隐藏了类型是指针,这很糟糕。第一个定义了一个函数类型。你不能在C中有类型函数的变量,但函数指针很好。所以你的代码应该是:

struct test {
    read_proc_t *read_proc;
}

e.g。 read_proc是指向read_proc_t类型函数的指针。 请注意,代码清楚地表达了正在进行的操作。使用秒方法,您得到read_proc_t read_proc,完全隐藏指针方面。