【问题标题】:Pointer to function pointer in C++C++中指向函数指针的指针
【发布时间】:2016-01-24 09:24:30
【问题描述】:

我写了一些代码来了解函数指针是如何工作的。 我在一些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() 指向的地址在哪里?它在内存中的什么位置?

【问题讨论】:

  • 1,见this。 2. operator() 调用该函数,因此您正在使用它返回的指针。
  • 通过%x 打印函数指针会调用未定义的行为,因为地址可能不适合int。使用printf("%p\n",(void*)s.pt_1);
  • 我在这里找到了第二个问题的答案Where in memory are return values stored in memory?

标签: c++ memory function-pointers


【解决方案1】:

与使用数组名类似,使用函数名,稍有挑衅就会衰减为指针。

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是一个指向函数的指针,显示指针中存储的地址。

在第二行,您取消引用指针并访问函数本身。当传递给函数时,它会衰减为指针。

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

【讨论】:

    【解决方案2】:

    问题是你基本上不能用“函数对象”做任何事情...... C++ 只管理“指向函数的指针”。

    因此,函数将隐式衰减为指向该函数的指针以供任何使用...无论您在其前面放多少 * 都没关系。

    数组也会发生类似的情况,它们隐式衰减为指向第一个元素的指针,不同之处在于您可以对数组进行一些操作(例如sizeof),而函数则禁止这样做。

    鉴于在 C++ 中没有(可移植的)方法在运行时创建新函数,因此无法操作函数对象的限制并不重要。无论如何,您只能处理指向现有函数的指针...

    【讨论】:

      猜你喜欢
      • 2018-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多