Pointers are abstractions of memory addresses with additional type semantics, and in a language like C type matters.
First of all, there's no guarantee that int *
and int **
have the same size or representation (on modern desktop architectures they do, but you can't rely on it being universally true).
Secondly, the type matters for pointer arithmetic. Given a pointer p
of type T *
, the expression p + 1
yields the address of the next object of type T
. So, assume the following declarations:
char *cp = 0x1000;
short *sp = 0x1000; // assume 16-bit short
int *ip = 0x1000; // assume 32-bit int
long *lp = 0x1000; // assume 64-bit long
The expression
cp + 1
gives us the address of the next char
object, which would be 0x1001
. The expression sp + 1
gives us the address of the next short
object, which would be 0x1002
. ip + 1
gives us 0x1004
, and lp + 1
gives us 0x1008
. So, given
int a = 5;
int *b = &a;
int **c = &b;
b + 1
gives us the address of the next int
, and c + 1
gives us the address of the next pointer to int
. Pointer-to-pointers are required if you want a function to write to a parameter of pointer type. Take the following code:
void foo( T *p ) *p = new_value(); // write new value to whatever p points to
void bar( void )
T val; foo( &val ); // update contents of val
This is true for any type
T
. If we replace T
with a pointer type P *
, the code becomesvoid foo( P **p ) *p = new_value(); // write new value to whatever p points to
void bar( void )
P *val; foo( &val ); // update contents of val
The semantics are exactly the same, it's just the types that are different; the formal parameter
p
is always one more level of indirection than the variable val
.
Post a Comment