I don't see where the spiral comes in. The following rule is simpler:
(1) Begin at the variable name, read from left to right, then go back to the name and read from right to left.
(2) Give precedence to expressions in parentheses.
For example:
char (fp)( int, float * )
The innermost expression is (* fp). Nothing to the right of the fp. so read to the left: "* ", it's a pointer. Next, we go right and see an arguments list, so it's a pointer to a function taking these arguments. Go back to where we started and read right to left: Pointer to a function taking (int,float *) that returns a pointer to char.
(1) Begin at the variable name, read from left to right, then go back to the name and read from right to left.
(2) Give precedence to expressions in parentheses.
For example: char (fp)( int, float * )
The innermost expression is (* fp). Nothing to the right of the fp. so read to the left: "* ", it's a pointer. Next, we go right and see an arguments list, so it's a pointer to a function taking these arguments. Go back to where we started and read right to left: Pointer to a function taking (int,float *) that returns a pointer to char.