The Clockwise/Spiral Rule(顺时针/螺旋规则)By David Anderson —快速看懂复杂C声明

原文链接在这里
http://c-faq.com/decl/spiral.anderson.html#

下面是我自己翻译的中文(对原文有精简)

方法

  1. 从一个变量名开始,以顺时针螺旋方式阅读它,在遇到以下内容时,用相应的声明替代它,有一些说明英文的逻辑更好理解一些,所以在一些地方会贴上英文
    //makedown语法原因,X被我改成了Z

    • [Z] or [ ]
      => Array Z size of… or Array undefined size of…
      …的数组大小为Z或 …的数组大小还未定义
    • (type1, type2)
      => function passing type1 and type2 returning…
      函数传递type1,type2参数,返回…
    • *
      => pointer(s) to…
      指向…的指针
  2. 保持这个阅读方式直到该变量声明里所有修饰符都被覆盖。

  3. 始终先解决圆括号里的任何内容

例子1 普通声明

                 +-------+
                 | +-+   |
                 | ^ |   |
            char *str[10];
             ^   ^   |   |
             |   +---+   |
             +-----------+

考虑一下,str是什么?

  • 我们使用顺时针螺旋规则从str出发,第一个遇到的符号是 [,这意味着一个数组,所以我们知道str是… 的数组,大小为 10
    str is an array 10 of…
  • 继续阅读,我们遇到了*,这意味着一个指针,所以str是指针的数组,数组里可以存放 10 个指针元素,但不知道指针元素指向什么类型
    str is an array 10 of pointers to…
  • 继续阅读,我们遇到行的末尾 (;) ,因为修饰符还没全部阅读完毕,所以继续阅读来到最后的char类型,所以str是一个内含 10 个指针元素的数组,每个指针元素都指向char类型
    str is an array 10 of pointers to char
  • 我们现在已经看过了所有修饰符,大功告成。

例子2 指向函数的指针声明

                 +--------------------+
                 | +---+              |
                 | |+-+|              |
                 | |^ ||              |
            char *(*fp)( int, float *);
             ^   ^ ^  ||              |
             |   | +--+|              |
             |   +-----+              |
             +------------------------+

fp上使用相同的方法

  • 第一个我们遇见的是) ,因此我们知道fp是在括号里,继续阅读,遇到了*,所以fp是一个指针,不知道指向什么类型.
    fp is a pointer to…
  • 继续阅读,离开了原来的括号,我们遇见了(,这意味着函数(想一想,指针后面紧跟括号,是不是意味着这个指针指向一个函数)。结合括号的内容,我们知道fp是一个指向函数的指针,函数传递了一个int类型的参数和一个指向float类型的指针,但是函数返回什么不清楚。
    fp is a pointer to a function passing an int and a pointer to float returning…
  • 继续阅读,离开了函数括号,我们看到了又一个* ,于是我们知道了函数返回的是一个指针,但是这个指针指向什么类型不清楚。
    fp is a pointer to a function passing an int and a pointer to float returning a pointer to…
  • 继续,我们来到了行的末尾 (;) ,跟例子1一样还没全部阅读完成,所以继续,来到了char类型,现在我们知道了指针指向char类型
  • fp is a pointer to a function passing an int and a pointer to float returning a pointer to a char

例子3 “ 极端 ”声明

                      +-----------------------------+
                      |                  +---+      |
                      |  +---+           |+-+|      |
                      |  ^   |           |^ ||      |
                void (*signal(int, void (*fp)(int)))(int);
                 ^    ^      |      ^    ^  ||      |
                 |    +------+      |    +--+|      |
                 |                  +--------+      |
                 +----------------------------------+

signal是什么?

  • 注意到signal在圆括号里,所以我们先解决这个
  • signal出发,第一个遇见的是(,意味着函数(想一想,变量后面紧跟括号,是不是一个函数),所以我们知道signal是一个函数,传递一个int类型的参数和一个…
    signal is a function passing an int and a…
  • emmm… 我们可以使用相同的规则在fp上,所以,fp是什么?fp也在括号内,继续阅读,我们看到了*,所以fp是一个指针,指向什么类型呢?
    fp is a pointer to…
  • 继续阅读,我们来到了(,我们知道了fp是一个指向函数的指针,传递一个int类型的参数,那函数返回什么呢?
    fp is a pointer to a function passing int returning…
  • 继续阅读,离开了函数括号,我们看到了void,所以函数不返回参数(void)
    fp is a pointer to a function passing int returning nothing (void)
  • 我们现在已经完成了fp,让我们继续完成之前的signal,我们现在知道signal是一个函数,传递一个int类型的参数和一个指向void类型的函数(参数:int)的指针,那signal函数返回什么呢?
    signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning…
  • 我们仍然在圆括号,下一个符号是*, 所以signal函数返回一个指针,指针指向什么?
    signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to…
  • 我们现在已经解决了圆括号内的内容,继续,我们可以看到另一个( ,所以signal返回的指针指向一个函数,这个函数是传递一个int类型的参数,那这个函数返回什么呢?
    signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to a function passing an int returning…
  • 最后我们继续,只剩下一个void,所以signal函数的最终定义是:一个函数,传递一个int类型和一个指向void类型的函数(参数:int)的指针,返回值是一个指向void类型函数(参数:int)的指针
    signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to a function passing an int returning nothing (void)

const and volatile

规则仍然适用于上面这两者

  1.  const char *chptr
    

按照规则阅读,则是 *---->char---->const
即,chptr是一个指向char常量的指针
chptr is a pointer to a char constant

  1.  char * const chptr
    

同理,可得 chptr是一个指向char的常量指针
chptr is a constant pointer to char

  1.  volatile char * const chptr
    

chptr 是一个指向char volatile的常量指针
chptr is a constant pointer to a char volatile_

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值