首页 > 解决方案 > 函数名是c中该函数的第一条指令的地址吗?

问题描述

为什么编译器说这不是指针:

#include <stdio.h>

double f(){ return 1.2; }
int main(){

    int i=0;
    double d =f()[0]; //f() is not pointer? it should be
    printf("%i\n",d);
}

错误:

subscripted value is neither array nor pointer nor vector
  double d =f()[0];

但是如果我声明了一个函数指针,然后使用了一个函数名,那么它就会变成指针:

#include <stdio.h>

int op(int (*op)(int,int), int a, int b){ return op(a,b); }
int add(int a, int b){ return a+b; }

int main(){
    printf("%i\n",op(add, 1, 2)); //here: add() will magically become pointer, different context
}

所以在第一种情况下,我想取消引用该函数,希望函数的名称是指针(因此允许取消引用)。在第二个例子中,函数指针是用指针声明的,所以函数add会衰减到指针(比较printf("%i\n",op(&add,1,2)))也可以工作。那么为什么第一个有问题呢?

标签: c++cfunctionpointers

解决方案


对于一个 function f,或者一般来说 callable ,f()是调用这个函数并计算出声明为函数返回类型的类型。函数可以衰减为指向函数的指针,类似于数组,但是当你调用函数时,这不会发生:

int foo(int,int){ return 1;}

int main() {
    using fptr = int (*)(int,int);
    fptr p = foo;                    // <- function pointer (note: no & needed because it decays to function pointer)
    fptr q = &foo;                   // <- also function pointer
    int x = foo(1,2);                // <- function call
}

在您的示例中:

double d =f()[0]; //f() is not pointer? it should be

不,f()不是指针。f返回一个双倍。

printf("%i\n",op(add, 1, 2)); //here: add() will magically become pointer, different context

不会。add()不会神奇地变成指针。add是会自动衰减为函数指针的函数(实际上它不是“魔法”)。


推荐阅读