Grouping & types Ready
main.c

                

Ready

Statements run 0 Lines printed 0
Ready

Keyboard: ← → step · Space play / pause · R reset · Esc exit classroom mode

How it works

The ideas behind the lab

Exactly what you watched happen, in plain steps.

C adds invisible parentheses

Precedence says which operator binds tighter: * before +. Associativity says what happens between operators of the SAME level: most go left to right, but unary operators, ?: and assignments go right to left. Together they decide how C groups an expression — before anything is calculated.

a + b * c        →  a + (b * c)          * binds tighter
a - b - c        →  (a - b) - c          left to right
a = b = c        →  a = (b = c)          right to left
!a == b          →  (!a) == b            unary first
a & b == c       →  a & (b == c)         == before & !
x > 0 && y > 0   →  (x > 0) && (y > 0)
The C precedence table (1 binds tightest)
Level Operators Kind Associativity
1 () [] -> . x++ x-- call, index, member, postfix left to right
2 ++x --x + - ! ~ (type) * & sizeof unary right to left
3 * / % multiplicative left to right
4 + - additive left to right
5 << >> shift left to right
6 < <= > >= relational left to right
7 == != equality left to right
8 & bitwise AND left to right
9 ^ bitwise XOR left to right
10 | bitwise OR left to right
11 && logical AND left to right
12 || logical OR left to right
13 ?: conditional right to left
14 = += -= *= /= %= &= ^= |= <<= >>= assignment right to left
15 , comma left to right

Precedence and associativity

  1. Unary operators bind tightest, then * / %, then + −, then shifts, comparisons, bitwise, logical, ?:, assignment, comma.
  2. Operators of the same level group left to right (a − b − c is (a − b) − c)…
  3. …except unary operators, ?: and assignments, which group right to left (a = b = c is a = (b = c)).
  4. Precedence decides GROUPING, not the order of calculation — only &&, ||, ?: and , fix that order.
  5. Parentheses always win. Use them whenever the reader might hesitate.

Implicit conversions

  1. Integer promotion: char and short are converted to int before any arithmetic.
  2. Mixed types: the smaller type is converted to the bigger one (int → long → float → double).
  3. Assignment converts the value to the type of the variable: it can lose decimals or high bits.
  4. int mixed with unsigned int becomes unsigned: -1 < 1u is false!
  5. Widening is safe; narrowing can lose data — gcc -Wall -Wconversion warns.

Casts and special operators

  1. A cast (type) value converts on purpose: (double) sum / n gives a real division.
  2. The cast binds tightly: (double) (a / b) converts the already-cut int result.
  3. sizeof gives a size in bytes (size_t, %zu); its operand is NOT evaluated.
  4. cond ? x : y evaluates the condition, then only ONE of x and y.
  5. The comma operator evaluates left to right and keeps the last value.
Walkthrough

Grouping and conversions in one program

Every line, explained.

1 #include <stdio.h>
2
3 int main(void)
4 {
5 int a = 10, b = 3;
6 int r1 = a + b * 2; * first: 10 + 6 = 16.
7 int r2 = (a + b) * 2; Parentheses first: 13 * 2 = 26.
8 int r3 = a - b - 2; Left to right: (10 − 3) − 2 = 5.
9 int x, y;
10 x = y = 4; Right to left: y = 4 first, and its value (4) is stored in x.
11 double avg = (double) (a + b) / 2; The cast converts 13 to 13.0, so the division is real: 6.5.
12 int big = a > b ? a : b; The conditional operator picks the larger: 10.
13 printf("%d %d %d %d %d %.1f %d\n", r1, r2, r3, x, y, avg, big); Prints 16 26 5 4 4 6.5 10
14 return 0;
15 }
Common mistakes

Spot the bug

Mistakes almost every beginner makes — and how to fix them.

Bitwise & with ==

✗ Wrong
if (flags & 4 == 4)
✓ Right
if ((flags & 4) == 4)

== (level 7) binds tighter than & (level 8), so the first means flags & (4 == 4), which is flags & 1.

Shift with +

✗ Wrong
int r = 1 << n + 1;   // 1 << (n + 1)
✓ Right
int r = (1 << n) + 1;

+ binds tighter than <<. Put parentheses around the shift if you mean "shift, then add".

A cast that comes too late

✗ Wrong
double avg = (double) (sum / n);
✓ Right
double avg = (double) sum / n;

In the first, sum / n is int division and has already lost the decimals before the cast.

Comparing signed and unsigned

✗ Wrong
int i = -1;
if (i < sizeof(int))   // false!
✓ Right
int i = -1;
if (i < (int) sizeof(int))

sizeof gives an unsigned value, so i is converted to unsigned: -1 becomes 4294967295. gcc -Wextra warns about signed/unsigned comparisons.

Expecting precedence to set the order of side effects

✗ Wrong
int r = i++ + i++;
✓ Right
int r = i + (i + 1);
i += 2;

Precedence only groups. Changing i twice in one expression is undefined behaviour — the compiler may do it in any order.

Practice

Check your understanding

Answer each question — you will see the explanation straight away.

0 / 5 correct
Question 1

How does C group a + b * c - d ?

Question 2

What is 20 / 4 / 5 ?

Question 3

After int a, b; a = b = 7; what are a and b?

Question 4

What is the value of (double) 7 / 2 ?

Question 5

What is sizeof(3 + 2.5) on a typical computer?

Assessment

Precedence, Associativity & Conversions quiz

Test yourself: 10 questions, 70% to pass. Create a free account to take the quiz, save your progress and work towards the certificate.