为什么必须使用函数指针?
Why must function pointers be used?
函数指针需要什么?标准答案好像是回调,但是为什么不能只传一个函数呢?
我正在阅读的关于 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;
}
我们将函数作为参数传递,而不是指针。接受函数 (!) 的函数不接受指针。
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
TL;博士
"Function"和"pointer to function"是一样的。
有指针的概念,以及它的使用语法;不清楚你问的是什么。
概念
指向函数的指针可能不同于函数本身(区别在 c++ 中没有用 - 见下文)因为函数可能占用很多 space - 它的代码可以任意复杂。操纵(例如复制或 searching/modifying)函数的代码很少有用,因此 c/c++ 根本不支持它。如果要修改函数的代码,请将指针转换为 char*
,应用所有必要的预防措施(我从未这样做过)。
因此,如果您正在编写 C,您所需要的只是指向函数的指针。
然而...
语法
如果你有一个指向函数的指针p
,你想如何调用该函数?
(*p)(18); // call the function with parameter 18
p(18); // the same, but looks better!
语法稍微简洁一些,不涉及 *
符号。为了支持它,c/c++ 的作者发明了 "decay" 的概念 - 当您的代码提到 "a function" 时,编译器会默默地 "corrects" 表示 "a pointer to a function"相反(在几乎所有情况下;请原谅我没有进一步详细说明)。这与 vsoftco 提到的 "decay" of an array to a pointer 非常相似。
所以在你的例子中
void runprint(int function(int x), int x) {
cout << function(x) << endl;
}
"function"类型实际上是"pointer to function"类型。实际上,如果您尝试 "overload":
void runprint(int (*function)(int x), int x) {
cout << function(x) << endl;
}
编译器会抱怨两个具有相同参数集的相同函数。
此外,在创建函数/函数指针类型的变量时
runprint(add, 1);
也没关系:
runprint(&add, 1); // does exactly the same
P.S。在声明接收回调的函数时,我大多看到(并使用)了显式编写的指针。我现在才想到,在调用回调时依赖函数到指针的衰减是不一致的,但在声明我的代码时却不是。所以如果问题是
why does everyone declare callbacks using a pointer-to-function syntax, when a function syntax would be sufficient?
我会回答 "a matter of habit"。
函数指针是保存函数地址的指针。
函数指针是在不知道函数名的情况下调用函数。这对于在运行时使用不同的功能很实用。
函数指针需要什么?标准答案好像是回调,但是为什么不能只传一个函数呢?
我正在阅读的关于 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;
}
我们将函数作为参数传递,而不是指针。接受函数 (!) 的函数不接受指针。
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
TL;博士
"Function"和"pointer to function"是一样的。
有指针的概念,以及它的使用语法;不清楚你问的是什么。
概念
指向函数的指针可能不同于函数本身(区别在 c++ 中没有用 - 见下文)因为函数可能占用很多 space - 它的代码可以任意复杂。操纵(例如复制或 searching/modifying)函数的代码很少有用,因此 c/c++ 根本不支持它。如果要修改函数的代码,请将指针转换为 char*
,应用所有必要的预防措施(我从未这样做过)。
因此,如果您正在编写 C,您所需要的只是指向函数的指针。
然而...
语法
如果你有一个指向函数的指针p
,你想如何调用该函数?
(*p)(18); // call the function with parameter 18
p(18); // the same, but looks better!
语法稍微简洁一些,不涉及 *
符号。为了支持它,c/c++ 的作者发明了 "decay" 的概念 - 当您的代码提到 "a function" 时,编译器会默默地 "corrects" 表示 "a pointer to a function"相反(在几乎所有情况下;请原谅我没有进一步详细说明)。这与 vsoftco 提到的 "decay" of an array to a pointer 非常相似。
所以在你的例子中
void runprint(int function(int x), int x) {
cout << function(x) << endl;
}
"function"类型实际上是"pointer to function"类型。实际上,如果您尝试 "overload":
void runprint(int (*function)(int x), int x) {
cout << function(x) << endl;
}
编译器会抱怨两个具有相同参数集的相同函数。
此外,在创建函数/函数指针类型的变量时
runprint(add, 1);
也没关系:
runprint(&add, 1); // does exactly the same
P.S。在声明接收回调的函数时,我大多看到(并使用)了显式编写的指针。我现在才想到,在调用回调时依赖函数到指针的衰减是不一致的,但在声明我的代码时却不是。所以如果问题是
why does everyone declare callbacks using a pointer-to-function syntax, when a function syntax would be sufficient?
我会回答 "a matter of habit"。
函数指针是保存函数地址的指针。 函数指针是在不知道函数名的情况下调用函数。这对于在运行时使用不同的功能很实用。