指向函数(C++)的指针

Pointers to Functions (C++)

本文关键字:指针 C++ 函数      更新时间:2023-10-16

我正在学习C++教程。我不能理解这个关于函数指针的例子。这是:-

// pointer to functions
#include <iostream>
using namespace std;
int addition (int a, int b)
{ return (a+b); }
int subtraction (int a, int b)
{ return (a-b); }
int operation (int x, int y, int (*functocall)(int,int))
{
  int g;
  g = (*functocall)(x,y);
  return (g);
}
int main ()
{
  int m,n;
  int (*minus)(int,int) = subtraction;
  m = operation (7, 5, addition);
  n = operation (20, m, minus);
  cout <<n;
  return 0;
}

行"m = operation (7, 5, addition);"answers"n = operation (20, m, minus);"的处理方式相同,但minus已被声明为指向函数的指针,而addition则没有。那么,它们是如何以相同的方式工作的呢?

在函数调用中或在C/C++中赋值运算符的右侧使用函数名作为参数参数,会导致转换为指向原始函数的函数指针。

例如,如果你有一个像这样的功能

void my_function(int a, int b);

如果您使用分配运算符右侧的标识符my_function,如下所示:

void (*my_function_ptr)(int, int) = my_function;

然后,my_function隐式地从函数对象转换为类型为void (*)(int, int)的函数指针,初始化标识符my_function_ptr,使其指向my_function。当将my_function传递给另一个函数(如:)时,也会出现同样的情况

void another_function(int, void (*)(int, int));
another_function(5, my_function);

在对another_function()的调用中,标识符my_function再次被转换为指向原始函数的指针。

最后,请记住,只有当您简单地将标识符名称传递给函数参数,或者将其放在赋值运算符的右侧时,才会发生这种情况。添加使用()符号和可选参数列表(即my_function(5, 6))的函数调用将评估函数,而不会导致转换为函数指针。

addition的类型是int (&)(int,int),它可以衰减为int (*)(int,int)类型的指针,这与operation函数的第三个参数的指针相同。因此,您可以将addition作为第三个参数传递给函数operation

CCD_ 19的类型也与CCD_ 20的类型相同。在代码中,subtraction的地址首先存储为兼容类型的局部变量,然后该变量作为参数传递给operation函数。

addition的情况下,它的地址不作为局部变量存储,而是按原样传递给operation。它直接用函数的地址初始化函数的第三个参数,而不使用任何局部变量。

在这两种情况下都会发生从int (&)(int,int)int (*)(int,int)的转换。只是substration在初始化局部变量时发生转换,而addition在初始化函数参数时发生转换。

一个类比是:

void f(double a, double b) {}
int main()
{
   double x = 100;//first store 100 in a local variable
   f(x, 100);  //pass the local variable as first arg, 
               //and pass 100 as second arg without using any local variable.
}

请注意,100的类型是int,因此它首先转换为double类型,然后将其存储为局部变量x,然后将它作为第一个参数传递给函数f。第二个参数100直接传递给函数,所以即使现在它也首先转换为double,然后初始化b(函数的第二个参数值)。

同样,在这两种情况下都会发生从intdouble的转换。第一个参数转换发生在初始化局部变量x时,而第二个参数转换则发生在初始化函数的第二个参数时。

C中函数的名称解析为其地址。所以这是有效的:

int (*minus)(int,int) = subtraction;

两种解决方案都有效:"运算"的第三个参数必须是函数指针。

请注意,安培数是可选的:

m = operation (7, 5, &addition);

同样有效。

通过将"add"传递给operation(),您实际上将其分配给了"functocall"。这与将"减法"赋给"减号"完全相同。他们的工作方式是一样的,因为他们是一样的。

真正的问题是,为什么不需要一个与号(&)来获取函数的地址?

p.s.除了免费使用iostream、namespace和cout之外,这实际上是一个C教程。正确的

C++提供了隐式函数到指针的转换(请参见C++2003标准中的4.3)。在您的示例中,它既用于subtractionminus的赋值,也用于将addition转换为operation接受的参数类型。因此,本质上两个调用都是以相同的方式完成的,只是在一种情况下,您显式地创建了一个指向函数的指针类型的中间变量。在这两种情况下,优化编译器都会简单地将相应函数的地址传递到operation中。