Pointers have two uses. The first is to store a memory address (see Section 5.4). The second is to use the stored memory address to access that points using an indirection (see Section 5.2).
An indirection in C is denoted by the operand *
    followed by the name of a pointer variable. Its meaning is “access the
    content the pointer points to”. Unfortunately, this operator is the
    same as the one to denote pointer data types when declaring pointer
    variables. It is very important to have a clear distinction between these
    two uses of the operator. When translating a program, the compiler does not
    check neither that the memory address contained in a pointer is correct, nor
    that the pointed data is correct. This feature makes the design of programs
    using pointer a complex task.
The following program shows the use of the indirection operator (file pointer_example_2.c):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19  | #include <stdio.h>
int main(int argc, char** argv) 
{
    int num1, num2;
    int *ptr1, *ptr2;
    ptr1 = &num1;
    ptr2 = &num2;
    num1 = 10;
    num2 = 20;
    *ptr1 = 30;
    *ptr2 = 40;
    *ptr2 = *ptr1;
    return 0;
}
 | 
Line 13 assigns the value 30 to the memory location stored
    in ptr1 through an indirection. The pointer has the address of
    num1, thus it is equivalent to assign the value 30 directly to
    num1. Analogously, line 14 assigns the value 40 to the address
    pointed by ptr2. This assignment is equivalent to assign the
    value 40 to num2. Line 16 contains two indirections. The right
    hand side of the assignment obtains the data from the memory address stored
    in ptr1 (the address of num1), and this data is
    assigned to the memory address stored in ptr2 (the address of
    num2). Upon program termination, variable num2
    contains the value 30 although it has not been directly assigned.
The following figure shows the evolution of these four variables throughout the program execution. Again, the memory addresses where they are stored are arbitrary.

The coincidence between the indirection operator and the
    definition of the pointer type “*” may pose a
    difficulty when understanding code. For example, the following line
int *r = *p;
contains two “*” operands. The
    first defines the type “pointer to integer” and is followed by
    a declaration of variable “r”. The second is an
    indirection and is applied to the address stored in pointer
    “p”.
Let us suppose that a data structure with name
      “struct s” has been defined. Applying the rule
      to define the pointer types, a pointer to this structure has type
      “struct s *”. In the following code fragment a
      structure is defined and declared, and a pointer is then declared
      containing its address.
1 2 3 4 5 6 7 8 9 10  | struct s 
{
    int x;
    char c;
}
struct s element;
struct s *pointer;
pointer = &element; | 
An indirection with pointer is used only to
      access the structure fields. This operation require two operators, the
      indirection (operator “*”) and the access to the
      structure fields (operator “.”). The syntax is
      then:
(*pointer).x = 10; (*pointer).c = 'l';
These two operations in C are grouped by the operator
      “->” that is placed between the pointer and
      the name of the field structure. The equivalent notation is then:
pointer->x = 10; pointer->c = 'l';
The operator “->” is always
      written next to a pointer pointing to a structure, and precedes the name
      of one of the fields of that structure. The following program shows the
      use of this operator to copy the content from one structure to
      another.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  | /* Definition of the structure */
struct coordinates 
{
    float x;
    float y;
    float z;
};
int main() 
{
    /* Declaring two structures */
    struct coordinates location1, location2;
    /* Declaring two pointers */
    struct coordinates *ptr1, *ptr2;
    /* Assigning the addresses to the pointers */
    ptr1 = &location1;
    ptr2 = &location2;
    /* Assigning values to the first structure */
    ptr1->x = 3.5;
    ptr1->y = 5.5;
    ptr1->z = 10.5;
    /* Copy the values to the second structure */
    ptr2->x = ptr1->x;
    ptr2->y = ptr1->y;
    ptr2->z = ptr1->z;
  
    return 0;
} | 
Copy and paste the content of the previous program in a
	text file in your development environment. Compile and execute. Define a
	second structure and include a pointer to it as a field in the
	“coordinate” structure. Write code to
	manipulate this new structure.