复杂指针判别

本文介绍了C语言中用于解析复杂声明的右左法则,并通过具体示例详细解释了如何使用该法则来理解指针、数组及函数指针等类型的声明。

  右左法则是一个既著名又常用的方法。不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的。

  右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。
  笔者要对这个法则进行一个小小的修正,应该是从未定义的标识符开始阅读,而不是从括号读起,之所以是未定义的标识符,是因为一个声明里面可能有多个标识符,但未定义的标识符只会有一个。

  要理解比较复杂的指针类型声明,在描述一个指针时就要注意语言比较简明。下面是我的一些规则。

  描述一个数组时:int a[5]  a是一个且有5个元素的数组它的元素是int型变量

  描述一个函数指针时:int (*p)(int i) p是一个函数指针,这类函数且有int型返回值,且有一个int型参数

  int (*func)(int *p);
  。从func看起,向左到括号,向右为*,结果:func为一个指针
  。跳出括号,向右看,又是一个括号。结果:func为一个指针函数
       。向左为int 结果:func为一个函数指针,这类函数且有一个int*型参数,且有一个int型返回值。

  int (*func)(int *p, int (*f)(int*));
  。从func看起,向左到括号,向右为*,结果:func为一个指针
  。跳出括号,向右看,又是一个括号。结果:func为一个指针函数
       。向左为int 结果:func为一个函数指针,这类函数且有一个int (*f)(int*)参数,且有一个int型返回值。
  。第二个参数较复杂,单独来看,可以发现与上面的例子一样。

  int (*func[5])(int *p);
  。从func看起,向左为[5],结果:func为一个且有5个元素的数组。
  。向右为*,结果:数组的元素为指针
  。跳出括号,向右看,又是一个括号。结果:数组的元素是一个指针数组
       。向左为int 结果:func是一个且有5个元素的数组,数组的元素为一个函数指针,这类函数且有int型返回值,且有一个int*型参数。
  说明:因为第一次向右看即为数组,说明func是数组,这里已经固定func的类型,下面再说即是对数组元素的描述

  int (*(*func)[5])(int *p);
  。从func看起,向左到括号,向右为*,结果:func为一个指针
  。跳出括号,向右看,是一个[5],说明func是一个数组指针,指向一个且有5个元素的数组。
  。向左看,是一个*,说明数组的元素是指针。
  。跳出括号,向右看,是一个括号,说明数组的元素是函数指针
       。向左为int 结果:func为一个指向且有5个元素的数组的指针,数组的元素是一个函数指针,这类函数且有int型返回值,且有一个int*型参 数
  说明:这里从指针跳到数组元素,再从数组元素跳到函数指针,一层层的说明。更容易理清条理

  int (*(*func)(int *p))[5];
  。从func看起,向右为括号,向左为*,说明func是一个指针
  。跳出括号向右为一个括号,说明func是一个函数指针,这类函数且有int*型参数
  。向左为一个*,说明这类函数返回指为一个指针
  。向右为[5],说明这类函数返回值为数组指针
  。向左为一个int,说明数组且有5个int型元素
  。func是一个函数指针,这类函数且有一个int*型参数。返回值为数组指针,数组里有5个int型元素

  说明:当确定为数组后,马上进入数组元素的分析
     当确定为函数指针后,马上进入对函数的分析,函数类型、函数返回值
     当确定为数组指针后,马上进入它所指向数组的分析

  实际应用中这样声明复杂的类型大大影响程序的可读性。应该分解,比如:

  int (*(*func)(int *p))[5];
  可以分解为:
  typedef int (*PARA)[5];
       PARA (*func)(int *p);

 
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值