A pointer is a variable that holds a memory address that is the location of another variable in memory.
The variable that holds the memory address is said to point to the variable stored at that address.
Pointers are one of the most powerful, and also the trickiest, features of the C programming language. They are especially important in passing arguments to functions by reference, as well as constructing dynamic data structures.
Pointers depend on two operators, the & operator and the * operator. The & operator is a unary operator that returns the memory address of the object to the right of it. To print the memory address returned to us from the & operator we use the %p conversion character.
int x = 0;
double y = 8086.1976;
printf("int x has the value %d and is stored at %p\n", x, &x);
printf("double y has the value %f and is stored at %p\n", y, &y);
The second pointer operator is *, which is a unary operator that returns the value of the variable located at the address that follows it. Perversely, this same symbol must also be placed in front of the variable name with declaring a pointer variable.
a = 1138;
b = &a;
printf("a = %d\n", a);
printf("b = %p\n", b);
printf("&a = %p\n", &a);
printf("*b = %d\n", *b);
The type of data that a pointer points to is called the base type of the pointer. It is the base type that determines what sort of variable the pointer can point to.
int i = 187;
char j = 's';
double k = 8184.14;
int *x = &i;
char *y = &j;
double *z = &k;
printf("x = %p and *x = %d\n", x, *x);
printf("y = %p and *y = %d\n", y, *y);
printf("z = %p and *z = %d\n", z, *z);
We can use a pointer on the right-hand side of an assignment statement to assign its value to another pointer.
int x = 404;
int *pointer1, *pointer2;
pointer1 = &x;
pointer2 = pointer1;
printf("Address stored at pointer1 = %p\n", pointer1);
printf("Address stored at pointer2 = %p\n", pointer2);
printf("Value pointed to by pointer1 = %d\n", *pointer1);
printf("Value pointed to by pointer2 = %d\n", *pointer2);
Remember, all pointer operations are done according to the pointer’s base type. So, when we declare a pointer, we must make sure that its type is compatible with the variable to which we want to point. It is, however, possible to convert one type of pointer into another type of pointer using an explicit cast. The results, it should be noted, are often undesirable.
double trouble = 909.68;
pointer = (int *) &trouble;
printf("The value of trouble is %f\n", trouble);
printf("The value of *pointer is %d\n", *pointer);