VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

有编程疑问吗?还请到提问专区发帖提问!
搜索
查看: 630|回复: 4

[求助] 关于函数指针理解方面的几个问题

[复制链接]
36_avatar_middle
在线会员 yq1557 发表于 2018-4-6 11:14:20 | 显示全部楼层 |阅读模式
5驿站币
本帖最后由 yq1557 于 2018-4-6 18:13 编辑

假设有如下三个返回类型均为指针的函数原型:
const double* f1(const double ar[], int n);
const double* f2(const double [], int n);
const double* f3(const double*,int n);
有三个问题:

一、const double* (*p1)(const double*, int n)=f1; 我知道p1是指向函数f1的指针,
      那么, 由于 auto p2 = f2 等价于 const double* (*p2)(const double*, int n)=f;所以p2也是指向f2的指针,对吗?

二、const double*(*pa[3])(const double*, int n)={f1, f2, f3}; 我知道pa是一个指针数组,每一个元素都是一个返回类型为指针的函数,
       那么 auto pb=pa; 其中的pb表示什么意思?为什么auto pb=pa 等价于 const double* (**pb)(const double*, int n)=pa; 麻烦解释一下

三、const double* (*(*pc)[3])(const double*, int n)=&pa 等价于 auto pc=&pa;我知道 pc表示是指向指针数组pa的指针,(*pc)[0]是pa指针数组中的第一个元素所在地址,(*pc)[1]是第二个元素所在地址,(*pc)[2]是第三个元素所在地址,
       那么 (*(*pc)[2])什么意思? (*(*pc)[3])这种表示有意义吗?

指针函数这些表示太复杂了,搞得我晕晕乎乎的,
各位高手,对我这种初学C++的新人来说,关于函数指针这章内容的学习有什么建议吗?

以下是具体代码:
  1. // arfupt.cpp -- an array of function pointers
  2. #include <iostream>
  3. // various notations, same signatures
  4. const double * f1(const double ar[], int n);
  5. const double * f2(const double[], int);
  6. const double * f3(const double *, int);

  7. int main()
  8. {
  9.         using namespace std;
  10.         double av[3] = { 1112.3, 1542.6, 2227.9 };

  11.         // pointer to a function
  12.         const double *(*p1)(const double *, int) = f1;
  13.         auto p2 = f2;  // C++0x automatic type deduction
  14.                                    // pre-C++0x can use the following code instead
  15.                                    // const double *(*p2)(const double *, int) = f2;
  16.         cout << "Using pointers to functions:\n";
  17.         cout << " Address  Value\n";
  18.         cout << (*p1)(av, 3) << ": " << *(*p1)(av, 3) << endl;
  19.         cout << p2(av, 3) << ": " << *p2(av, 3) << endl;

  20.         // pa an array of pointers
  21.         // auto doesn't work with list initialization
  22.         const double *(*pa[3])(const double *, int) = { f1,f2,f3 };
  23.         // but it does work for initializing to a single value
  24.         // pb a pointer to first element of pa
  25.         auto pb = pa;
  26.         // pre-C++0x can use the following code instead
  27.         // const double *(**pb)(const double *, int) = pa;
  28.         cout << "\nUsing an array of pointers to functions:\n";
  29.         cout << " Address  Value\n";
  30.         for (int i = 0; i < 3; i++)
  31.                 cout << pa[i](av, 3) << ": " << *pa[i](av, 3) << endl;
  32.         cout << "\nUsing a pointer to a pointer to a function:\n";
  33.         cout << " Address  Value\n";
  34.         for (int i = 0; i < 3; i++)
  35.                 cout << pb[i](av, 3) << ": " << *pb[i](av, 3) << endl;

  36.         // what about a pointer to an array of function pointers
  37.         cout << "\nUsing pointers to an array of pointers:\n";
  38.         cout << " Address  Value\n";
  39.         // easy way to declare pc
  40.         auto pc = &pa;
  41.         // pre-C++0x can use the following code instead
  42.         // const double *(*(*pc)[3])(const double *, int) = &pa;
  43.         cout << (*pc)[0](av, 3) << ": " << *(*pc)[0](av, 3) << endl;
  44.         // hard way to declare pd
  45.         const double *(*(*pd)[3])(const double *, int) = &pa;
  46.         // store return value in pdb
  47.         const double * pdb = (*pd)[1](av, 3);
  48.         cout << pdb << ": " << *pdb << endl;
  49.         // alternative notation
  50.         cout << (*(*pd)[2])(av, 3) << ": " << *(*(*pd)[2])(av, 3) << endl;
  51.     cin.get();
  52.         return 0;
  53. }

  54. // some rather dull functions

  55. const double * f1(const double * ar, int n)
  56. {
  57.         return ar;
  58. }
  59. const double * f2(const double ar[], int n)
  60. {
  61.         return ar + 1;
  62. }
  63. const double * f3(const double ar[], int n)
  64. {
  65.         return ar + 2;
  66. }
复制代码

最佳答案

查看完整内容

没错,是这么回事!




上一篇:关于创建进程例子的一些问题请求大神
下一篇:程序MFC库引用问题

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

01_avatar_middle
online_admins admin 发表于 2018-4-6 11:14:21 | 显示全部楼层
yq1557 发表于 2018-4-6 22:37
我想明白了,

const double* (*p1)(const double*, int n)=f1,p1是指向函数f1的指针;

没错,是这么回事!

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

01_avatar_middle
online_admins admin 发表于 2018-4-6 16:58:44 | 显示全部楼层
类似这种问题,楼主可以直接写几个简单的函数,之后直接调用下就可以看到各个函数的地址了,之后对比下值就知道对不对了!

第一个问题,楼主可以用如下的代码测试:
  1. #include "stdafx.h"
  2. #include <afx.h>
  3. #include <iostream>
  4. using namespace std;

  5. const double* f1(const double ar[], int n)
  6. {
  7.         cout << "f1f1f1" << endl;
  8.         return NULL;
  9. }
  10. const double* f2(const double[], int n)
  11. {
  12.         cout << "f2f2f2" << endl;
  13.         return NULL;
  14. }
  15. const double* f3(const double*, int n)
  16. {
  17.         cout << "f3f3f3" << endl;
  18.         return NULL;
  19. }

  20. int _tmain(int argc, _TCHAR* argv[])
  21. {
  22.         const double* (*p1)(const double*, int n) = f1;
  23.         auto p2 = f2;

  24.         double arr_d[2] = { 1, 2 };
  25.         (*p2)(arr_d, 2);

  26.         return 0;
  27. }
复制代码


第二个问题:其实不用非得用函数指针来举例子,普通的指针来说明问题也是一样的:
pa[3] 是个指针数组,那么我想把 pa 赋值给其他的一个指针变量应该怎么定义呢?除了用 auto 还能用什么类型?
答案是双*,也就是二级指针,所以 auto pb=pa 等价于 const double* (**pb)(const double*, int n)=pa;

第三个问题:跟问题二类似,实际上就是三级指针了!

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

36_avatar_middle
ico_lz  楼主| yq1557 发表于 2018-4-6 18:11:39 | 显示全部楼层
本帖最后由 yq1557 于 2018-4-6 18:13 编辑
admin 发表于 2018-4-6 16:58
类似这种问题,楼主可以直接写几个简单的函数,之后直接调用下就可以看到各个函数的地址了,之后对比下值就 ...


首先感谢你的解答,但有几个疑惑
一是你所给的代码,为什么我的VS2017编译器提示错误,提示内容为:fatal error C1083: 无法打开包括文件: “stdafx.h”: No such file or directory,即便我将引号改为"<>"也提示错误

二是第二个问题,按你所说,pb是指向pa的指针,即pb是指向指针数组的指针?那不就和第三个问题auto pc=&pa(pc表示是指向指针数组pa的指针)表示的意思一样了吗?

三是第三个问题,(*(*pc)[2])表示的是指针数组pa的第三个元素地址吗?为什么代码中(具体代码详见问题补充里,在第54行)用的是 (*(*pd)[2])(av, 3) 而 (*(*pd)[3])(av, 3)会提示错误?

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

36_avatar_middle
ico_lz  楼主| yq1557 发表于 2018-4-6 22:37:08 | 显示全部楼层
admin 发表于 2018-4-6 16:58
类似这种问题,楼主可以直接写几个简单的函数,之后直接调用下就可以看到各个函数的地址了,之后对比下值就 ...

我想明白了,

const double* (*p1)(const double*, int n)=f1,p1是指向函数f1的指针;

const double*(*pa[3])(const double*, int n)={f1, f2, f3};pa是一个指针数组
const double* (**pb)(const double*, int n)=pa;则pb是指向指针数组的指针

const double* (*(*pc)[3])(const double*, int n)=&pa,则pc指向的是数组指针的指针,既然pc指向数组
指针,则可以像数组指针那样用下标表示个元素地址,所以 (*(*pd)[0])即第一个元素地址, (*(*pd)[2])即
第三个元素地址

对吧

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2018-12-13 08:43

Powered by Discuz! X3.4

© 2009-2018 cctry.com

快速回复 返回顶部 返回列表