Operator Precedence & Associativity
Understand which operators are evaluated first. Learn the PUMAS REBL TAC memory trick and when to use parentheses.
Track Your Progress
Sign in to save your learning progress
What You Will Learn
- ✓Know which operators execute first
- ✓Understand left-to-right vs right-to-left
- ✓Use parentheses to control order
- ✓Memorize PUMAS REBL TAC mnemonic
01Why Precedence Matters
When you write an expression like 10 + 20 * 30, the compiler needs rules to decide which operation to perform first. Without these rules, different compilers could give different results!
Without Precedence Rules
10 + 20 * 30
= (10 + 20) * 30?
= 900
✓ With Precedence Rules
10 + 20 * 30
= 10 + (20 * 30)
= 610
▶ Try it: Proves that * is evaluated before + due to higher precedence.
1#include <stdio.h>23int main() {4 int result = 10 + 20 * 30;5 printf("10 + 20 * 30 = %d\n", result);6 // Output: 610, not 900!7 8 return 0;9}02What is Operator Precedence?
Operator Precedence is a ranking that determines which operator is evaluated first when multiple operators appear in an expression. Operators with higher precedence are evaluated before those with lower precedence.
Quick Precedence Guide (Highest → Lowest)
( )
Parentheses
++ -- !
Unary
* / %
Multiply, Divide
+ -
Add, Subtract
< > <= >= == !=
Comparison
&& || =
Logical & Assignment
Use ( ) when in doubt - it makes code clearer!
Precedence in Action
▶ Try it: Shows step-by-step how precedence affects a complex expression.
1#include <stdio.h>23int main() {4 // Expression: 6 + 3 * 4 / 25 // Step 1: 3 * 4 = 12 (* evaluated first)6 // Step 2: 12 / 2 = 6 (/ next, same precedence as *)7 // Step 3: 6 + 6 = 12 (+ evaluated last)8 9 int result = 6 + 3 * 4 / 2;10 printf("6 + 3 * 4 / 2 = %d\n", result); // 1211 12 // Compare with parentheses13 int result2 = (6 + 3) * 4 / 2;14 printf("(6 + 3) * 4 / 2 = %d\n", result2); // 1815 16 return 0;17}03What is Associativity?
Associativity determines the order of evaluation when operators have the same precedence. It can be either:
Left-to-Right →
Most operators
100 / 5 % 2
= (100 / 5) % 2
= 20 % 2
= 0
← Right-to-Left
Assignment, unary, ternary
a = b = c = 5
= a = (b = (c = 5))
c=5, b=5, a=5
All = 5
▶ Try it: Demonstrates both left-to-right and right-to-left associativity.
1#include <stdio.h>23int main() {4 // Left-to-right associativity (/, %, -, +)5 int result1 = 100 / 5 % 2;6 printf("100 / 5 %% 2 = %d\n", result1); // 07 // Evaluated as: (100 / 5) % 2 = 20 % 2 = 08 9 int result2 = 20 - 5 - 3;10 printf("20 - 5 - 3 = %d\n", result2); // 1211 // Evaluated as: (20 - 5) - 3 = 15 - 3 = 1212 // NOT: 20 - (5 - 3) = 20 - 2 = 1813 14 // Right-to-left associativity (=)15 int a, b, c;16 a = b = c = 10;17 printf("a = b = c = 10: a=%d, b=%d, c=%d\n", a, b, c);18 // Evaluated as: a = (b = (c = 10))19 20 // Right-to-left for unary operators21 int x = 5;22 int y = - - x; // Double negation23 printf("- - 5 = %d\n", y); // 524 25 return 0;26}100 / 5 % 2 = 0
20 - 5 - 3 = 12
a = b = c = 10: a=10, b=10, c=10
- - 5 = 5
04Complete Precedence Table
Here is the complete operator precedence table from highest (1) to lowest (15) priority:
| Priority | Operators | Description | Associativity |
|---|---|---|---|
| 1 | () [] . -> ++ -- | Postfix operators | Left → Right |
| 2 | ++ -- + - ! ~ (type) * & sizeof | Unary operators | Right → Left |
| 3 | * / % | Multiplicative | Left → Right |
| 4 | + - | Additive | Left → Right |
| 5 | << >> | Bitwise shift | Left → Right |
| 6 | < <= > >= | Relational | Left → Right |
| 7 | == != | Equality | Left → Right |
| 8 | & | Bitwise AND | Left → Right |
| 9 | ^ | Bitwise XOR | Left → Right |
| 10 | | | Bitwise OR | Left → Right |
| 11 | && | Logical AND | Left → Right |
| 12 | || | Logical OR | Left → Right |
| 13 | ?: | Ternary conditional | Right → Left |
| 14 | = += -= *= /= %= &= ^= |= <<= >>= | Assignment | Right → Left |
| 15 | , | Comma | Left → Right |
Quick Reference
Highest: Postfix () [] → Lowest: Comma ,
Right-to-Left: Unary, Ternary, Assignment operators
05Memory Trick: PUMAS REBL TAC
Remembering 15 precedence levels is hard! Use this mnemonic to remember the order from highest to lowest:
PUMAS'REBL TAC
Postfix
() [] ++ --
Unary
++ -- ! ~ sizeof
Multiplicative
* / %
Additive
+ -
Shift
<< >>
Relational
< <= > >=
Equality
== !=
Bitwise
& ^ |
Logical
&& ||
Ternary
?:
Assignment
= += -= ...
Comma
,
Think of it as: "PUMA'S REBEL CAT"
Imagine a rebellious puma cat! This silly image will help you remember the order of operator precedence.
06Using Parentheses
Parentheses () have the highest precedence. Use them to override default precedence and make your code clearer.
▶ Try it: Shows how parentheses change the evaluation order of the same numbers.
1#include <stdio.h>23int main() {4 // Same numbers, different results!5 int a = 100 + 200 / 10 - 3 * 10;6 int b = (100 + 200) / 10 - 3 * 10;7 int c = (100 + 200) / (10 - 3) * 10;8 int d = 100 + 200 / (10 - 3 * 10);9 10 printf("100 + 200 / 10 - 3 * 10 = %d\n", a); // 9011 printf("(100 + 200) / 10 - 3 * 10 = %d\n", b); // 012 printf("(100 + 200) / (10 - 3) * 10 = %d\n", c); // 42013 printf("100 + 200 / (10 - 3 * 10) = %d\n", d); // Division by -2014 15 return 0;16}Best Practice
Even when not required, use parentheses to make complex expressions clearer.(a && b) || c is clearer than a && b || c
07Common Pitfalls
Chaining Comparisons (C vs Python)
int a = 10, b = 20, c = 30;// This does NOT work like Python!if (c > b > a) { // WRONG interpretation! printf("TRUE");}// Evaluated as: ((c > b) > a) = (1 > 10) = 0 (FALSE)// Correct way:if (c > b && b > a) { printf("TRUE"); // This works!}Comma Operator Confusion
int a;a = 1, 2, 3; // a = 1 (not 3!)// Evaluated as: (a = 1), 2, 3// What you probably meant:a = (1, 2, 3); // a = 3 (last value)Bitwise vs Logical Operators
int x = 1, y = 2;// & has LOWER precedence than ==if (x & y == 0) { } // Parsed as: x & (y == 0)// What you meant:if ((x & y) == 0) { } // Use parentheses!Pre vs Post Increment in Expressions
int i = 5;int a = i++ + ++i; // Undefined behavior!// Don't modify a variable twice in one expression!Code Pitfalls: Common Mistakes & What to Watch For
Common Mistakes with Operator Precedence
Copying code often generate expressions with subtle precedence bugs:
- ✗Bitwise vs comparison: Copied code
x & mask == 0meaningx & (mask == 0), not(x & mask) == 0 - ✗Ternary operator issues: Beginners often chain ternary operators without parentheses, creating unexpected evaluation order
- ✗Pointer dereference: Copied code
*ptr++expecting(*ptr)++but gets*(ptr++) - ✗Assignment in conditions: Beginners often confuse
=and==in if statements without parentheses for clarity
Always Understand Before Using
When you may copy complex expressions, add explicit parentheses to clarify intent. If you're unsure about precedence, the compiler doesn't care about extra parentheses — but wrong precedence creates bugs that compile silently and fail at runtime.
09Frequently Asked Questions
Q:Do I need to memorize the entire precedence table?
A: No! Memorize the basics: arithmetic (*,/) before (+,-), comparison before logical, assignment is lowest. For anything else, use parentheses to make your intent clear. Clear code beats clever code.
Q:What is associativity?
A: When operators have the same precedence, associativity determines order. Left-to-right:a - b - c = (a - b) - c.Right-to-left (assignment): a = b = c =a = (b = c).
Q:Why is a = 5 == 5 legal but confusing?
A: Because == has higher precedence than =, it evaluates asa = (5 == 5) = a = 1. Perfectly valid but looks like you meant (a = 5) == 5. Use parentheses!
Q:Why is *ptr++ dangerous?
A: Because postfix ++ binds tighter than *! So *ptr++ is*(ptr++) — dereference, then increment pointer. To increment the value, write (*ptr)++. When in doubt, parenthesize.
Q:What's undefined behavior with increment operators?
A: Modifying a variable multiple times in one expression is undefined: i++ + ++i can give different results on different compilers! Rule: never modify and read the same variable in one expression without a sequence point.
09Summary
What You Learned:
- ✓WHY: Precedence determines which operators execute first in complex expressions
- ✓Associativity: Left-to-right or right-to-left when operators have same precedence
- ✓Best Practice: Use parentheses to make your intent clear
10Memory Tips for Precedence
The Postfix Rule
Postfix operators (function calls, array subscripts, ->, .) have the highest precedence. This means *ptr++ increments the pointer, not the value. Use (*ptr)++ to increment the value.
Assignment is Low Priority
Assignment operators have very low precedence, which is whyx = a + b works as expected. But this also meansx = a == b assigns the comparison result (0 or 1) to x.
When in Doubt, Parenthesize
Even if you know the precedence rules, others reading your code might not. Explicit parentheses make code self-documenting and prevent bugs during refactoring. Compilers optimize them away—there's no runtime cost.
Test Your Knowledge
Related Tutorials
C Operators and Expressions
Learn all the operators in C: math (+, -, *, /), comparisons (==, <, >), and logical operations (&&, ||). Build expressions that compute values.
Type Casting & Type Conversion
Learn how to convert between data types in C. Master implicit (automatic) and explicit (manual) type casting, avoid integer division bugs, and understand when data loss occurs.
Control Flow & Decision Making
Make your programs smart! Use if-else to make decisions and switch for multiple choices. Programs can now respond differently to different situations.
Have Feedback?
Found something missing or have ideas to improve this tutorial? Let us know on GitHub!