Linux | c&cpp | Email | github | QQ群:425043908 关注本站

itarticle.cc

您现在的位置是:网站首页 -> 代码相关 文章内容

C/C++中复杂的指针的理解方法-itarticl.cc-IT技术类文章记录&分享

发布时间: 7年前代码相关 129人已围观返回

C/C++中的指针是令所有 C/C++ programmer 都望而生畏的东西,有很多难点。

有这样两个复杂的指针定义:

char* const* (*ss[23][200])(void (*)(int h, void (*)(void)))

void *(*(*fp1)(int))[10];


一种理解方法:层级分析

void *(*(*fp1)(int))[10];

(1) 从外层看:void* (*(*fp1)(int)) [10]; 这个等价于: void* A [10]; 所以整个声明就是一个10个元素的数组,这个数组的每个元素是一个指向 void 的指针(或者说成:每个元素是一个 void*);

(2) 再往里看: (* (*fp1)(int) ) ==-gt- * (*fp1) (int) 这就是一个函数指针,所指向函数需要一个int型的参数,并且返回值是一个指针;下一步就是确定返回值指针的类型了;

(3) 结合(1),就知道,fp1返回值指针指向的就是(1)里所声明的那个类型。

所以,整理一下语言,就是: fp1 是一个函数指针,指向的函数有一个int型参数,并返回一个指针;返回的这个指针指向的是一个含有10个元素的数组,这个数组的每个元素是一个void*.

现在看一下那个比较BT的例子:

char* const* (*ss[23][200])(void (*)(int h, void (*)(void)));

(1) 最外层: char* const * (*ss[23][200]) ( void (*) ( int h, void (*)(void) ) ); 这个相当于:T * (A) (B); 也就是一个函数指针,所指向的函数的参数是B,返回值是T的指针;

(2) 一个一个来看,先看T,char* const 是 char型的指针常量;

(3) 再看A:(* ss[23][200] ) (B),这个相当于: (* F ) (B),也就是一个函数指针;

(3.1) A的里面 ss[23][200] 是一个二维数组声明,这个数组的类型是什么呢?结合(3)就知道了:这个数组的每个元素就是(3)中分析得到的——函数指针;整理一下就是:ss[23][200]的每个元素都是一个函数指针;

(4) 再看B: ( void (*) ( int h, void(*)(void) ) ) 这个又是一个函数指针,相当于: void (*F) (P); 它指向的函数参数是P,返回值是void;

(4.1) B这个函数指针指向的函数需要2个参数:第一个参数是int型,第二个参数是:void (*)(void),即:第二个参数又是一个函数指针(这个指针很好分析,就不写了);

(5) 结合(3)和(4)就知道 (*ss[23][200]) (B) 这个数组函数指针所指向的函数的参数也是一个函数指针;

(6) 又结合 (2) 知道(5)的函数指针返回值类型。

所以,整理一下,得到:ss是一个23X200的二维数组,每个元素是一个函数指针(a);它 指向的函数的返回值是一个指针,这个返回值指针的类型是char型的指针常量;函数(a)的参数只有一个,是一个函数指针(b);(b)指向的函数返回值 是void型,参数有两个,第一个是 int 型变量,第二个又是一个函数指针(c),(c)的返回值是void,参数也是void。


另外一种理解方法:

void (*funcPtr) ();

funcPtr是一个函数指针,它所指向的函数无参无返回值。

*funcPtr一定要用括号括起来,否则“void *funcPtr();”会被编译器看做是一个函数声明,返回值为void *。

有时候函数指针可能被定义的很复杂,以至于很难看清其具体类型。想要准确分析出一个复杂的函数指针定义,最好的办法是从“变量名”开始,以“先右后左”的方式向外扩展分析。

float (*(*fp)(int, int, float)) (int);

首先fp右边什么也没有,左边是*,且*fp以括号括起来,所以fp是一个函数指针。再向右看“(int, int, float)”,所以fp指向的函数有三个参数,类型分别是int、int、float。再向左看,左边是*,此时可以把(*fp)(int, int, float)提出来,剩下float (*) (int);,也就是fp指向的函数返回值,仍然是一个函数指针,这个函数指针指向的函数有一个int类型的参数,返回值类型为float。

void * (*(*fp1)(int))[10];

fp1是一个函数指针,所指向的函数有一个int类型的参数。此时可以把(*fp1)(int)提出来,剩下void * (*)[10];,可以看出fp1所指向的函数的返回值是一个指针,此指针指向一个含有10个void指针的数组(void * [10])。

int (*(*f2())[10]) ();

f2右边是(),所以f2不是一个函数指针,它只是一个普通的函数声明。函数f2无参,返回值是一个指针(int (*(*)[10]) ();),该指针指向含有10个函数指针的数组(int (* [10]) ();)。数组中的这些函数指针,所指向的函数无参,返回值类型为int。

可以使用typedef定义函数指针类型,以缩短复杂的函数指针定义。

typedef double (*(*(*fp3)())[10])();

fp3 a;

fp3是一个函数指针类型,该类型的函数指针所指向的函数无参,并返回一个指针(double (*(*)[10])()),该指针指向含有10个函数指针的数组(double (* [10])()),数组中的这些函数指针所指向的函数无参,返回值类型为double。a是函数指针类型fp3的一个变量,它是fp3类型的函数指针。

在实际使用中,通常不会遇到如此复杂的函数指针定义。

发布时间: 7年前代码相关129人已围观返回回到顶端

很赞哦! (1)

上一篇:C++ 模板小结

下一篇:解密内存屏障

文章评论

  • 请先说点什么
    热门评论
    128人参与,0条评论

站点信息

  • 建站时间:2016-04-01
  • 文章统计:728条
  • 文章评论:82条
  • QQ群二维码:扫描二维码,互相交流