The purpose of a pointer is to save the address of a specific variable. Then the memory structure of following code should look like:
int a = 5;
int *b = &a;
The C language is strongly typed. This means that, for every address, there is a type, which tells the compiler how to interpret the value at that address.
In your example:
int a = 5;
int *b = &a;
The type of a
is int
, and the type of b
is int *
(read as "pointer to int
"). Using your example, the memory would contain:
..... memory address ...... value ........ type
a ... 0x00000002 .......... 5 ............ int
b ... 0x00000010 .......... 0x00000002 ... int*
The type is not actually stored in memory, it's just that the compiler knows that, when you read a
you'll find an int
, and when you read b
you'll find the address of a place where you can find an int
.
In your second example:
int a = 5;
int *b = &a;
int **c = &b;
The type of c
is int **
, read as "pointer to pointer to int
". It means that, for the compiler:
c
is a pointer;c
, you get the address of another pointer;int
.That is,
c
is a pointer (int **
);*c
is also a pointer (int *
);**c
is an int
.And the memory would contain:
..... memory address ...... value ........ type
a ... 0x00000002 .......... 5 ............ int
b ... 0x00000010 .......... 0x00000002 ... int*
c ... 0x00000020 .......... 0x00000010 ... int**
Since the "type" is not stored together with the value, and a pointer can point to any memory address, the way the compiler knows the type of the value at an address is basically by taking the pointer's type, and removing the rightmost *
.
By the way, that's for a common 32-bit architecture. For most 64-bit architectures, you'll have:
..... memory address .............. value ................ type
a ... 0x0000000000000002 .......... 5 .................... int
b ... 0x0000000000000010 .......... 0x0000000000000002 ... int*
c ... 0x0000000000000020 .......... 0x0000000000000010 ... int**
Addresses are now 8 bytes each, while an int
is still only 4 bytes. Since the compiler knows the type of each variable, it can easily deal with this difference, and read 8 bytes for a pointer and 4 bytes for the int
.