A programming language is a tool that gives the programmer the power and also the responsibility to do meaningful things. Like with a hammer: it's supposed to drive nails, not to throw through glass windows. ;-)
So, C/C++ pointers are there to point to memory locations. The memory can be regarded as a large contiguous array of bytes, the bytes in that memory are numbered from 0 to the end of the memory. That number is called the address of a byte in memory.
A variable occupies one or more consecutive bytes in memory to store the variable's value. The address of the variable is the address of the first byte of the variable.
When you declare a variable, the compiler adds the machinery to access that memory location of the variable: if you assign a value to the variable, the program determines the memory location of the variable and stores the value to the bytes at that location. Likewise when you read from a variable: the bytes at that memory location are interpreted as the value of that variable (of a given type).
This address machinery is hidden to the programmer. But under certain conditions, you need the address of a variable instead of the value of the variable. In that case, you define an additional variable that can hold the address of another variable. Such a variable is called a
pointer variable. E.g.
int number = 5;
int *pointerToNumber = &number;
The
*
tells that we are not storing an
int
but rather the address to an
int
variable in that variable. To access the address of a variable, you put a
&
before the variable of choice.
Since a pointer variable is also a variable, you can take the address of that variable again, etc.
Use cases in C:
Swapping the value of two variables:
- You must pass the address of the variables.
- If the variable's values were passed directly, you could not exchanged them in memory.
void swap_int(int *a, int *b) { int i = *a; *a = *b; *b = i; }
...
int a = 7;
int b = 13;
...
swap_int(&a, &b);
Setting a pointer variable within a function (e.g. in a "factory" function):
void create_string(char **string, size_t size)
{
*string = (char*)malloc(size);
...
}
...
char *s;
create_string(&s, 1000);
Multidimensional array:
int arrayNx1[N]; int arrayNxM[N][M]; int arrayUxVxW[U][V][W]; etc.
You see here that you have the power to do the things you need (e.g. multi dimensional arrays), but you have the responsibility to handle with care. To initialize such multi dimensional arrays is left as exercise ;-).
Cheers
Andi
PS: Not all variables are stored in memory. A possible optimization is to store variables in CPU registers only. But this is only possible if you do not access the address of the variable explicitly (a CPU register is not located in memory and therefore has no address). This optimization is left to the compiler, though.