*p = *q looks like it does something to the pointers — but the stars mean both sides are dereferenced, so it copies a value from one variable to another. This question from our C Programming Quiz App is a precision test: do you know the difference between assigning pointers and assigning through pointers?
The Quiz Question
int a = 5, b = 10;
int *p = &a, *q = &b;
*p = *q;
printf("%d %d", a, b);
What is printed by this code?
- 5 10
- 10 10
- 10 5
- 5 5
The Correct Answer: 10 10
Read *p = *q from the right: *q reads the value at the address in q — that’s b, so 10. *p on the left is the destination: the object at the address in p, which is a. So the statement is exactly a = b; spelled through pointers. a becomes 10, b never changes. Verified on gcc 13.3 and Apple clang 21:
$ gcc -Wall -Wextra copy.c && ./a.out 10 10
Why Each Wrong Answer Is Wrong
Why not “5 10”?
“5 10” would mean nothing happened to either variable — which is what you get from pointer assignment instead of pointee assignment. We ran that variant too:
int a = 5, b = 10;
int *p = &a, *q = &b;
p = q; /* no stars: repoints p at b */
printf("%d %d %d", a, b, *p);
5 10 10
p = q copies the address, so p now points at b — but a and b themselves are untouched. One character pair (*) is the whole difference between “repoint the arrow” and “overwrite the target”.
Why not “10 5”?
That’s a swap — and *p = *q is only half of one. A real pointer swap needs a temporary:
int tmp = *p; /* save a's 5 */
*p = *q; /* a = 10 */
*q = tmp; /* b = saved 5 */
Without the first and third lines, a‘s original 5 is simply overwritten and lost. This three-step dance is exactly how swap functions work in C.
Why not “5 5”?
“5 5” is the assignment run backwards — *q = *p would copy a‘s 5 into b. Assignment in C always moves the right-hand value into the left-hand object, never the reverse.
Why This Matters: Pass by Value
This mechanism is why C functions take pointer parameters when they need to modify the caller’s variables. C passes arguments by value — a plain int parameter is a copy, and changing the copy changes nothing outside. Passing &a hands the function the address, and *param = ... inside writes straight to the caller’s a. That is the entire trick behind scanf("%d", &n), output parameters, and swap functions. Note also that *p = *q is a one-time copy — it does not link the variables; changing b afterwards leaves a at 10.
For the basics of the dereference operator itself, start with our pointer dereference question.
Frequently Asked Questions
What is the difference between p = q and *p = *q?
p = q copies the address: both pointers now point at the same object, and no int changes. *p = *q copies the pointed-to value: the object p points at is overwritten with the value of the object q points at.
Does *p = *q keep a and b linked afterwards?
No. It’s a one-time copy of the value at that instant. Assigning to b later has no effect on a; they remain separate objects at separate addresses.
How do you swap two variables using pointers?
Use a temporary: tmp = *p; *p = *q; *q = tmp;. Wrapped in a function taking int *, int *, this swaps the caller’s variables — the standard C idiom, since C has no pass-by-reference.
Related Reading
- Pointers in C – Complete Guide
- C Program to Swap Two Variables
- Function Argument Evaluation Order in C
- 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 #41 in the C Programming Quiz App — 155 questions with explanations covering operators, pointers, memory, and more.
Download on Google Play →