【问题标题】:Function pointer expression函数指针表达式
【发布时间】:2018-01-13 12:53:54
【问题描述】:

所以我得到了以下表达式:

int (*f1(int(*a)(int, int))) (int, int);

我试图理解它,但它令人困惑。我发现“a”是一个指向带有 2 个参数(int,int)的函数的指针。 然后 f1 似乎是指向另一个接受 2 个 int 参数的函数的指针。 但令我困惑的是 f1 与 a 的关系。

有人可以给我一些提示或正确解释上述表达式的作用吗?

【问题讨论】:

  • 请告诉我为什么人们使用函数指针编写 C++ 代码。 std::function 可用
  • 这不是问题的重点。我有这条线,我正试图弄清楚它的含义,但我被卡住了。
  • cdecl.org 说:“将 f1 声明为函数(指向函数 (int, int) 返回 int)返回指向函数 (int, int) 返回 int 的指针”
  • How do I understand complicated function declarations? 的可能重复我确实看到这个问题是关于 C 的,而这个问题是关于 C++ 的,但这个问题没有任何 C++ 特定的内容。

标签: c++ pointers


【解决方案1】:

它将f1 声明为带有一个名为a 的单个参数的函数。参数类型和返回类型都是“指向带有两个int参数返回int的函数的指针”。


你是这样解析它的:

// f1 is...
      f1
// ...a function...
      f1(                 )
// ...with a single parameter called `a`, which is...
      f1(     a           )
// ...a pointer to...
      f1(    *a           )
// (skip parentheses)
      f1(   (*a)          )
// ...a function...
      f1(   (*a)(        ))
// ...with two `int` parameters...
      f1(   (*a)(int, int))
// ...returning an `int`. The `f1` itself returns...
      f1(int(*a)(int, int))
// ...a pointer to...
     *f1(int(*a)(int, int))
// (skip parentheses)
    (*f1(int(*a)(int, int)))
// ...a function...
    (*f1(int(*a)(int, int))) (        )
// ...with two int parameters...
    (*f1(int(*a)(int, int))) (int, int)
// ...returning an `int`.
int (*f1(int(*a)(int, int))) (int, int)

【讨论】:

    【解决方案2】:

    这是函数f1的声明,它接受一个参数a-一个指向函数的指针,它接受2个ints作为参数并返回一个int-并返回一个指向相同函数的指针输入。

    用 typedef 分解它:

    typedef int(*t)(int, int);
    
    t f1(t a); //this is your declaration
    

    【讨论】:

      【解决方案3】:

      C 中的技巧是将声明当作表达式来阅读。正是这种著名的对称性使 C 变得优雅。

      如何阅读?遵循运算符优先规则:

      1. *a: 如果我取消引用变量a;
      2. (*a)(int,int): 然后用两个整数调用它;
      3. int (*a)(int,int):那我得到一个整数;

      所以a 是一个指向以两个ints 作为参数并返回一个int 的函数的指针。

      然后:

      1. f( int(*a)(int,int) ) 如果我使用参数 a 调用 f;
      2. *f( int(*a)(int,int) ) 然后我取消引用结果;
      3. (*f( int(*a)(int,int) )(int,int) 然后用 2 int 作为参数调用这个结果
      4. int (*f( int(*a)(int,int) )(int,int) 我得到一个int

      所以f 是一个以a 作为参数并返回一个指向以两个ints 作为参数并返回int 的函数的函数的函数。所以f 返回类型与其参数返回类型相同。本来可以更简单的:

      using ftype = int(*)(int,int);
      ftype f( ftype a);
      

      【讨论】:

      • 请注意,C++ 使用引用扩展此 C 语法的方式似乎并未遵循此模式。例如。 int &x;x 声明为对 int 的引用,但这并不意味着 &x 具有 int 类型(它实际上具有 int* 类型)。因此,只有当您的声明中没有引用时,这一切都是正确的。
      • Arhhh 引用是怪物:具有指向对象语义的 const 指针。
      【解决方案4】:

      af1唯一参数的名称;当您删除它时,您可以使用https://cdecl.org/ 来破译整个声明:

      将 f1 声明为函数(指向函数 (int, int) 返回 int 的指针) 返回指向函数的指针 (int, int) 返回 int

      所以f1 是一个函数。它接受一个函数指针(称为a)并返回一个函数指针。

      这两个函数指针都用于接受两个 ints 并返回一个 int 的函数。

      下面是一个例子,可以看到这一切:

      #include <iostream>
      
      int passed(int x, int y) { std::cout << "passed\n"; return x * y; }
      int returned(int x, int y) { std::cout << "returned\n"; return x + y; }
      
      // a is redundant here, where we just declare f1:
      int (*f1(int(*a)(int, int))) (int, int);
      
      // but not here, where we define f1:
      int (*f1(int(*a)(int, int))) (int, int)
      {
          std::cout << "f1\n";
          int result_of_passed = a(10, 10);
          std::cout << result_of_passed << '\n';
          return returned;
      }
      
      int main()
      {
          int x = f1(passed)(10, 10);
          std::cout << x << '\n';
      }
      

      输出:

      f1
      passed
      100
      returned
      20
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-31
        • 2016-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-23
        相关资源
        最近更新 更多