函数指针的解释

Daw*_*dPi 20 c++ pointers typedef function

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

通常当我们想要声明一种类型的函数时,我们会做如下:

typedef void(*functionPtr)(int);
Run Code Online (Sandbox Code Playgroud)

这对我来说没问题.从现在开始,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;
}
Run Code Online (Sandbox Code Playgroud)

我们5打印在屏幕上.

我们有指向函数的指针fun,我们为函数分配了一些现有的指针 - function我们通过指针执行这个函数.凉.

现在正如我在一些书中读到的那样,函数和指向函数的方法在某种程度上是相同的,所以事实上在function()每次声明函数声明函数后我们指的是真正的函数和指向同一类型函数的指针,所以下面的编译和每个指令给出相同的结果(5在屏幕上打印):

int main() {

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

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以现在只要我能想象,那些指向函数和函数的指针几乎是一样的,那么它对我来说就好了.

然后我,如果指向函数和实函数的指针是相同的,那么为什么我不能做以下事情:

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

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

int main() {

    functionPtr fun = function;
    fun(5);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这给了我以下错误:

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

因此我明白,由于某些原因编译器现在理解,这种乐趣已经存在功能.然后我试着跟随:

int main() {

    functionPtr fun;
    fun(5);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到链接错误.我以某种方式理解,因为编译器现在将乐趣视为已经存在的函数,然后由于事实,这种乐趣无法定义,我将得到链接错误.因此我更改了变量的名称:

typedef void(functionPtr)(int);

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

int main() {

    functionPtr function;
    function(5);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以现在功能在主阴影全局名称功能,所以function(5)从声明使用functionPtr function;它工作正常并在屏幕上打印5.

所以现在我很震惊.为什么会这样?另外误导的是,当函数指针被声明为这样:

typedef void(*functionPtr)(int);
Run Code Online (Sandbox Code Playgroud)

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

functionPtr function(int a){
    std::cout << a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

而在宣布类似的东西时:

typedef void(functionPtr)(int);
Run Code Online (Sandbox Code Playgroud)

这样做:

functionPtr function(int a){
    std::cout << a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

被编译器解释为函数返回函数.如果是这样,为什么以前的declaration(typedef void(functionPtr)(int);)知道,这是一个返回void的函数而不是返回functionPtr的函数?

有人可以帮我解释一下真正发生在我身下的情况吗?

我正在使用启用了C++ 14选项的g ++ C++编译器.

Ser*_*eyA 9

嗯,有点令人困惑.

函数类型和指向函数类型的指针实际上是两种不同的类型(不再类似于int和指向它们int).但是,有一个规则,函数类型在几乎所有上下文中都会衰减指向函数类型.这里松散地衰变意味着转换(类型转换和衰减之间存在差异,但你现在可能对它不感兴趣).

重要的是,几乎每次使用函数类型时,最终都会指向函数类型.但是几乎每次都注意到 - 几乎每次都不!

如果没有,你会遇到一些情况.

typedef void(functionPtr)(int);
functionPtr fun = function;
Run Code Online (Sandbox Code Playgroud)

此代码尝试将一个函数(不是指针!函数!)复制到另一个函数.但当然,这是不可能的 - 你不能用C++复制函数.编译器不允许这样,我不敢相信你编译它(你说你有链接器错误吗?)

现在,这段代码:

typedef void(functionPtr)(int);
functionPtr function;
function(5);
Run Code Online (Sandbox Code Playgroud)

function不会影响任何东西.编译器知道它不是可以调用的函数指针,只是调用原始函数function.