*p = *q in C – Copying a Value Through Pointers, Explained

*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?

  1. 5 10
  2. 10 10
  3. 10 5
  4. 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

Recommended Books

This question is #41 in the C Programming Quiz App — 155 questions with explanations covering operators, pointers, memory, and more.
Download on Google Play →

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>