What does *p print when p holds the address of a variable? This is the first thing to get straight about pointers, and it’s exactly what this question from our C Programming Quiz App tests. The dereference operator * follows the pointer to its target and reads the value stored there — not the address, not garbage, and it’s not a compile error.
The Quiz Question
int a = 10;
int *p = &a;
printf("%d", *p);
What is printed by this code?
- 10
- Address of a
- Garbage value
- Compile error
The Correct Answer: 10
&a takes the address of a, and that address is stored in the pointer p. Dereferencing with *p means “go to the address stored in p and read the value there” — which is the 10 sitting in a. Compiled with gcc -Wall -Wextra (gcc 13.3) and clang -Wall (Apple clang 21), both print:
$ gcc -Wall -Wextra deref.c && ./a.out 10
& and * are inverse operations: & goes from a variable to its address, * goes from an address back to the variable. So *&a is just a, and here *p is *&a.
Why Each Wrong Answer Is Wrong
Why not “Address of a”?
The address is what p holds without the star. To print it you would pass the pointer itself, with the %p conversion:
printf("%p", (void *)p); /* prints something like 0x7ffe8233658c */
On our test run this printed 0x7ffe8233658c — a stack address that changes from run to run. The star is precisely what converts “the address” into “the value at that address”.
Why not “Garbage value”?
Garbage is what you risk when a pointer is uninitialized. Here p is initialized to &a on the same line it is declared, so it points at a perfectly valid, live object. Contrast with:
int *p; /* uninitialized: holds an indeterminate address */
printf("%d", *p); /* undefined behavior — may print garbage or crash */
That version is undefined behavior, and gcc flags it with -Wuninitialized (as -Wall includes it in most cases). Our quiz code has no such problem.
Why not “Compile error”?
Every type lines up: a is an int, &a is an int *, p is declared int *, and *p is an int matching the %d format. Both gcc and clang compile it with zero warnings under -Wall -Wextra.
Reading Pointer Declarations
The declaration int *p is best read right to left: “p is a pointer to int”. A useful mental model is that the declaration mirrors the use: *p is an int, therefore p is a pointer to one. Once p = &a, the two names describe the same memory:
a: [ 10 ] ← the int object, at address 0x...658c p: [0x...658c] ← the pointer object, holding a's address *p ───────────→ follows the address, reads 10
Assigning through the pointer works the same way in reverse: *p = 25; writes 25 into a. That’s the mechanism behind functions like scanf("%d", &n) and swap-by-pointer — the callee can modify the caller’s variable because it was handed the address, not a copy. See our *p = *q value-copy question for the follow-up quiz on writing through pointers.
Frequently Asked Questions
What does *p mean in C?
In an expression, *p dereferences the pointer p: it evaluates to the object p points to. In a declaration like int *p, the star instead says that p is a pointer. Same symbol, two roles.
How do I print the address stored in a pointer?
Use printf("%p", (void *)p). The cast to void * is what the standard specifies for %p, and it keeps -Wformat quiet on both gcc and clang.
What happens if I dereference an uninitialized pointer?
Undefined behavior. The pointer holds an indeterminate bit pattern; reading through it may print garbage, crash with a segmentation fault, or appear to work. Always initialize pointers — to a real address or to NULL.
Related Reading
- Pointers in C – Complete Guide
- C Program to Swap Two Variables
- Returning a Pointer to a Local Variable – Why It Fails
- C Aptitude Questions and Answers
Recommended Books
- The C Programming Language – Kernighan & Ritchie (India) | Amazon.com
- C Programming: A Modern Approach – K.N. King (India) | Amazon.com
This question is #13 in the C Programming Quiz App — 155 questions with explanations covering operators, pointers, memory, and more.
Download on Google Play →