【问题标题】:C function pointer syntaxC 函数指针语法
【发布时间】:2012-12-16 09:20:28
【问题描述】:

我的问题很简单。

通常,在声明某个变量时,您会将其类型放在其前面,例如:

int a;

函数指针的类型可能类似于:int(*)(int,int),以防我们指向一个接受两个整数并返回一个整数的函数。但是,当声明这样一个指针时,它的标识符不在类型之后,比如:

int(*)(int,int) mypointer;

相反,你必须在中间写上标识符:

int(*mypointer)(int,int);

为什么会这样? 抱歉,我知道这是一个令人尴尬的简单问题...

感谢大家的回复。 A.S.

【问题讨论】:

  • 这不是唯一的情况,你也可以在数组声明中使用这种样式。
  • 搜索“声明反映使用”。
  • 这个 Q 有助于解释 Typedef 语法 typedef old-type alias-identifier 但示例函数指针示例如“typedef int (*sum_func)(int,int);”语法不匹配...直到现在!

标签: c declare


【解决方案1】:

我在对Why was the C syntax for arrays, pointers, and functions designed this way? 的回答中对此进行了解释,基本上可以归结为:

语言作者更喜欢使语法以变量为中心而不是以类型为中心。也就是说,他们希望程序员查看声明并思考“如果我写表达式*func(arg),那将导致int;如果我写*arg[N],我将有一个浮点数”而不是“ func 必须是指向一个函数的指针,该函数采用 this 并返回 that"。

C entry on Wikipedia 声称:

Ritchie 的想法是在与其使用相似的上下文中声明标识符:“声明反映使用”。

...引用 K&R2 的 p122。

【讨论】:

    【解决方案2】:

    这个结构反映了一个普通函数是如何声明(和使用)的。

    考虑一个普通的函数定义:

    int foo (int bar, int baz, int quux);
    

    现在考虑定义一个指向相同签名函数的函数指针:

    int (*foo) (int, int, int);
    

    注意这两个结构是如何相互镜像的?这使得*foo 更容易被识别为函数指针而不是其他东西。

    【讨论】:

      【解决方案3】:

      如果你正在处理一个函数(不是指向一个函数的指针),名称也在中间。它就像:return-type function-name "(" argument-list ")" ...。例如,int foo(int) 中,int 是返回类型,foo 是名称,int 是参数列表。

      指向函数的指针的工作方式几乎相同——返回类型,然后是名称,然后是参数列表。在这种情况下,我们必须添加一个* 使其成为指针,并且(因为指针的* 是前缀)一对括号将* 绑定到名称而不是返回类型。例如,int *foo(int) 表示一个名为 foo 的函数,它接受一个 int 参数并返回一个指向 int 的指针。为了让 * 绑定到 foo,我们需要括号,给出 int (*foo)(int)

      当您需要一个指向函数的指针数组时,这会变得特别难看。在这种情况下,大多数人发现使用 typedef 作为指针类型最容易,然后创建该类型的数组:

      typedef int (*fptr)(int);
      
      fptr array[10];
      

      【讨论】:

        【解决方案4】:

        我曾在某些地方看到过声明为

        的函数指针
        int (*foo) (int a, int b);
        

        在某些地方,ab 没有被提及,它们仍然有效。

        所以

        int (*foo) (int, int)
        

        也是正确的。

        我发现记住的一个非常简单的方法如下所述:

        假设函数声明为:

        int function (int a , int b);
        

        第一步:简单的把函数放在括号里:

        int (function) (int a , int b);
        

        第二步:在函数名前加上*,改名:

        int (*funcPntr) (int a , int b);
        

        PS:在这个答案中,我没有遵循正确的命名约定等编码准则。

        【讨论】:

        • int (*foo) (int a, int b);int (*foo) (int, int); 都有效,因为函数原型中的参数名称在 C 中是可选的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-02
        相关资源
        最近更新 更多