Pointers#
C provides a special data type known as a pointer for storing memory addresses. There are two types of pointers depending on how the memory at the stored address should be treated:
- A pointer to a variable stores the memory address of a variables.
- A pointer to a function or a function pointer stores the memory address of a function (since the code of functions is stored in memory as well).
Declaring a pointer to variable is done in the following way:
data-type *pointer;
Declaring a function pointer is done in the following way:
return-type (*pointer)(param-type-1, param-type-2, ...);
You can optionally give names to the parameters as well:
return-type (*pointer)(param-type-1 param1, param-type-2 param2, ...);
Example: Pointer to Function
The following is a declaration of a pointer ptr to a function returns an int and takes two parameters - a double and a pointer to float:
int (*ptr)(double, float*);
int (*ptr)(double doubleParam, float *floatPointerParam);
The following is a declaration of a pointer ptr to a function which returns nothing and takes one parameter which is another function pointer to a functions which returns an int and takes no parameters:
void (*ptr)(int (*)());
void (*ptr)(int (*func)());
Address-Of Operator#
We can assign a value to a pointer as we would do with any other variable:
int *ptrToInt = 0x66f1;
double (*ptrToFunc)(int) = 0x900010;
However, this is not very useful because we are rarely aware of the underlying memory layout. Instead, we can use the address-of operator (&) to obtain the address of another object in memory:
int var = 4;
int *pointerToVar = &var; // pointerToVar holds the memory address of var
double func(int p)
{
return (double) (p / 2);
}
// ...
double (*ptrToFunc)(int) = &func; // ptrToFunc holds the memory address of func
For function pointers, the address-of operator can also be omitted:
double (*ptrToFunc)(int) = func;
Dereferencing#
Pointers are useful because they allow us to access variables indirectly. If we have a pointer data-type *pointer, we can access the memory at the stored address and treat it as data-type by using the dereference operator (*).
int var = 1;
int *pointerToVar = &var; // pointerToVar is now equal to the address of var
*pointerToVar = 2; // var is now equal to 2
*pointerToVar += 4; // var is now equal to 6
int anotherVar = *ip; // anotherVar is now equal to var, which is six