C Part I · Module 3 · Expressions and Operators
Assignment and Compound Assignment
You have been writing assignments since Chapter 2.1, where the symbol was introduced as a way of putting a value into an object and then left alone. This chapter is where it is examined properly, and there are two things to establish. The first is that assignment runs right to left — it evaluates the expression on the right and stores the result in the object named on the left — which is why a line like x = x + 1 is an ordinary instruction rather than the impossible equation it resembles. The second is that assignment is itself an expression, producing a value like any other, which is a fact you can demonstrate in one line and which explains a form of C you will certainly encounter. Then the compound forms, which are not quite the shorthand they are usually described as.
Foundation11 min readCPart IFundamentalsExpressions
Part I · Module 3 · Chapter 3.4 · Assignment and Compound Assignment
1. The Symbol That Misleads Everyone
Chapter 3.1 said that most expressions only produce a value, and that a few also change something. Assignment is the one you have already been using:
count = 9;The trouble is the symbol. In mathematics = states that two things are equal — a claim about the world, which is either true or false. In C it does no such thing. It is an instruction, and it runs in a direction the symbol does not suggest.
2. Right to Left
Here is what count = 9; actually does, in order:
With that order in mind, the line that troubles every beginner stops being troubling:
int x = 5;
x = x + 1;As an equation that is false — no number equals itself plus one. As an instruction it is entirely ordinary:
- Evaluate
x + 1.xcurrently holds 5, so this produces 6. - Store 6 in the object named
x.
The left-hand side is not a claim. It names where the value goes.
3. Assignment Is an Expression
Chapter 3.1 defined an expression as something that produces a value, and said that some expressions also have a side effect. Assignment is exactly that: its side effect is changing the object, and its value is the value that was stored.
That is a claim you can test in one line:
#include <stdio.h>
int main(void)
{
int a = 0;
int b = 0;
printf("the value of (a = 5) is %d\n", a = 5);
printf("a now holds %d\n", a);
b = a = 7;
printf("a is %d, b is %d\n", a, b);
return 0;
}Output:
the value of (a = 5) is 5
a now holds 5
a is 7, b is 7The first line settles it. a = 5 was handed to printf as a value to print, and it printed 5 — so the assignment produced a value, exactly like 4 + 1 would have. It also stored 5 in a, which the second line confirms.
The third statement, b = a = 7, follows from that. Assignments group from the right, so this is b = (a = 7): the inner assignment stores 7 in a and produces 7, and the outer assignment stores that 7 in b. Chapter 3.10 covers grouping rules properly; here the one fact you need is that the right-hand assignment happens first.
A practical note: writing an assignment inside a larger expression is legal and is usually worth avoiding. The form exists, you will read it in other people's code, and b = a = 7; is clear enough — but an assignment buried in the middle of a complicated expression makes a line do two jobs at once, and Chapter 3.11 shows why that is a worse idea in C than it looks.
4. Compound Assignment
Adding to an object is common enough that C provides a shorter form:
#include <stdio.h>
int main(void)
{
int total = 10;
total += 5; printf("after += 5 : %d\n", total);
total -= 3; printf("after -= 3 : %d\n", total);
total *= 2; printf("after *= 2 : %d\n", total);
total /= 4; printf("after /= 4 : %d\n", total);
total %= 4; printf("after %%= 4 : %d\n", total);
return 0;
}Output:
after += 5 : 15
after -= 3 : 12
after *= 2 : 24
after /= 4 : 6
after %= 4 : 2Read total += 5 as add 5 to what total holds, and store the result back in total. There is one for each arithmetic operator, including /= and %=, which behave exactly as Chapter 3.3 described — 24 /= 4 gives 6, and 6 %= 4 gives 2.
Like plain assignment, a compound assignment is an expression: it has the same side effect and produces the stored value.
5. Not Quite Shorthand
You will very often see x += y described as shorthand for x = x + y. For the values in §4 the two do give the same answer, and at this stage you can reason about them that way. But they are not the same construct, and two differences are worth knowing now so that you are not surprised later.
The left-hand side is evaluated once. In x = x + y, whatever names the object appears twice; in x += y it appears once and is worked out once. With a plain variable that makes no difference. With a more elaborate way of naming an object — the kind you will meet from Module 6 onward — evaluating it twice can do real work twice, and that is a genuine bug source.
The conversion behaviour is not identical. Chapter 3.2 said the type of an arithmetic result comes from the operands, and Chapter 3.12 is about what happens when the operands' types differ. Compound assignment has its own rule for that case, and it is not simply the expanded form's rule. While every operand in this module is the same type, you will not notice; the point is that "identical to" is an overstatement, and remembering that it is will save you an argument later.
6. A Realistic Use
Accumulating a running total is the shape you will write more than almost any other:
#include <stdio.h>
int main(void)
{
int bytes_sent = 0;
bytes_sent += 128;
bytes_sent += 256;
bytes_sent += 64;
printf("bytes sent: %d\n", bytes_sent);
return 0;
}Output:
bytes sent: 448Three statements, each reading the object, computing a new value and storing it back. Written out longhand as bytes_sent = bytes_sent + 128; it would mean the same thing and name the object twice on every line.
This is also the point at which Chapter 2.6's warning becomes practical rather than theoretical. A running total accumulates, and accumulating is how a value reaches the edge of its type's range. If bytes_sent were counting something large, the question of whether an int can hold the answer stops being academic — and if it were unsigned, subtracting more than it holds would not give you a negative.
7. What You Should Be Able to Say Now
=is not equality. It is an instruction, and C has a different operator for asking whether values are equal.- Assignment runs right to left: evaluate the right-hand side, store the result in the object named on the left.
- That is why
x = x + 1is ordinary rather than impossible. - The left-hand side must name somewhere a value can be put.
5 = x;is not valid C. - Assignment is an expression. It produces the value that was stored, which
printf("%d", a = 5)demonstrates directly. - Assignments group from the right, so
b = a = 7stores 7 inafirst and then inb. - Compound forms —
+=,-=,*=,/=,%=— change an object by a given amount and are expressions too. x += yis not literally identical tox = x + y: the left side is evaluated once, and the conversion rules differ.- Prefer the compound form. Avoid burying assignments inside larger expressions.
8. Exercise
Exercise 1 — trace it. Write down what x holds after each line:
int x = 4;
x = x + 3;
x = x * 2;
x -= 4;
x /= 5;Exercise 2 — predict, then run. Give the exact output:
#include <stdio.h>
int main(void)
{
int p = 1;
int q = 2;
printf("%d\n", q = p + 5);
printf("%d %d\n", p, q);
return 0;
}Exercise 3 — explain the direction. A beginner says x = x + 1; cannot be right because nothing equals itself plus one. Using §2, explain in two sentences what they have misread.
Exercise 4 — say why it fails. Why is 5 = x; not valid C? Answer in terms of what the left-hand side of an assignment has to be.
Exercise 5 — unpack the chain. For c = b = a = 3; where all three are int, say what each object holds afterwards and the order in which the three stores happen.
Exercise 6 — correct the claim. A colleague writes in a review: "total += x is just a textual shorthand for total = total + x, so they are interchangeable." Give the two differences from §5 and say which one could actually change a program's behaviour.
9. Summary
=is an instruction, not a claim. It stores; it does not assert equality.- It runs right to left — evaluate the right-hand side, then store into the object on the left. That direction is what makes
x = x + 1sensible. - The left side must name a place a value can go.
- Assignment is an expression with a side effect and a value, which
printf("%d", a = 5)proves in one line. - Assignments group from the right, so
b = a = 7works the way it does. - Compound assignment changes an object by an amount and reads better than the longhand.
- It is not merely shorthand: the left operand is evaluated once, and the conversion rules are its own.
You can now change an object deliberately. What you still cannot do is ask a question about a value — whether one is larger than another, or whether two are the same. That is the next chapter, and it introduces the operator most easily confused with the one you have just learned.
Standards & specifications
- Governing standard
- ISO/IEC 9899 (the C language standard)(opens ISO/IEC (JTC 1/SC 22/WG 14) in a new tab)
Defines the C language itself — the type system, expression semantics, object model, storage duration and the behaviour categories a conforming implementation must honour. It is a FAMILY of editions (C89/C90, C99, C11, C17, C23) and this curriculum names the edition wherever a claim depends on one. It does not define any foreign-function interface to a hardware description language, and it does not define platform behaviour: what a memory-mapped access does on real silicon is the implementation's and the device's contract, not this standard's. Working drafts published by WG14 are freely available and are what most engineers read day to day; a draft is not the published standard.
This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.
Where this fits
Part of the C Programming curriculum.
