对函数指针的需求是什么?这个标准答案似乎是回调,但为什么我们不能传递一个函数呢?
我在C ++上读的书演示了一个函数作为参数传递,并承认在实际上编译将它转换为一个函数指针,并传递,而不是因为函数不是实际的对象。它显示了使用函数指针的等效代码,这稍微更复杂一些 - 如果代码是等效的,为什么要使用函数指针。
我假设有一个case when简单地是不可能传递该函数,而且必须传递一个指针?有人可以给我一个这种情况的例子,因为这将帮助我理解为什么函数指针是有用的。
考虑下面的代码:
#include< iostream> using namespace std; int add(int x){ return ++ x; //这是一个副本,所以它不触摸x } void runprint(int function(int x),int x){ cout< function(x)<< endl; } int main(){ runprint(add,1); return 0; }我们传递一个函数作为参数,而不是一个指针。接受函数(!)的函数不接受指针。
解决方案TL; DR
函数和指向函数的指针是相同的。
有一个指针的概念及其用法的语法;
概念指向函数的指针可能不同于函数本身(差别在c ++中没有用 - 见下文),因为函数可能占用很多空间 - 其代码可以是任意复杂的。操作(例如复制或搜索/修改)函数的代码很少有用,因此c / c ++根本不支持它。如果你想修改函数的代码,可以使用 char * 的指针,应用所有必要的预防措施(我从来没有做过)。
因此,如果你正在写C,你所需要的是指向函数的指针。
但是...
语法如果你有一个指针 p 想要调用函数?
(* p)(18) //使用参数18调用函数 p(18); //一样,但看起来更好!有一些稍干净的语法不涉及 * 符号。为了支持它,c / c ++的作者发明了衰变的概念 - 当你的代码提到一个函数时,编译器静静地修正它意味着一个函数的指针(几乎在所有情况下;对不起,不详细说明)。这与vsoftco提到的数组的数组的衰减非常相似。
所以在你的例子中
void runprint(int function(int x),int x){ cout< function(x)<< endl; }function类型实际上是一个指向函数的指针类型。确实,如果你尝试重载:
void runprint(int(* function)(int x),int x) { cout<< function(x)<< endl; }编译器将抱怨两个相同的函数具有相同的参数集。 p>
此外,在创建函数/指针到函数类型的变量时
runprint(add,1);也没关系:
runprint(& add,1); // does exactly the same
当声明一个接收回调的函数时,我主要看到(和使用)明确写入的指针。现在只发生在我看来,它不一致,依赖于函数到指针衰减时调用回调,但不是当声明我的代码。所以如果问题是
为什么每个人都使用指针函数语法来声明回调,当一个函数语法足够时? / p>
我会回答习惯问题。
What is the need for function pointers? The standard answer for this seems to be callbacks, but why can't we just pass a function?
The book I was reading on C++ demonstrates passing a function as a parameter, and acknowledges that in actual fact the compiled turns this into a function pointer and passes that instead, because functions are not actual objects. It showed the equivalent code using function pointers, which was slightly more complex - if the code is equivalent, why bother to use a function pointer.
I presume there is a case when is simply isn't possible to pass the function, and one must pass a pointer instead? Can someone give me an example of this case, as it would help me understand why function pointers are useful.
Consider the following code:
#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; }We are passing a function as a parameter, not a pointer. The function accepting the function (!), is not accepting a pointer.
解决方案TL; DR
"Function" and "pointer to function" is the same.
There is the concept of a pointer, and the syntax of its usage; it's not clear what you are asking about.
ConceptA pointer to a function may be different from the function itself (the difference is not useful in c++ - see below) in that a function may occupy much space - its code can be arbitrarily complex. Manipulating (e.g. copying or searching/modifying) the code of a function is rarely useful, so c/c++ don't support it at all. If you want to modify the code of a function, cast a pointer to char*, applying all the necessary precautions (I have never done it).
So if you are writing C, all you need is pointers to functions.
However...
SyntaxIf you have a pointer p to a function, how do you want to call the function?
(*p)(18); // call the function with parameter 18 p(18); // the same, but looks better!There is the slightly cleaner syntax not involving the * sign. To support it, the authors of c/c++ invented the concept of "decay" - when your code mentions "a function", the compiler silently "corrects" it to mean "a pointer to a function" instead (in almost all circumstances; excuse me for not detailing further). This is very similar to the "decay" of an array to a pointer mentioned by vsoftco.
So in your example
void runprint(int function(int x), int x) { cout << function(x) << endl; }the "function" type is actually a "pointer to function" type. Indeed, if you try to "overload":
void runprint(int (*function)(int x), int x) { cout << function(x) << endl; }the compiler will complain about two identical functions with identical set of parameters.
Also, when making a variable of a function / pointer-to-function type
runprint(add, 1);it also doesn't matter:
runprint(&add, 1); // does exactly the same
P.S. When declaring a function that receives a callback, I have mostly seen (and used) the explicitly written pointer. It has only now occurred to me that it's inconsistent to rely on function-to-pointer decay when calling the callback, but not when declaring my code. So if the question is
why does everyone declare callbacks using a pointer-to-function syntax, when a function syntax would be sufficient?
I'd answer "a matter of habit".
更多推荐
为什么必须使用函数指针?
发布评论