C++中的函数指针指针

7

我写了一些代码来了解函数指针的工作原理。我在一些IDE上运行了以下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
    1. s.pt_1() 的地址指向哪里?它在内存中的位置在哪里?

3
  1. 查看此链接,了解函数指针的解引用原理。
  2. operator() 调用函数,因此你正在使用它返回的指针。
- LogicStuff
1
使用%x打印函数指针会导致未定义的行为,因为地址可能不适合于int。请使用printf("%p\n",(void*)s.pt_1); - phuclv
我在这里找到了第二个问题的答案:返回值存储在内存中的哪里? - Ngo Thanh Nhan
2个回答

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++中没有(可移植的)方法来在运行时创建新函数,不能操作函数对象的限制并不重要。无论如何,您只能处理指向现有函数的指针...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接