The Clockwise/Spiral Rule
原文链接在这里
http://c-faq.com/decl/spiral.anderson.html#
下面是我自己翻译的中文(对原文有精简)
方法
-
从一个变量名开始,以顺时针螺旋方式阅读它,在遇到以下内容时,用相应的声明替代它,有一些说明英文的逻辑更好理解一些,所以在一些地方会贴上英文
//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…
指向…的指针
-
保持这个阅读方式直到该变量声明里所有修饰符都被覆盖。
-
始终先解决圆括号里的任何内容
例子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
规则仍然适用于上面这两者
-
const char *chptr
按照规则阅读,则是 *
---->char
---->const
即,chptr是一个指向char常量的指针
chptr is a pointer to a char constant
-
char * const chptr
同理,可得 chptr是一个指向char的常量指针
chptr is a constant pointer to char
-
volatile char * const chptr
chptr 是一个指向char volatile的常量指针
chptr is a constant pointer to a char volatile_