Let us suppose that the memory address are represented
    internally by the processor using 32 bits (4 bytes). We can then store the
    address of d1 (the number 100) in a different memory location
    occupying 4 bytes because it is a memory address. The following figure
    shows this situation with the memory addresses stored in position 200.

The memory address of any variable in C may be obtained
    using the & operand followed by the a variable name. In the
    previous figure, the expression &d1 returns the value
    100.
The value returned by the & operator
    depends on the position of its operand, and therefore is not under the
    control of the programmer. The memory address stored as a regular data in
    the address 200 is known generically as a “pointer” because its
    value “points to” the location of d1. Another way
    of saying the same is: address 200 contains a pointer to
    d1.
If position 200 contains a pointer to the variable
    d1, the fields of this data structure can be accessed through
    an “indirection”. The data stored in position 200 is taken and
    its value (the number 100) is now interpreted as a memory address. We access
    to that direction and in there we may access to the fields of
    d1. We just accessed to d1 indirectly, or through
    an “indirection”.
The indirection can be applied multiple times in the same
    access in what is known as “multiple indirection”. Following
    with the previous example, we may now store the address of the pointer (that
    is, the value 200) in another memory location, for example, position 300. In
    this position we now have the address of the address of d1. Or
    analogously, in position 300 we have a pointer to a pointer to
    d1. As in the previous case, we may access the fields in
    d1 but this time using a double indirection. It is possible to
    build multiple indirections with an arbitrary number of levels.