How to intuitively come up with an example for an ambiguous grammar and how to make that grammar unambiguous?
The simple way of seeing this class of ambiguities is to observe that if two right-hand sides for the same non-terminal overlap, then they could be applied in either order:

 D ::=     "*" D
    |          D "[" number "]"


The overlap is pretty clear:

 "*" D "[" number "]"


Another example, where a right-hand side can overlap with itself:

E ::= E "+" E


Overlap:

      E "*" E
            E "*" E
      -------------
      E "*" E "*" E


The solution is to remove the overlap by introducing a new non-terminal for one of the overlapping uses. Here's my solution to the ambiguity in your grammar:

Declaration ::= Type D ;
Type ::= "int" | "char"
D ::= "*" D
   E
E ::= E "[" number "]
   |  E "(" Type ")"
   |  "(" D ")"
   |  name


Which productions you decide to shift to the new non-terminal is not arbitrary; it will define which of the competing parses is correct for the language you are designing. There is no universal answer to that question, so it cannot be done algorithmically. 

Note: The clumsy solution you have been provided with is probably because your lesson is being mixed with a discussion of top-down parsing. My grammar, though unambiguous, is not suitable for top-down parsing because it is left-recursive. However, the resulting parse tree reflects the syntactic structure of the declaration.