🧑🏽💻Intro to C Programming
Operators in C
Study smarter with Fiveable
Get study guides, practice questions, and cheatsheets for all your subjects. Join 500,000+ students with a 96% pass rate.
Why This Matters
Operators are the verbs of C programming—they're how you actually do things with your data. Every calculation, every comparison, every decision your program makes relies on operators. You're being tested not just on recognizing operator symbols, but on understanding operator precedence, type behavior (like integer division truncation), and side effects (how increment operators change values mid-expression). These concepts appear constantly in exam questions that ask you to trace code or predict output.
Mastering operators means understanding evaluation order, type conversion, and memory manipulation. The difference between = and == has crashed countless programs, and knowing when to use && versus & separates competent programmers from confused ones. Don't just memorize symbols—know what each operator returns, how it affects its operands, and where precedence might trip you up.
Arithmetic and Mathematical Operations
These operators handle the fundamental math your programs need. The key insight: C treats integer and floating-point arithmetic differently, and this catches many students off guard.
Arithmetic Operators (+, -, *, /, %)
- Five core operations—addition
+, subtraction-, multiplication*, division/, and modulus%form the foundation of all calculations - Integer division truncates— evaluates to , not ; use floating-point types or casting to preserve decimals
- Modulus returns remainders— evaluates to ; only works with integer operands and is essential for cycling, wrapping, and divisibility checks
Increment and Decrement Operators (++, --)
- Shorthand for operations—
++xandx++both add 1, but timing differs based on prefix vs. postfix form - Prefix evaluates before use—in
y = ++x, x increments first, then y gets the new value; postfix (x++) assigns first, then increments - Loop workhorses—nearly every
forloop uses these operators; understanding prefix vs. postfix prevents off-by-one errors
Compare: ++x vs. x++—both increment x by 1, but prefix returns the new value while postfix returns the original value. If asked to trace y = x++ where x starts at 5, y becomes 5 and x becomes 6.
Assignment and Compound Assignment
Assignment operators store values in variables. The critical distinction: assignment is an operation that returns a value, not just a statement.
Assignment Operator (=)
- Right-to-left evaluation—the expression on the right is fully evaluated before being stored in the left-hand variable
- Returns the assigned value—this enables chaining like
a = b = c = 0, which assigns 0 to all three variables - Common error source—confusing
=(assignment) with==(comparison) compiles without error but produces bugs;if (x = 5)always evaluates true
Compound Assignment Operators (+=, -=, *=, /=, %=)
- Shorthand combinations—
x += 5is equivalent tox = x + 5, reducing repetition and potential typos - Works with all arithmetic operators—includes
+=,-=,*=,/=,%=, and even bitwise versions like&=and|= - Evaluates left side once—important when the left side has side effects;
arr[i++] += 1only increments i once
Compare: x = x + 1 vs. x += 1 vs. x++—all increment x by 1, but compound assignment and increment operators are more concise and, in some contexts, can be more efficient. Use ++ for simple increments, += when adding values other than 1.
Comparison and Decision-Making
Relational and logical operators power every if statement and loop condition. These operators always return either 0 (false) or 1 (true) in C.
Relational Operators (==, !=, <, >, <=, >=)
- Return boolean integers—comparisons yield for true and for false; C has no dedicated boolean type in C89
- Six comparison types—equal
==, not equal!=, less than<, greater than>, less than or equal<=, greater than or equal>= - Lower precedence than arithmetic—
x + 1 < yevaluates the addition before the comparison; parentheses clarify intent
Logical Operators (&&, ||, !)
- Combine boolean expressions—AND
&&requires both operands true; OR||requires at least one true; NOT!inverts the value - Short-circuit evaluation—
&&stops if the left operand is false;||stops if the left operand is true; this prevents unnecessary computation and potential errors - NOT has high precedence—
!x && yapplies NOT to x only; use parentheses!(x && y)to invert the entire expression
Compare: && vs. &—logical AND (&&) works on truth values and short-circuits; bitwise AND (&) operates on individual bits and always evaluates both sides. Using & when you mean && is a common bug that sometimes works by accident.
Bitwise and Low-Level Operations
Bitwise operators manipulate individual bits within integers. These are essential for systems programming, embedded development, and optimization.
Bitwise Operators (&, |, ^, ~)
- Operate on binary representations—AND
&yields 1 only where both bits are 1; OR|yields 1 where either bit is 1; XOR^yields 1 where bits differ - NOT inverts all bits—
~flips every bit;~0becomes all 1s (typically in two's complement) - Masking and flags—use AND to extract specific bits, OR to set bits, XOR to toggle bits; essential for hardware control and compact data storage
Shift Operators (<<, >>)
- Left shift multiplies by powers of 2—
x << nis equivalent to ; bits shift left, zeros fill from the right - Right shift divides by powers of 2—
x >> nis equivalent to for unsigned types; behavior varies for signed negatives - Faster than multiplication/division—compilers often optimize arithmetic to shifts automatically, but explicit shifts clarify intent in bit manipulation code
Compare: << vs. *—left-shifting by 1 (x << 1) doubles x just like x * 2, but shifting is a single CPU instruction. For powers of 2, shifting is idiomatic in systems code; for general multiplication, use * for clarity.
Special-Purpose Operators
These operators serve specific roles that don't fit neatly into other categories. Each solves a particular programming problem elegantly.
Conditional Operator (? :)
- Ternary inline if-else—syntax is
condition ? value_if_true : value_if_false; the only C operator taking three operands - Returns a value—unlike if-else statements, this is an expression:
max = (a > b) ? a : bassigns directly - Keep it simple—nested ternary operators become unreadable quickly; use if-else for complex logic
Sizeof Operator
- Returns size in bytes—
sizeof(int)gives the byte count for an int on your system (commonly 4 bytes) - Works on types and variables—
sizeof(x)returns the size of variable x; parentheses optional for variables but required for type names - Essential for memory allocation—
malloc(n * sizeof(int))ensures portable, correct memory requests regardless of platform
Comma Operator (,)
- Evaluates left-to-right, returns rightmost—in
(a = 1, b = 2, a + b), all three execute but the expression yields - Common in for loops—
for (i = 0, j = 10; i < j; i++, j--)initializes and updates multiple variables - Lowest precedence—parentheses are usually needed to prevent the comma from being interpreted as a separator rather than an operator
Compare: Conditional ? : vs. if-else—both make decisions, but the ternary operator is an expression returning a value while if-else is a statement. Use ternary for simple value selection; use if-else for complex actions or multiple statements.
Memory and Pointer Operations
Pointer operators give you direct access to memory addresses. Understanding these is crucial for dynamic memory, arrays, and efficient function calls.
Pointer Operators (* and &)
- Ampersand gets addresses—
&xreturns the memory address where variable x is stored; this address can be stored in a pointer - Asterisk dereferences pointers—if
pholds an address,*paccesses the value at that address; also used in pointer declarations (int *p) - Foundation for advanced C—pointers enable dynamic memory allocation, efficient array handling, and pass-by-reference function parameters
Compare: * in declarations vs. expressions—int *p declares p as a pointer to int; *p = 5 dereferences p to store 5 at the pointed-to location. Same symbol, different contexts—this trips up many beginners.
Quick Reference Table
| Concept | Best Examples |
|---|---|
| Basic math operations | +, -, *, /, % |
| Value modification | =, +=, -=, ++, -- |
| Comparisons | ==, !=, <, >, <=, >= |
| Boolean logic | &&, ` |
| Bit manipulation | &, ` |
| Conditional expressions | ? : |
| Memory and size | sizeof, *, & |
| Multiple expressions | , (comma operator) |
Self-Check Questions
-
What is the output of
int x = 5; int y = x++;for both x and y? How would the result differ with++x? -
Why does
7 / 2evaluate to 3 in C, and what are two ways to get the result 3.5 instead? -
Compare
&&and&: when would using the wrong one cause a bug, and when might it accidentally work correctly? -
If
int a = 10;andint *p = &a;, what dop,*p, and&aeach represent? How would you use these to change a's value to 20? -
Trace this expression:
int result = (3 > 2) ? (4 + 1) : (4 - 1);What value does result hold, and how would you rewrite this using an if-else statement?