Question bank — Pointers — declaration, dereferencing ( - ), address-of (&)
Reminders you may lean on (all built in the parent note):
&x= the address (house number) ofx.*p= the value living at the address stored inp(and it can be written to).- In a declaration
int *p;, the*is part of the type; in an expression*p, the*is the operator. *(&x)is justx— the two operators undo each other.
True or false — justify
* and & are inverse operations, so &(*p) also gives back p.
p to its target with *, then asking that target's address with &, returns the same address p held. The round trip works in both directions when p points at valid memory.int *p; immediately makes p point at a valid integer you can dereference.
p = &x;) is undefined behaviour.The * in int *p = &x; and the * in y = *p; mean the same thing.
* is part of the type ("p is a pointer to int"); the second is the dereference operator that fetches the value. Same symbol, two grammars.All pointer variables on a given machine have the same size.
sizeof(p) for int *p equals sizeof(int).
sizeof(p) is the size of the pointer itself (e.g. 8 bytes), not the 4-byte int it points to. To get the target's size use sizeof(*p).Passing swap(m, n) by value can still swap m and n in the caller.
swap shuffles private copies and the caller's originals never change. You must pass &m, &n so the function can reach the real houses.*p = 99; changes p to point somewhere new.
p; it goes to the address inside p and writes 99 at the target. To change where p points you assign p = &something; (no *).int *p, q; declares two pointers.
p is a pointer; q is a plain int, because * binds to the individual declarator, not the whole line. Write int *p, *q; for two pointers.A NULL pointer points to a valid memory location whose value happens to be 0.
NULL is a sentinel meaning "points to nowhere". Dereferencing it reads address 0, which is illegal and typically crashes; the pointer is 0, not the target's value.Spot the error
int *p;
*p = 10;::: p was never given an address, so it holds garbage — writing through it corrupts random memory or crashes. Fix: int x; int *p = &x; *p = 10;.
int x = 5;
int *p = x;::: You stored the value 5 into a pointer, not an address; the compiler warns and p now "points" at address 5. Fix: int *p = &x; — take the address with &.
int a = 3, b = 4;
swap(a, b); // void swap(int *x, int *y)::: swap expects addresses but received values, so this is a type error (and even if it compiled, it couldn't reach the originals). Fix: swap(&a, &b);.
int *p = NULL;
printf("%d", *p);::: Dereferencing NULL reads address 0 — an illegal access that segfaults. Guard it: if (p != NULL) printf("%d", *p);.
printf("%p", &x);::: %p expects a void *; passing a bare int * is technically undefined and may warn. Fix: printf("%p", (void*)&x);.
int a[3] = {10,20,30};
int *p = &a[0];
printf("%d", *p + 1);::: This computes (*p) + 1 = 11, not the next element. To read a[1]=20 you need *(p + 1) — parentheses matter because * binds tighter than +.
Why questions
Why does C need pointers at all, when we could just return new values?
Why does p + 1 skip sizeof(int) bytes instead of 1 byte for an int *?
p+1 lands on the next whole int.Why must a pointer carry a type and not just an address number?
Why is reading a declaration as "*p gives an int" the correct mental model for int *p;?
*p, you get an int, which is exactly why p must be a pointer-to-int.Why does *(&x) always equal x?
&x produces x's address, then * follows that address straight back to the same house — the operations cancel, leaving x itself.Why do we cast to (void*) when printing an address with %p?
%p's contract is a generic void *; casting makes the type match, avoiding undefined behaviour and compiler warnings on mismatched pointer types.Edge cases
What happens if you dereference an uninitialised (not NULL) pointer?
*p reads or writes random memory — sometimes a silent wrong value, sometimes a crash. This is worse than NULL because it may not fail loudly.Is *p = t; where p is int * and t is int valid?
*p names the int at the target, so assigning an int value into it is exactly right; this is how you write through a pointer.Can two different pointers hold the same address, and what does that mean?
*p = 5; is instantly visible through the other pointer. They are aliases for the same variable.What is the value and behaviour of & applied to a literal, e.g. &42?
42 is a value, not a variable with a home, so it has no address. & only works on things that occupy memory (variables, array elements).After int *p = &x;, does changing x directly (x = 8;) affect what *p reads?
p still points at x's house, so *p now reads 8. The pointer sees the target's current contents, not a snapshot.If a function returns the address of its local variable, is the returned pointer safe to use?
Connections
- Pass by Reference vs Pass by Value — the swap and "why pointers exist" traps live here.
- Pointer Arithmetic — the
p + 1step-size and*(p+1)precedence traps. - Arrays in C —
&a[0]and array-name decay. - NULL and Segmentation Faults — the NULL/uninitialised dereference dangers.
- Dynamic Memory malloc free — dangling pointers and returning local addresses.
- Strings as char pointers —
char *extends the same rules.