Operators

Operators combine values: arithmetic, comparison, logic and assignment. C's operators are compact and powerful — several were copied by almost every language since — but a few, like increment and integer division, need care.

Arithmetic

C
#include <stdio.h>

int main(void) {
    int a = 17, b = 5;
    printf("%d + %d = %d\n", a, b, a + b);
    printf("%d - %d = %d\n", a, b, a - b);
    printf("%d * %d = %d\n", a, b, a * b);
    printf("%d / %d = %d\n", a, b, a / b);
    printf("%d %% %d = %d\n", a, b, a % b);
    printf("-17 / 5 = %d, -17 %% 5 = %d\n", -17 / 5, -17 % 5);
    return 0;
}
Output
17 + 5 = 22
17 - 5 = 12
17 * 5 = 85
17 / 5 = 3
17 % 5 = 2
-17 / 5 = -3, -17 % 5 = -2

Integer division truncates toward zero, and % (remainder) takes the sign of the left operand. % only works on integers; use fmod for floating point. Dividing an integer by zero is undefined behaviour — always check the divisor.

Assignment operators

C
#include <stdio.h>

int main(void) {
    int score = 10;
    score += 5;   // score = score + 5
    score *= 2;   // score = score * 2
    score -= 4;   // score = score - 4
    score /= 2;   // score = score / 2
    score %= 7;   // score = score % 7
    printf("%d\n", score);
    return 0;
}
Output
6

Increment and decrement

++ adds one and -- subtracts one. Prefix (++x) changes the variable and gives the new value; postfix (x++) gives the old value, then changes it:

C
#include <stdio.h>

int main(void) {
    int x = 5;
    int a = x++;   // a = 5, then x = 6
    int b = ++x;   // x = 7, then b = 7
    printf("a=%d b=%d x=%d\n", a, b, x);
    return 0;
}
Output
a=5 b=7 x=7

Use them as stand-alone statements (count++;) and the difference doesn't matter. Never change the same variable twice in one expression, as in i = i++ or printf("%d %d", i++, i++) — that's undefined behaviour.

Comparison

Comparisons produce 1 (true) or 0 (false), as an int:

C
#include <stdio.h>

int main(void) {
    int age = 20;
    printf("%d %d %d\n", age == 20, age != 20, age >= 18);
    printf("%d %d\n", age < 13, age > 65);
    return 0;
}
Output
1 0 1
0 0

== compares; a single = assigns. Mixing them up is a classic bug that the compiler warns about (lesson 4).

Logical operators

OperatorTrue when
a && bboth are true
a || bat least one is true
!aa is false

In C, zero is false and any other value is true. && and || short-circuit: they stop as soon as the answer is known, so the right side may never run. That's how you safely guard a risky check:

C
#include <stdio.h>

int main(void) {
    int count = 0, total = 50;
    if (count != 0 && total / count > 10) {
        printf("high average\n");
    } else {
        printf("no division happened\n");
    }
    printf("%d %d %d\n", !0, !5, 3 && 0);
    return 0;
}
Output
no division happened
1 0 0

The conditional operator

condition ? a : b chooses between two values:

C
#include <stdio.h>

int main(void) {
    int items = 1;
    printf("%d item%s\n", items, items == 1 ? "" : "s");
    items = 3;
    printf("%d item%s\n", items, items == 1 ? "" : "s");
    int a = 8, b = 13;
    printf("max = %d\n", a > b ? a : b);
    return 0;
}
Output
1 item
3 items
max = 13

Precedence

Operators bind with different strength, so 2 + 3 * 4 is 14. A short version of the table, highest first:

LevelOperators
Postfixx++ x-- () [] . ->
Unary++x --x ! ~ - + * & sizeof (type)
Multiplicative* / %
Additive+ -
Shifts<< >>
Relational< <= > >=
Equality== !=
Bitwise&, then ^, then |
Logical&&, then ||
Conditional?:
Assignment= += -= …
Comma,

When in doubt, add parentheses — they cost nothing and make intent clear. Bitwise operators are a known trap: flags & MASK == 0 means flags & (MASK == 0).

Try it yourself

Check whether a year is a leap year: divisible by 4, except century years, which must be divisible by 400.

Try it yourself · main.c
Edit the code, copy it into main.c, then compile and run it with cc -std=c17 -Wall main.c -o main && ./main. How to set up a C compiler
Output
1900: not a leap year
2000: leap year
2024: leap year
2026: not a leap year