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.