指针复杂声明

来源:互联网 发布:黎巴嫩真主党 知乎 编辑:程序博客网 时间:2024/05/21 19:22

转载自:http://blog.csdn.net/tiantangniao232/article/details/1851003


在前两篇文章都理解的基础上,本篇文章将教你如何去理解指针的复杂声明。

首先先介绍一下 左右法则:其实就是------向右看,向左看
首先找到变量名,然后向右看,遇到括号改变阅读方向,重复这个过程,直到解析完整个表达式。
看到上面的法则,如果没有接触过这个法则,可能会不知所云。
下面就通过一些具体的例子来教你如何理解复杂的指针声明:
第一个:
int  (*p)[3];
1-----首先找到变量名 p ,从变量名向右看是括号,依据法则改变解析方向,向左看,有一个 * 说明 p是一个指针,至此我们知道 p 是一个指针,至于是什么样的指针需要更进一步的解析。
2-----解析完括号向右看 是一个 [3],是一个具有3个整型元素数组,所以 p 就是一个指向这个数组的指针,学名数组指针。
第二个:
int (*func)(int *p);
1-----首先找到变量名 func,从变量名向右看是括号,依据法则改变解析方向,向左看,有一个* 说明 func是一个指针,至此我们知道 func是一个指针,至于是一个什么样的指针需要更进一步解析。
2-----解析完括号向右看,发现 func是一个函数指针,参数类型是 int * ,返回值是 int
第三个:
int (*func)(int *p, int (*f)(int*));
1-----首先找到变量名func,从变量名向右看是括号,依据法则改变解析方向,向左看,有一个 * 说明func是一个指针,至此我们知道func是一个指针,至于是什么样的指针需要更进一步的解析。
2-----解析完括号向右看,发现func是一个函数指针,参数的类型是 int * 和 另外一个函数指针,返回值是int
第四个:
int (*func[5])(int *p);
1------首先找到变量名 func,从变量名向右看是一个[5],是一个具有5个元素的数组,至此我们知道,func是一个数组,至于是一个什么样的数组,取决于更进一步的解析。
2-----解析完[ 5 ]继续向右看,是括号,依据法则改变解析方向,向左看,是一个 * 说明,数组func中的元素是指针。继续向左,是括号,跳出括号,改变解析方向,向右看,发现数组中的元素指针是一个函数指针,参数类型是 int * ,返回值是 int
总结:func就是一个指针数组,这个数组中元素是5个函数指针。
第五个:
int (*(*func)[5])(int *p);
1-----首先找到变量名func,从变量名向右看是括号,依据法则改变解析方向,向左看,是一个 * ,说明 func是一个指针,至此我们知道func是一个指针,至于是什么样的指针,需要更进一步的解析。
2-----解析完 * 继续向左看,是括号,依据法则改变解析方向,向右看,是一个[5],是一个拥有5个元素的数组,说明func是一个指向这个数组的指针。
3-----解析完[5 ]继续向右解析,是括号,依据法则改变解析方向,向左看,是一个 * 说明这个数组中的元素是指针。
4-----解析完 * 继续向左看,是括号,依据法则改变解析方向,向右看,发现这个这个指针是一个函数指针。
总结:func是一个指向数组的指针,这个数组的元素也是一个指针,这个指针的类型就是函数指针。
第六个:
int (*(*func)(int *p))[5];
1-----首先找到变量名func,从变量名向右看是括号,依据法则改变解析方向,向左看,是一个 * 说明 func是一个指针,至此我们知道func是一个指针,至于是什么样的指针,需要更进一步的解析。
2-----解析完 * 继续向左看,是括号,依据法则改变解析方向向右看,发现func是一个函数指针,至此,下面的就不用再解析了,剩下的就是这个函数指针的返回值类型。疑惑?不相信?去掉这个函数指针已解析的部分:
(*func)(int *p),剩下:int (*)[5],说明这个函数指针的返回类型是 int (*)[5]  。没看过这种返回类型吧!!
下面就来验证一下,我只要能按照我的理由,成功声明一个对应的函数,就说明我说的是对的。
但是如果我直接声明这样一个函数肯定不行,因为系统中没有这个返回类型:
 int (*)[5]    Funx( int *p);
怎么办呢?用 typedef 啊!!
typedef  int (*FRet)[5];//类型定义
FRet  Funx(int *p) //函数声明定义
{
      cout<<"Funx"<<endl;
      return 0;
}
 int (*(*func)(int *p))[5];//函数指针声明

int   main ( )
{
 func = Funx;
func( 0 );
  return 0;
}
运行:输出: Funx
成功!
第七个:
int (*(*(*func)(int *))[5])(int *);
看到这个没晕吧!坚持住!一句话就可以解决它。还记得上一题的解题技巧吗??
一 眼就看出:(*func)(int *)是一个函数指针,解析到这里下面的就不用再解析了,剩下的就是这个函数指针的返回值类型。简单吧!具体说一下:去掉 (*func) (int *) 表达式剩下的就是:int (*(*)[5])(int *),它就是返回值类型!返回值类型其实就是 上面第五个表达式的类型。
这个你自己可以验证一下:
typedef  int (*(*FRet)[5])(int *);
FRet Funx(int *)
{
   cout<<"Funx"<<endl;
   return 0;
}
说了这么多,不理解的好好体会一下,反正别晕就行!呵呵
有问题,欢迎指教!! 
0 0
原创粉丝点击