对函数指针有什么需求?对此的标准答案似乎是回调,但为什么我们不能只传递函数?
我在C ++上阅读的这本书演示了将函数作为参数传递,并确认实际上编译后将其转换为函数指针并传递它,因为函数不是实际对象。它显示了使用函数指针的等效代码,这稍微复杂一些 - 如果代码是等效的,为什么还要使用函数指针。
我认为有一种情况是简单地无法传递函数,而且必须传递一个指针?有人可以给我一个这种情况的例子,因为它可以帮助我理解为什么函数指针是有用的。
请考虑以下代码:
#include <iostream>
using namespace std;
int add(int x) {
return ++x; //this is a copy, so it doesn't touch x
}
void runprint(int function(int x), int x) {
cout << function(x) << endl;
}
int main() {
runprint(add, 1);
return 0;
}
我们将函数作为参数传递,而不是指针。接受函数(!)的函数不接受指针。
答案 0 :(得分:3)
function
被g ++视为函数指针:
$ cat fp.cpp
#include <typeinfo>
#include <iostream>
using namespace std;
int add(int x) {
return ++x; //this is a copy, so it doesn't touch x
}
void runprint(int function(int x), int x) {
cout << typeid(function).name() << endl;
int (*f)(int); // function pointer compatible with function argument
f = function;
cout << typeid(f).name() << endl;
cout << function(x) << endl;
}
int main() {
runprint(add, 1);
return 0;
}
$ g++ -Wall -std=c++11 -o fp fp.cpp
$ ./fp
PFiiE
PFiiE
2
答案 1 :(得分:1)
&#34;作用&#34;和&#34;指向功能的指针&#34;是一样的。
有一个指针的概念,以及它的用法语法;它不清楚你在问什么。
指向函数的指针可能与函数本身不同(差异在c ++中没有用 - 见下文),因为函数可能占用很多空间 - 它的代码可能是任意复杂的。操作(例如复制或搜索/修改)函数的代码很少有用,因此c / c ++根本不支持它。如果要修改函数的代码,请将指针强加到char*
,并应用所有必要的预防措施(我从未这样做过)。
因此,如果您正在编写C语言,那么您只需要指向函数。
...然而
如果你有一个函数指针p
,你想如何调用该函数?
(*p)(18); // call the function with parameter 18
p(18); // the same, but looks better!
语法稍微清晰,不涉及*
符号。为了支持它,c / c ++的作者发明了&#34;衰变&#34; - 当你的代码提到&#34;一个函数&#34;时,编译器默默地&#34;纠正&#34;它意味着&#34;指向函数的指针&#34;相反(几乎在所有情况下;请原谅我没有进一步详细说明)。这非常类似于&#34;衰变&#34;一个数组到vsoftco提到的指针。
所以在你的例子中
void runprint(int function(int x), int x) {
cout << function(x) << endl;
}
&#34;功能&#34; type实际上是&#34;指向函数的指针&#34;类型。事实上,如果你试图超载&#34;:
void runprint(int (*function)(int x), int x) {
cout << function(x) << endl;
}
编译器会抱怨具有相同参数集的两个相同函数。
此外,在创建函数/指向函数类型的变量时
runprint(add, 1);
它也无关紧要:
runprint(&add, 1); // does exactly the same
P.S。当声明一个接收回调的函数时,我主要看到(并使用过)明确写入的指针。我现在才想到,在调用回调时依赖于函数到指针的衰减是不一致的,但在声明我的代码时则不然。所以如果问题是
当函数语法足够时,为什么每个人都使用指向函数的语法声明回调?
我回答&#34;习惯问题&#34;。