There is a technique known as the ``Clockwise/Spiral Rule'' which enables any C programmer to parse in their head any C declaration!
There are three simple steps to follow:
+-------+
| +-+ |
| ^ | |
char *str[10];
^ ^ | |
| +---+ |
+-----------+
Question we ask ourselves: What is str?
``str is an...
``str is an array 10 of...
``str is an array 10 of pointers to...
``str is an array 10 of pointers to char''
+--------------------+
| +---+ |
| |+-+| |
| |^ || |
char *(*fp)( int, float *);
^ ^ ^ || |
| | +--+| |
| +-----+ |
+------------------------+
Question we ask ourselves: What is fp?
``fp is a...
``fp is a pointer to...
``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...
``fp is a pointer to a function passing an int and a pointer to float returning a pointer to a char''
+-----------------------------+
| +---+ |
| +---+ |+-+| |
| ^ | |^ || |
void (*signal(int, void (*fp)(int)))(int);
^ ^ | ^ ^ || |
| +------+ | +--+| |
| +--------+ |
+----------------------------------+
Question we ask ourselves: What is `signal'?
Notice that signal is inside parenthesis, so we must resolve this first!
``signal is a function passing an int and a...
fp is a pointer to...
``fp is a pointer to a function passing int returning...''
``fp is a pointer to a function passing int returning nothing (void)''
``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning...
``signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to...
``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...
``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)''
The same rule is applied for const and volatile. For Example:
const char *chptr;
``chptr is a pointer to a char constant''
How about this one:
char * const chptr;
``chptr is a constant pointer to char''
Finally:
volatile char * const chptr;
``chptr is a constant pointer to a char volatile.''
Practice this rule with the examples found in K&R II on page 122.
This article may be freely distributed as long as the author's name and this notice are retained.