Chapter 4 — Operators
Arithmetic, comparison, logical, and bitwise operators — the verbs of C. Precedence rules matter more than you think.
What you'll learn
- 1Use arithmetic operators correctly, especially integer division and modulo.
- 2Distinguish pre- and post-increment.
- 3Combine boolean conditions with `&&`, `||`, `!`.
- 4Apply explicit type casts.
Core Concepts
1) Arithmetic
7 / 2 // → 3 (integer division!)
7 % 2 // → 1
7.0 / 2 // → 3.5 (promoted to double)| Operator | Meaning |
|---|---|
| `+ - * /` | usual arithmetic |
| `%` | remainder (integers only) |
2) Comparison and logical
| Operator | Meaning | ||
|---|---|---|---|
| `== !=` | equal / not equal | ||
| `< <= > >=` | comparisons | ||
| `&& | ` | logical and / or (short-circuit) | |
| `!` | logical not |
`a == b` is the comparison; `a = b` is assignment — one of C's classic typo bugs.
3) Increment / decrement
int x = 5;
int y = x++; // y=5, x=6 (post: use then increment)
int z = ++x; // x=7, z=7 (pre: increment then use)4) Compound assignment
x += 3; // same as x = x + 3
x *= 2; // same as x = x * 25) Type cast
int a = 7, b = 2;
double r = (double)a / b; // 3.5Without the cast both operands are `int` and integer division kicks in.
6) Precedence cheat sheet (highest → lowest, simplified)
unary (! ++ --) > * / % > + - > < <= > >= > == != > && > || > = += -=When unsure, **add parentheses**. Clearer code beats clever code.
Examples
Example 1 — `ex01_arith.c`: integer vs floating-point division
printf("%d\n", 7 / 2);
printf("%d\n", 7 % 2);
printf("%f\n", 7.0 / 2);**Output**
3
1
3.500000Key: int / int truncates; promote at least one side to float/double.
Example 2 — `ex02_increment.c`: pre vs post
int x = 5;
printf("%d\n", x++); // prints 5 then becomes 6
printf("%d\n", x); // 6
printf("%d\n", ++x); // becomes 7, prints 7**Output**
5
6
7Key: never combine multiple `++` on the same variable in one expression — undefined behavior.
Example 3 — `ex03_logical.c`: short-circuit evaluation
int a = 0, b = 5;
if (a != 0 && b / a > 1) { // safe: a != 0 false, second never runs
printf("never\n");
} else {
printf("avoided divide-by-zero\n");
}**Output**
avoided divide-by-zeroKey: `&&` stops at the first false; use that to guard dangerous ops.
Example 4 — `ex04_cast.c`: explicit cast
int a = 7, b = 2;
printf("int div = %d\n", a / b);
printf("float div = %.2f\n", (double)a / b);**Output**
int div = 3
float div = 3.50Key: cast **before** the division, not after.
Common mistakes
- **`=` vs `==`** — `if (x = 0)` always assigns and is false; turn on `-Wall`.
- **Integer division surprise** — `1/2 == 0`.
- **Operator precedence** — `a & b == c` parses as `a & (b == c)`. Parenthesize.
- **Double increment in one expression** — `i = i++ + ++i;` is undefined.
Recap
- `/` and `%` on ints truncate; cast to get float behavior.
- `&&` and `||` short-circuit — leverage that.
- When in doubt, add parentheses.
Try it
cd src
gcc -std=c11 -Wall -o ex01 ex01_arith.c && ./ex01
gcc -std=c11 -Wall -o ex02 ex02_increment.c && ./ex02
gcc -std=c11 -Wall -o ex03 ex03_logical.c && ./ex03
gcc -std=c11 -Wall -o ex04 ex04_cast.c && ./ex04💻 Examples
Compilable, runnable examples — see the output yourself.
#include <stdio.h>
int main(void) {
int a = 17, b = 5;
printf("a = %d, b = %d\n", a, b);
printf("a + b = %d\n", a + b);
printf("a - b = %d\n", a - b);
printf("a * b = %d\n", a * b);
printf("a / b = %d ( )\n", a / b);
printf("a %% b = %d ()\n", a % b);
printf("a / (double)b = %.3f\n", a / (double)b);
return 0;
}
3
1
3.500000#include <stdio.h>
int main(void) {
int a = 5;
int b;
b = a++; // : a
printf(": a=%d, b=%d\n", a, b); // a=6, b=5
a = 5;
b = ++a; // : a
printf(": a=%d, b=%d\n", a, b); // a=6, b=6
a += 10; // a = a + 10
printf("a += 10 -> %d\n", a);
a *= 2;
printf("a *= 2 -> %d\n", a);
return 0;
}
5
6
7#include <stdio.h>
int main(void) {
int a = 10, b = 20;
printf("a == b : %d\n", a == b);
printf("a != b : %d\n", a != b);
printf("a < b : %d\n", a < b);
printf("a >= b : %d\n", a >= b);
int age = 25;
int has_license = 1;
printf("Adult : %d\n", (age >= 18) && has_license);
printf(" : %d\n", (age < 18) || !has_license);
return 0;
}
avoided divide-by-zero#include <stdio.h>
int main(void) {
int total = 95, count = 4;
double avg_wrong = total / count;
double avg_right = (double)total / count;
printf(" ( ): %.3f\n", avg_wrong); // 23.000
printf(" (): %.3f\n", avg_right); // 23.750
double pi = 3.99;
int trunc = (int)pi;
printf("(int)3.99 = %d ( )\n", trunc);
return 0;
}
int div = 3
float div = 3.50📝 Exercises
Try them yourself first, then open the solution to compare.
Problem 1 (hw01.c)
Goal: Read two ints and print sum, diff, product, and division (as double).
- Filename: hw01.c
▶Toggle solution
#include <stdio.h>
int main(void) {
int a, b;
printf("Two ints: ");
scanf("%d %d", &a, &b);
printf("sum: %d\n", a + b);
printf("diff: %d\n", a - b);
printf("prod: %d\n", a * b);
if (b != 0) {
printf("quot: %d\n", a / b);
printf("rem: %d\n", a % b);
printf("float div: %.2f\n", (double)a / b);
} else {
printf("Cannot divide by zero.\n");
}
return 0;
}
Problem 2 (hw02.c)
Goal: Read one int and print whether it's even or odd.
- Filename: hw02.c
▶Toggle solution
#include <stdio.h>
int main(void) {
int n;
printf("Enter int: ");
scanf("%d", &n);
int even = (n % 2 == 0);
int positive = (n > 0);
int negative = (n < 0);
printf("even=%d, pos=%d, neg=%d\n", even, positive, negative);
return 0;
}
Problem 3 (hw03.c)
Goal: Read one int and print its absolute value (without `abs()`).
- Filename: hw03.c
▶Toggle solution
#include <stdio.h>
int main(void) {
double f;
printf("Fahrenheit: ");
scanf("%lf", &f);
double c = (f - 32) * 5.0 / 9.0;
printf("Celsius: %.2f\n", c);
return 0;
}
All lecture materials and example code are openly available on GitHub.
View on GitHub ↗