Skip to content
Home C / C++ Operators in C Explained — Types, Examples and Common Mistakes

Operators in C Explained — Types, Examples and Common Mistakes

Where developers are forged. · Structured learning · Free forever.
📍 Part of: C Basics → Topic 3 of 17
Master operators in C with clear explanations, runnable code examples, real output, and beginner mistakes to avoid.
🧑‍💻 Beginner-friendly — no prior C / C++ experience needed
In this tutorial, you'll learn
Master operators in C with clear explanations, runnable code examples, real output, and beginner mistakes to avoid.
  • Integer division in C silently truncates — 7 / 2 is 3, not 3.5. Cast to float explicitly when you need decimals.
  • = assigns, == compares. Mixing them up compiles without error but produces wrong behaviour — this is one of C's most dangerous silent bugs.
  • Postfix counter++ returns the old value then increments; prefix ++counter increments first then returns the new value. The difference only matters when the result is used in an expression.
✦ Plain-English analogy ✦ Real code with output ✦ Interview questions
Quick Answer

Think of operators like the buttons on a calculator. The numbers are your data, and the buttons (+, -, ×, ÷) tell the calculator WHAT TO DO with those numbers. In C, operators are the symbols that tell your program how to work with values — add them, compare them, combine them, or flip them. Without operators, your program would just be a list of numbers sitting there doing nothing.

Every useful program on the planet — from a banking app calculating your balance to a game engine deciding if a bullet hit a target — makes decisions and performs calculations. None of that is possible without operators. They are the verbs of your code. If variables are the nouns (the things), operators are the actions performed on those things. Understanding them deeply isn't optional — it's the foundation everything else is built on.

Before operators existed in programming languages, writing even simple math required multiple low-level machine instructions. C gave programmers a concise, expressive set of symbols that map closely to what the hardware actually does — which is why C is still used in embedded systems, operating systems, and performance-critical software today. Operators solve the problem of expressing computation, comparison, and logic in a way that's both human-readable and highly efficient.

By the end of this article you'll know every major category of C operator, understand exactly what each one does and why it exists, be able to read real C code without getting tripped up by symbols like >>= or !=, and you'll know the two most common operator mistakes beginners make — so you can avoid them from day one.

Arithmetic Operators — Your Program's Built-In Calculator

Arithmetic operators do exactly what the name suggests: math. C gives you six of them — addition (+), subtraction (-), multiplication (*), division (/), modulus (%), and unary negation (-). You already know the first four from school. The one that surprises beginners is modulus.

Modulus (%) gives you the REMAINDER after division. So 10 % 3 gives you 1, because 10 divided by 3 is 3 with 1 left over. This is incredibly useful in real code — use it to check if a number is even or odd, to wrap a value around a range (like keeping a game character on screen), or to cycle through array indices.

One critical thing to understand: when you divide two integers in C, you get integer division. That means 7 / 2 gives you 3, not 3.5. The decimal part is thrown away — not rounded, just discarded. This catches virtually every beginner at least once. If you need the decimal result, at least one of the operands must be a float or double.

arithmetic_operators.c · C
123456789101112131415161718192021222324252627282930313233343536373839
#include <stdio.h>

// Package Branding: io.thecodeforge

int main() {
    int apples = 17;
    int children = 5;

    // Basic arithmetic
    int total_after_buying_more = apples + 8;   // addition
    int eaten = apples - 3;                      // subtraction
    int doubled = apples * 2;                    // multiplication

    // Integer division: the decimal part is SILENTLY dropped
    int each_child_gets = apples / children;     // 17 / 5 = 3 (not 3.4)

    // Modulus: gives the leftover after division
    int leftover_apples = apples % children;     // 17 % 5 = 2

    printf("Apples after buying more: %d\n", total_after_buying_more);
    printf("Apples after eating 3: %d\n", eaten);
    printf("Apples if we doubled: %d\n", doubled);
    printf("Each child gets: %d apples\n", each_child_gets);
    printf("Leftover apples: %d\n", leftover_apples);

    // To get the decimal result, use float casting
    float precise_share = (float)apples / children;
    printf("Precise share per child: %.2f apples\n", precise_share);

    // Checking even/odd with modulus
    int mystery_number = 42;
    if (mystery_number % 2 == 0) {
        printf("%d is even\n", mystery_number);
    } else {
        printf("%d is odd\n", mystery_number);
    }

    return 0;
}
▶ Output
Apples after buying more: 25
Apples after eating 3: 14
Apples if we doubled: 34
Each child gets: 3 apples
Leftover apples: 2
Precise share per child: 3.40 apples
42 is even
⚠ Watch Out: Integer Division Silently Drops Decimals
7 / 2 in C gives 3, not 3.5. There's no error, no warning — your program just quietly gives you the wrong answer. If you need decimal precision, write (float)7 / 2 or make one of your variables a float. This silent truncation is one of the most common bugs in beginner C programs.

Relational and Logical Operators — Teaching Your Program to Make Decisions

Arithmetic operators crunch numbers. Relational operators compare them and return either 1 (true) or 0 (false). They're the basis of every if-statement, every loop condition, every decision your program makes. C has six: == (equal to), != (not equal to), > (greater than), < (less than), >= (greater than or equal to), and <= (less than or equal to).

Logical operators let you combine those comparisons. Think of them as the words 'and', 'or', and 'not' in English. In C: && means AND (both conditions must be true), || means OR (at least one must be true), and ! means NOT (flips true to false or false to true).

Here's a real-world framing: you're building a ride at an amusement park. The rule is: you must be AT LEAST 120cm tall AND you must be UNDER 200cm tall. That's two conditions joined by AND — exactly what && handles. If either condition is false, you don't get on the ride. This kind of gating logic appears in virtually every program ever written.

relational_logical_operators.c · C
123456789101112131415161718192021222324252627282930
#include <stdio.h>

// Standard interview logic for flow control

int main() {
    int height_cm = 145;
    int age = 12;
    int has_parent_with_them = 1;  

    // --- Relational Operators ---
    printf("height_cm > 120: %d\n", height_cm > 120);
    printf("height_cm > 200: %d\n", height_cm > 200);

    // --- Logical AND (&&) with short-circuiting ---
    int allowed_on_ride = (height_cm >= 120) && (height_cm <= 200);
    printf("\nAllowed on ride (height check): %d\n", allowed_on_ride);

    // --- Logical OR (||) ---
    int can_enter_park = (age >= 18) || (has_parent_with_them == 1);
    printf("Can enter park (age OR has parent): %d\n", can_enter_park);

    // --- Combined condition ---
    if (allowed_on_ride && can_enter_park) {
        printf("\nWelcome! Enjoy the ride!\n");
    } else {
        printf("\nSorry, you cannot go on this ride.\n");
    }

    return 0;
}
▶ Output
height_cm > 120: 1
height_cm > 200: 0
Allowed on ride (height check): 1
Can enter park (age OR has parent): 1
Welcome! Enjoy the ride!
⚠ Watch Out: == vs = Is the #1 Beginner Bug in C
Writing if (score = 10) instead of if (score == 10) doesn't cause an error — it ASSIGNS 10 to score and then evaluates to true, because 10 is non-zero. Your program runs, but with completely wrong behaviour. Always double-check your if-conditions. Some compilers warn about this with -Wall — always compile with warnings enabled.

Assignment and Compound Assignment Operators — Writing Less, Doing More

The single equals sign (=) in C is the assignment operator. It takes the value on the right and stores it in the variable on the left. It does NOT check equality — that's ==. Read it as 'gets the value of', not 'equals'.

C also gives you compound assignment operators, which combine an arithmetic operation WITH assignment into one step. Instead of writing score = score + 10, you write score += 10. They're shorthand — nothing more, nothing less. But they appear everywhere in real C code, so you need to be completely comfortable reading them.

The full set is: += (add and assign), -= (subtract and assign), *= (multiply and assign), /= (divide and assign), and %= (modulo and assign). There's also a special pair called the increment (++) and decrement (--) operators. These add or subtract exactly 1. You'll see them constantly in loops. They come in two flavours — prefix (++counter) and postfix (counter++) — and the difference matters in certain situations, so pay attention to the code below.

assignment_operators.c · C
12345678910111213141516171819
#include <stdio.h>

int main() {
    int player_score = 100;

    // Compound assignment: += -= *= /=
    player_score += 50;   
    player_score *= 2;    
    printf("Final score after logic: %d\n", player_score);

    // --- Prefix vs Postfix ---
    int counter = 5;
    int a = counter++; // 'a' gets 5, then counter becomes 6
    int b = ++counter; // counter becomes 7, then 'b' gets 7

    printf("Postfix result: %d, Prefix result: %d, Final counter: %d\n", a, b, counter);

    return 0;
}
▶ Output
Final score after logic: 300
Postfix result: 5, Prefix result: 7, Final counter: 7
💡Pro Tip: Use Prefix ++ in Loops When In Doubt
When you write for (int i = 0; i < 10; i++), postfix vs prefix makes no difference because the result isn't being assigned anywhere. But when you use ++ inside an expression like array[i++] vs array[++i], the difference is critical. If you're unsure, use prefix (++i) — it's also marginally faster on some older compilers because it doesn't need to store a temporary copy of the old value.

Bitwise Operators — Working Directly With the Zeros and Ones

Every value in your computer is stored as binary — a sequence of 0s and 1s called bits. Bitwise operators let you manipulate those individual bits directly. This sounds advanced, but it's used everywhere: setting hardware flags in embedded systems, optimising memory in tight loops, building permission systems (read/write/execute flags in Linux are a perfect example), and even fast graphics programming.

C has six bitwise operators: & (AND), | (OR), ^ (XOR), ~ (NOT/complement), << (left shift), and >> (right shift). The AND and OR work bit-by-bit, just like logical && and || but on the individual bits of both operands simultaneously.

Left shift (<<) multiplies a number by powers of 2 very efficiently. Shifting left by 1 is the same as multiplying by 2, shifting left by 2 is multiplying by 4, and so on. Right shift (>>) divides by powers of 2. This is why you'll often see bitwise operations in performance-sensitive C code — they're single CPU instructions, much faster than multiplication and division.

bitwise_operators.c · C
12345678910111213141516171819202122
#include <stdio.h>

// Production-grade bit manipulation for flag management

int main() {
    unsigned int READ    = 1 << 2; // 0000 0100 (4)
    unsigned int WRITE   = 1 << 1; // 0000 0010 (2)
    unsigned int EXECUTE = 1 << 0; // 0000 0001 (1)

    unsigned int user_perms = READ | WRITE; // Sets bit 2 and 1

    // Checking if bit is set using AND (&)
    if (user_perms & READ) {
        printf("Access Granted: Read Enabled\n");
    }

    // Toggling using XOR (^)
    user_perms ^= WRITE; 
    printf("New Perm Value: %u\n", user_perms);

    return 0;
}
▶ Output
Access Granted: Read Enabled
New Perm Value: 4
🔥Interview Gold: Why Use Bitwise Over Boolean Arrays for Flags?
Storing 8 permission flags as separate boolean variables uses 8 bytes (minimum). Storing them as bits inside a single unsigned char uses 1 byte — 8x more memory-efficient. In embedded systems with kilobytes of RAM, this difference is mission-critical. Interviewers love asking this exact question when they see bitwise operators on your resume.
Operator CategoryPurposeReturnsCommon Use Case
Arithmetic (+, -, *, /, %)Perform math calculationsNumeric resultScore calculation, geometry, counters
Relational (==, !=, >, <, >=, <=)Compare two values1 (true) or 0 (false)if-conditions, loop bounds, sorting
Logical (&&, ||, !)Combine boolean conditions1 (true) or 0 (false)Multi-condition checks, access control
Assignment (=, +=, -=, *=, /=)Store values in variablesThe assigned valueUpdating variables, running totals
Increment/Decrement (++, --)Add or subtract 1Old or new value (prefix vs postfix)Loop counters, pointer traversal
Bitwise (&, |, ^, ~, <<, >>)Manipulate individual bitsNumeric result (bit pattern)Flags, permissions, fast math, hardware

🎯 Key Takeaways

  • Integer division in C silently truncates — 7 / 2 is 3, not 3.5. Cast to float explicitly when you need decimals.
  • = assigns, == compares. Mixing them up compiles without error but produces wrong behaviour — this is one of C's most dangerous silent bugs.
  • Postfix counter++ returns the old value then increments; prefix ++counter increments first then returns the new value. The difference only matters when the result is used in an expression.
  • Bitwise operators work on individual bits and are used for flags, permissions, and fast power-of-2 math — understanding them is what separates systems programmers from script writers.

⚠ Common Mistakes to Avoid

    Using = instead of == in conditions — Writing if (temperature = 100) assigns 100 to temperature and always evaluates as true (since 100 is non-zero), so your else branch is unreachable and the variable is silently corrupted. Fix: always use == for comparison inside if, while, and for conditions. Compile with gcc -Wall to catch this — the compiler will say 'suggest parentheses around assignment used as truth value'.
    Fix

    always use == for comparison inside if, while, and for conditions. Compile with gcc -Wall to catch this — the compiler will say 'suggest parentheses around assignment used as truth value'.

    Assuming integer division gives a decimal result — Writing int result = 7 / 2 gives 3, not 3.5. There's no compiler warning; you just get a wrong answer silently. Fix: cast at least one operand to float before dividing — float result = (float)7 / 2 — or declare the variables as float/double from the start if decimal precision matters.
    Fix

    cast at least one operand to float before dividing — float result = (float)7 / 2 — or declare the variables as float/double from the start if decimal precision matters.

    Confusing prefix and postfix ++ inside expressions — Writing int snapshot = counter++ stores the ORIGINAL value of counter in snapshot, then increments counter. Writing int snapshot = ++counter increments counter FIRST, then stores the NEW value. Using the wrong one inside array indexing (arr[i++] vs arr[++i]) causes off-by-one errors that are notoriously hard to debug. Fix: never use ++ or -- inside a larger expression unless you're certain which version you need. When in doubt, put the increment on its own line.
    Fix

    and postfix ++ inside expressions — Writing int snapshot = counter++ stores the ORIGINAL value of counter in snapshot, then increments counter. Writing int snapshot = ++counter increments counter FIRST, then stores the NEW value. Using the wrong one inside array indexing (arr[i++] vs arr[++i]) causes off-by-one errors that are notoriously hard to debug. Fix: never use ++ or -- inside a larger expression unless you're certain which version you need. When in doubt, put the increment on its own line.

Interview Questions on This Topic

  • QDifference between prefix and postfix increment with dry run of: int x=10; int y=x++ + ++x; What is y?
  • QExplain short-circuit evaluation in logical operators (&& and ||). How does C handle the second operand if the first already determines the result?
  • QHow do you check if a number is a power of 2 using bitwise operators in a single line of code? (LeetCode standard: x & (x-1) == 0)
  • QWhat is the difference between bitwise AND (&) and logical AND (&&)? Provide a scenario where one is preferred over the other.
  • QImplement a swap function for two integers without using a temporary variable using XOR (^).

Frequently Asked Questions

Which operator has the highest precedence in C?

Postfix operators like () (function call), [] (array subscripting), and . or -> (member access) have the highest precedence. They are evaluated before arithmetic or logical operators. Always use parentheses if you are unsure of the order of evaluation.

What is the result of a bitwise shift beyond the size of the variable?

Shifting a bit by a value equal to or greater than the number of bits in the operand is 'Undefined Behavior' in C. For example, shifting a 32-bit integer by 32 or more positions will yield unpredictable results depending on the CPU architecture.

What is the modulus operator in C and when should I use it?

The modulus operator (%) gives you the remainder after integer division. For example, 17 % 5 equals 2 because 5 goes into 17 three times with 2 left over. Use it to check if a number is even or odd (number % 2 == 0 means even), to wrap values around a range, or to cycle through a fixed set of options repeatedly.

Why do bitwise operators exist if we already have logical operators like && and ||?

Logical operators (&&, ||) work on entire values treated as true or false — they only care whether something is zero or non-zero, and they short-circuit (stop evaluating early). Bitwise operators (&, |) work on every individual bit simultaneously and never short-circuit. Bitwise operators are essential for packing multiple flags into a single integer, manipulating hardware registers, and writing memory-efficient code — tasks where logical operators simply don't have the precision needed.

Is there a 'Power' operator (like ^ in Python) in C?

No. In C, the ^ symbol is the Bitwise XOR operator. To perform exponentiation, you must use the pow(base, exponent) function from the <math.h> library or write a loop for integer powers.

🔥
Naren Founder & Author

Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.

← PreviousVariables and Data Types in CNext →Control Flow in C
Forged with 🔥 at TheCodeForge.io — Where Developers Are Forged