c 声明 && right-left rule

int f; //一个整型变量
        int *f; //一个指向整型的指针
        不过,请看第 2 个声明是如何工作的:它把表达式 *f 声明为一个整数。根据这个事实,你肯定能推断出 f 是个指向整型的指针。C 声明的这种解释方法可以通过下面的声明得到验证。
        int* f,g;
        它并没有声明两个指针。尽管它们之间存在空白,但星号是作用于 f 的,只有 f 是一个指针。 g 只是一个普通的整型变量。
   
        下面的例子,你曾见过:
        int f();
        它把 f 声明为一个函数,它的返回值是一个整数。旧式风格的声明对函数的参数不提供任何信息。它只声明了 f 的返回类型。现在我将使用这种旧式风格,这样例子看上去简单一些,后面我将再回到完整的原型形式。

        下面是一个例子:
        int *f();     // f 是一个函数,它返回一个指向 int 类型的指针
        要想推断出它的含义,必须确定表达式 *f() 是如何进行求值的。首先执行的是函数调用操作符(), 因为它的优先级高于间接访问操作符。
   
        接下来的一个声明更为有趣:
        int (*f)();     // f 是一个指向函数的指针,该函数返回一个 int 类型的对象
        确定括号的含义是分析这个声明的一个重要步骤。第 2 对儿括号是函数调用操作符,但第 1 对儿括号只是起到聚组的作用。它迫使间接访问在函数调用之前进行,使 f 成为一个函数指针,它所指向的函数返回一个整型值。
   
        “函数指针”? 是的,程序中每个函数都位于内存中的某个位置,所以存在指向那个位置的指针是完全可能的。
   
        现在下面的这个声明应该是比较容易懂了:
        int *(*f)();
        它和前一个声明基本相同, f 也是一个函数指针,它所指向的函数返回一个指向 int 类型的指针。必须对其进行间接访问操作才能得到一个整型值。
   
        现在让我们把数组也考虑进去。
        int f[];
        这个声明表示 f 是个整型数组,数组的长度暂时忽略,因为我们现在关心的是它的类型,而不是它的长度
             【注】如果它们的链接属性是external或者是作用函数的参数,即使它们声明时未注明长度,也仍然是合法的。
   
        下面的声明又如何呢?
        int *f[];
        这个声明又出现了两个操作符。下标的优先级更高,所以 f 是一个数组,它的元素类型是指向整型的指针
   
        下面的这个例子隐藏着一个圈套。不管怎样,让我们先推断它的含义。
        int f()[];
        f 是一个函数,返回一个整型数组。这里的圈套在于这个声明是非法的————函数只能返回标量值,不能返回数组。
   
        还有一个例子,颇费思量:
        int f[]();
        现在 f 似乎是一个数组,它的元素是返回值为整型的函数。但是,这个声明也是非法的,因为数组元素必须具有相同的长度,但不同的函数显然可能具有不同的长度。

        但是,下面的这个声明是合法的:
        int (*f[])();
        你必须找到所以的操作符,然后按照正确的次序执行它们。括号内的表达式 *f 首先进行求值,所以 f 是一个元素为某种类型的指针的数组。 表达式 () 是函数调用操作符,所以 f 肯定是一个数组,数组元素的类型是函数指针,它所指向的函数返回整型值。

        如果你弄明白了上面最后一个声明,下面这个应该是比较容易的了:
        int *(*f[])();
        它和上面那个声明的唯一区别就是多了一个间接访问操作符,所以这个声明创建了一个指针数组,指针指向返回整型指针的函数。

 

http://www.cdecl.org/

在线 解释 c 声明, 很好很强大

int *(*(*f)(int * ))[]

declare f as pointer to function (pointer to int) returning pointer to array of pointer to int

这个没问题

 

int *(*(*f)(int *, char *(*(*))() ) ) []

declare f as pointer to function (pointer to int, pointer to pointer to function returning pointer to char) returning pointer to array of pointer to int

这个也没问题,是不是很强大

 

最后来一段规则:

C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法。不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的,两者可以说是相反的。右左法则的英文原文是这样说的:

        The   right-left   rule:   Start   reading   the   declaration   from   the   innermost   parentheses,   go   right,   and   then   go   left.   When   you   encounter  parentheses,   the   direction   should   be   reversed.   Once   everything   in   the   parentheses   has   been   parsed,   jump   out  of   it.   Continue   till   the   whole   declaration   has  been   parsed.

 

关于 right-left rule 的 ref

http://www.codeproject.com/Articles/7042/How-to-interpret-complex-C-C-declarations

http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html

自行 google

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值