2016-01-24 154 views
7

我写了一些代码来知道函数指针是如何工作的。 我在一些IDE上运行以下C++代码,结果是一样的。C++中函数指针的指针

#include "stdafx.h" 

int *function(){ 
    static int a=1; 
    return &a; 
} 
typedef struct{ 
    int *(*pt_1)(); 
    int *(*pt_2)(); 
}x_t; 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    x_t s; 
    s.pt_1 = function; 
    s.pt_2 = &function; 

    printf("%x\n",s.pt_1); //Result: 0x013011a9 
    printf("%x\n",*s.pt_1); //Result: 0x013011a9 
    printf("%x\n",**s.pt_1); //Result: 0x013011a9 
    printf("%x\n",s.pt_1()); //Result: 0x01307000 
    printf("%x\n",*s.pt_1()); //Result: 1 

    printf("%x\n",s.pt_2); //Result: 0x013011a9 
    printf("%x\n",*s.pt_2); //Result: 0x013011a9 
    printf("%x\n",**s.pt_2); //Result: 0x013011a9 
    printf("%x\n",s.pt_2()); //Result: 0x01307000 
    printf("%x\n",*s.pt_2()); //Result: 1 

    return 0; 
} 

我的问题:

    1. 为什么s.pt_1 == s.pt_2 == *s.pt_1 = **s.pt_1
  • 凡地址是否s.pt_1()点?它在哪里找到内存?
+3

1,请参阅[this](http://stackoverflow.com/questions/2795575/how-does-dereferencing-of-a-function-pointer-happen)。 2. operator()调用函数,所以你正在处理它的返回指针。 – LogicStuff

+1

由'%x'打印函数指针会调用未定义的行为,因为地址可能不适合'int'。使用'printf(“%p \ n”,(void *)s。' –

+0

我在这里找到了第二个问题的答案[内存中的内存是否存储在内存中的返回值?](http://stackoverflow.com/questions/5472008/where-in-memory-are-return-values -stored式存储器) –

回答

4

与使用数组名称类似,使用函数名称会使其衰减为最轻微的挑衅指针。

s.pt_1 = function;  

这里function衰变成指向函数的指针。

s.pt_2 = &function; 

在这里,您实际上将函数的地址与第一种情况的结果相同。

printf("%x\n",s.pt_1); //Result: 0x013011a9 
printf("%x\n",*s.pt_1); //Result: 0x013011a9 
printf("%x\n",**s.pt_1); //Result: 0x013011a9 

在第一行pt_1是指向一个功能,并且显示存储在指针的地址。

在第二行,您取消引用指针并访问函数本身。当传递给一个函数时,哪些衰变成指针。

在第三行中,您取消引用指针以获取该函数,然后在与另一个*一起使用该函数时衰减为指针。第二个星号产生的值在传递给函数时会再次衰减为指针。等

1

的问题是,你不能根本做任何一个“函数对象” ...... C++只管理“指针的功能”。

因此,一个函数将隐式衰减为指向函数的指针以供任何用途......无论您放在它前面有多少个*

类似的情况发生在数组中,它们隐含地衰减为指向第一个元素的指针,不同之处在于您可以对数组执行一些操作(例如sizeof),即使这对函数也是禁止的。

鉴于比在C++中没有(便携式)方法在运行时创建新函数,不能操纵函数对象的限制并不重要。您只能处理指向现有函数的指针......