【问题标题】:typedef a function interface (not function pointer)typedef 一个函数接口(不是函数指针)
【发布时间】:2014-04-14 14:10:48
【问题描述】:

如果我这样输入定义:

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

定义here

这种技术叫什么?

如果我以这种方式 typedef,这意味着我创建了一个类型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;

这是正确的吗?通常,如果我 typedef 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;

在什么情况下我会选择一个?

【问题讨论】:

    标签: c function-pointers typedef


    【解决方案1】:

    不同之处在于,在第一种情况下,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);
    

    【讨论】:

      【解决方案2】:

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

      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 它:

      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;
      

      【讨论】:

        【解决方案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 不行。

        【讨论】:

          【解决方案4】:

          在所有绝对所有情况下,您都应该更喜欢使用

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

          例如read_proc 是指向 read_proc_t 类型函数的指针。 请注意,代码清楚地表达了正在做什么。使用秒方法,您会得到read_proc_t read_proc,它完全隐藏了指针方面。

          【讨论】:

            猜你喜欢
            • 2011-05-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-01-12
            • 2013-09-09
            • 1970-01-01
            • 2017-04-18
            • 1970-01-01
            相关资源
            最近更新 更多