函数指针说明 [英] Explanation of function pointers

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

问题描述

我有一个理解一些C ++语法结合函数指针和函数声明的问题,即:



通常当我们声明一个类型的函数类似:

  typedef void(* functionPtr)(int); 

这对我来说很好。从现在开始,functionPtr是一个类型,它代表
指向函数的指针,返回void并以一个值作为参数接受int。



它如下:

  typedef void(* functionPtr)(int); 

void function(int a){
std :: cout< a<< std :: endl;
}

int main(){

functionPtr fun = function;
fun(5);

return 0;
}

我们得到 5 打印在屏幕上。



我们有一个指向函数 fun 的指针, function ,我们通过指针执行这个函数。 Cool。



现在我在一些书中读到,函数和函数的指针被以某种方式处理,所以实际上在声明 function )函数每次我们说函数是指真正的函数和指向相同类型的函数,所以以下编译和每个指令给出相同的结果(5在屏幕上打印):

  int main(){

functionPtr fun = function;
fun(5);
(* fun)(5);
(* function)(5);
function(5);

return 0;
}

现在只要我想象,函数和函数的指针



然后我认为,如果指针的函数和真正的函数是相同的,那么为什么我不能这样做: / p>

  typedef void(functionPtr)(int); // removed * 

void function(int a){
std :: cout< a<< std :: endl;
}

int main(){

functionPtr fun = function;
fun(5);

return 0;
}

这会产生以下错误:


prog.cpp:12:14:warning:声明'void fun(int)'有'extern'并初始化
functionPtr fun = function;


因此,我理解,由于编译器现在理解的某些原因,这种乐趣是已经存在的函数。然后我尝试以下:

  int main(){

functionPtr fun;
fun(5);

return 0;
}

我不知何故理解,作为编译器现在把乐趣作为已经存在的函数,然后由于事实,那个乐趣是没有定义,我会得到链接错误。因此我改变了变量的名称:

  typedef void(functionPtr)(int); 

void function(int a){
std :: cout< a<< std :: endl;
}

int main(){

functionPtr function;
function(5);

return 0;
}

现在函数在主阴影全局名函数中,因此 function(5)从声明 functionPtr函数; 使用它工作正常,并在屏幕上打印5。



现在我很震惊。为什么会发生?另外误导的是,当函数指针声明如下:

  typedef void(* functionPtr)(int); 

我可以用以下方式创建functionPtr类型的函数:

  functionPtr函数(int a){
std :: cout< a<< std :: endl;
}

,而声明像:

  typedef void(functionPtr)(int); 

使得:

  functionPtr function(int a){
std :: cout< a<< std :: endl;
}

由编译器解释为函数返回函数。如果是这样,为什么前面的声明( typedef void(functionPtr)(int); )知道,这是一个函数返回void和不返回functionPtr? >

有人可以解释一下为我真正发生的事情吗?



我使用g ++ C ++编译器与C ++ 14选项已启用。

解决方案

好吧,这有点混乱。



函数类型和指向函数类型的指针确实是两种不同类型(不再类似于 int 和指向 int 的指针) 。然而,有一个规则,在几乎所有上下文中,函数类型衰减为指向函数类型的指针。这里松动意味着转换 (类型转换和衰变之间有差异,但是您现在可能不感兴趣)



重要的是,每次使用一个函数类型时,几乎,你最终得到函数类型的指针。注意,几乎每一次都不是总是



当你没有遇到某些情况时,

  typedef void(functionPtr)(int); 
functionPtr fun = function;

此代码试图将一个函数(而不是指针!但是当然,这是不可能的 - 你不能复制C ++中的函数。编译器不允许这个,我不敢相信你编译了(你说你有链接器错误?)



现在,这段代码:

  typedef void(functionPtr)(int); 
functionPtr function;
function(5);

函数编译器知道它不是一个可以调用的函数指针,只是调用你原来的函数


I have a problem with understanding some C++ syntax combined with function pointers and function declarations, that is:

Usually when we want to declare a type of function we make something like:

typedef void(*functionPtr)(int);

and this is fine for me. From now on functionPtr is a type, that represents pointer to the function, that returns void and takes int by a value as an argument.

We can use it as follows:

typedef void(*functionPtr)(int);

void function(int a){
    std::cout << a << std::endl;
}

int main() {

    functionPtr fun = function;
    fun(5);

    return 0;
}

And we get 5 printed on a screen.

we have got pointer to function fun, we assign some existing pointer to function - function and we execute this function by a pointer. Cool.

Now as I read in some books, function and pointer to function are treated somehow the same, so in fact after declaration of function() function everytime we say function we mean real function and pointer to function at the same type, so following compiles and every instruction gives the same result (5 printed on a screen):

int main() {

    functionPtr fun = function;
    fun(5);
    (*fun)(5);
    (*function)(5);
    function(5);

    return 0;
}

So now as long as I can imagine, that pointers to functions and functions are pretty much the same, then it's somehow fine for me.

Then I though, if pointer to function and real function is the same, then why cannot I do following:

typedef void(functionPtr)(int); //removed *

void function(int a){
    std::cout << a << std::endl;
}

int main() {

    functionPtr fun = function;
    fun(5);

    return 0;
}

This gives me following error:

prog.cpp:12:14: warning: declaration of 'void fun(int)' has 'extern' and is initialized functionPtr fun = function;

therefore I understood, that for some reason compiler now understands, that fun is already existing function. Then I tried following:

int main() {

    functionPtr fun;
    fun(5);

    return 0;
}

And I got linking error. I somehow understand, that as compiler now treats fun as already existing function, then due to the fact, that fun is nowhere defined, I will get linking error. Therefore I changed the name of the variable:

typedef void(functionPtr)(int);

void function(int a){
    std::cout << a << std::endl;
}

int main() {

    functionPtr function;
    function(5);

    return 0;
}

So now function in main shadows global name function, so function(5) is used from declaration functionPtr function; It works fine and prints 5 on the screen.

So now I am shocked. Why did this happen? Also misleading thing is, that when function pointer is declared like this:

typedef void(*functionPtr)(int);

i can create function of type functionPtr in following manner:

functionPtr function(int a){
    std::cout << a << std::endl;
}

whereas, when declaring something like:

typedef void(functionPtr)(int);

makes this:

functionPtr function(int a){
    std::cout << a << std::endl;
}

being interpreted by a compiler as function returning function. If this is so, why previous declaration (typedef void(functionPtr)(int);) knew, that this is a function returning void and not function returning functionPtr?

Could someone please explain what is really happening underhood for me?

I am using g++ C++ compiler with C++14 option enabled.

解决方案

Well, it is confusing a bit.

Function type and pointer to function type are indeed two different types (no more similar than int and pointer to int). However, there is a rule, that a function type decays to pointer to function type in almost all contexts. Here decaying loosely means converted (there is a difference between type conversion and decaying, but you are probably not interested in it right now).

What is important, is that almost every time you use a function type, you end up with pointer to function type. Note the almost, however - almost every time is not always!

And you are hitting some cases when it doesn't.

typedef void(functionPtr)(int);
functionPtr fun = function;

This code attempts to copy one function (not the pointer! the function!) to another. But of course, this is not possible - you can't copy functions in C++. The compiler doesn't allow this, and I can't believe you got it compiled (you are saying you got linker errors?)

Now, this code:

typedef void(functionPtr)(int);
functionPtr function;
function(5);

function does not shadow anything. Compiler knows it is not a function pointer which can be called, and just calls your original function.

这篇关于函数指针说明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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