为什么必须使用函数指针? [英] Why must function pointers be used?

查看:261
本文介绍了为什么必须使用函数指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对函数指针的需求是什么?这个标准答案似乎是回调,但为什么我们不能传递一个函数呢?



我在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.

Concept

A 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...

Syntax

If 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".

这篇关于为什么必须使用函数指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆