zoukankan      html  css  js  c++  java
  • 指针复杂声明

    转载自: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;
    }
    说了这么多,不理解的好好体会一下,反正别晕就行!呵呵
    有问题,欢迎指教!! 

  • 相关阅读:
    函数的返回值以及局部,全局变量
    函数的参数
    文件操作 函数
    数据类型一些基本操作方法
    设置精度的方法
    字符串和编码问题
    python中一些函数应用
    初步认识类
    P1613 跑路
    P2383 狗哥玩木棒
  • 原文地址:https://www.cnblogs.com/batteryhp/p/5020443.html
Copyright © 2011-2022 走看看