The second innovation that most clearly distinguishes C from its
  predecessors is this fuller type structure and especially its
  expression in the syntax of declarations... given an object of any
  type, it should be possible to describe a new object that gathers
  several into an array, yields it from a function, or is a pointer to
  it.... [This] led to a
  declaration syntax for names mirroring that of the expression syntax
  in which the names typically appear. Thus,
int i, *pi, **ppi; declare an integer, a pointer to an integer, a
  pointer to a pointer to an integer. The syntax of these declarations
  reflects the observation that i, *pi, and **ppi all yield an int type
  when used in an expression. 
Similarly, int f(), *f(), (*f)(); declare
  a function returning an integer, a function returning a pointer to an
  integer, a pointer to a function returning an integer. int *api[10],
  (*pai)[10]; declare an array of pointers to integers, and a pointer to
  an array of integers.
In all these cases the declaration of a
  variable resembles its usage in an expression whose type is the one
  named at the head of the declaration.
An accident of syntax contributed to the perceived complexity of the
  language. The indirection operator, spelled * in C, is syntactically a
  unary prefix operator, just as in BCPL and B. This works well in
  simple expressions, but in more complex cases, parentheses are
  required to direct the parsing. For example, to distinguish
  indirection through the value returned by a function from calling a
  function designated by a pointer, one writes *fp() and (*pf)()
  respectively. The style used in expressions carries through to
  declarations, so the names might be declared
int *fp(); int (*pf)(); 
In more ornate but still realistic cases,
  things become worse: int *(*pfp)(); is a pointer to a function
  returning a pointer to an integer.
There are two effects occurring.
  Most important, C has a relatively rich set of ways of describing
  types (compared, say, with Pascal). Declarations in languages as
  expressive as C—Algol 68, for example—describe objects equally hard to
  understand, simply because the objects themselves are complex. A
  second effect owes to details of the syntax. Declarations in C must be
  read in an `inside-out' style that many find difficult to grasp. 
  Sethi [Sethi 81] observed that many of the nested
  declarations and expressions would become simpler if the indirection
  operator had been taken as a postfix operator instead of prefix, but
  by then it was too late to change.