๐Ÿงฎ 21. Operator Precedence & Associativity in C

When a C expression contains several operators, its meaning depends on how the operators and operands are grouped and how equal-precedence operators group together. These rules are described using operator precedence and operator associativity.

Core idea: Precedence answers โ€œWhich operator binds more strongly?โ€ Associativity answers โ€œWhen operators have the same precedence, how are they grouped?โ€
Precedence

Determines the grouping when operators from different precedence levels appear together.

Associativity

Determines grouping direction when operators with the same precedence are present.

Parentheses

Parentheses state the intended grouping directly and make an expression easier to read.

21.1 Why Do We Need Precedence?

Consider:

int result = 2 + 3 * 4;

There are two operators: + and *. If addition happened first, the result would be:

(2 + 3) * 4 = 20

But multiplication has higher precedence than addition, so C groups the expression as:

2 + (3 * 4)

Therefore:

2 + 12 = 14
 Expression: 2 + 3 * 4 โ”‚ โ–ผ * has higher precedence โ”‚ โ–ผ 2 + (3 * 4) โ”‚ โ–ผ 14 

21.2 What Is Operator Precedence?

Operator precedence defines the relative priority of operators when an expression contains different operators.

For example:

* / % 

have higher precedence than:

+ - 

Therefore:

a + b * c

is grouped as:

a + (b * c)

not:

(a + b) * c

21.3 What Is Associativity?

Associativity determines how operators having the same precedence are grouped.

For example:

a - b + c

The + and - operators have the same precedence and their associativity is left-to-right.

Therefore:

(a - b) + c

is the grouping.

 a - b + c โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Same precedenceโ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ Left โ†’ Right (a - b) + c 

21.4 Precedence vs Associativity

Concept Question Answered Example
Precedence Which operator binds more strongly? a + b * c
Associativity How are equal-precedence operators grouped? a - b + c
Parentheses What grouping did the programmer explicitly request? (a + b) * c

21.5 C Operator Precedence Reference Table

The following table is a practical ordering from higher precedence to lower precedence.

Level Operators Description Associativity
1 () [] -> . ++ -- Function call, array subscript, member access, postfix increment/decrement Left โ†’ Right
2 ++ -- + - ! ~ (type) * & sizeof _Alignof Prefix increment/decrement, other unary operators, and casts Right โ†’ Left
3 * / % Multiplication, division, remainder Left โ†’ Right
4 + - Addition, subtraction Left โ†’ Right
5 << >> Bitwise shift Left โ†’ Right
6 < <= > >= Relational comparison Left โ†’ Right
7 == != Equality comparison 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 ?: Conditional operator Right โ†’ Left
14 = += -= *= /= %=
<<= >>= &= ^= |=
Assignment operators Right โ†’ Left
15 , Comma operator Left โ†’ Right
Important: Use this table to work out grouping. It does not say which independent operand or function call runs first. The increment operators appear at two levels because prefix and postfix forms have different precedence.

21.6 Parentheses Make Grouping Explicit

Parentheses explicitly group an expression.

int a = 2 + 3 * 4; int b = (2 + 3) * 4;

Results:

a = 14 b = 20
Best practice: Add parentheses when they help a reader understand the intended grouping. They are especially useful when mixing arithmetic, comparisons, and bitwise operators.

21.7 Arithmetic Precedence

int result = 10 + 4 * 2;

Multiplication comes first:

10 + (4 * 2) 10 + 8 18

Now consider:

int result = (10 + 4) * 2;

Parentheses change the grouping:

14 * 2 28

21.8 Multiplication, Division and Remainder

The operators *, /, and % have the same precedence and associate from left to right.

int result = 20 / 5 * 2;

Grouping:

(20 / 5) * 2

Result:

8

Not:

20 / (5 * 2)

21.9 Addition and Subtraction

int result = 20 - 5 + 2;

Both operators have the same precedence and are left-associative.

(20 - 5) + 2 15 + 2 17

21.10 Relational Operators vs Equality Operators

Relational operators have higher precedence than equality operators.

a < b == c < d

The relational comparisons are grouped first:

(a < b) == (c < d)

A comparison produces int value 1 when true and 0 when false. In the next comparison, that 0 or 1 becomes an operand.

21.11 Logical AND vs Logical OR

Logical AND has higher precedence than logical OR.

a || b && c

is grouped as:

a || (b && c)

not:

(a || b) && c
Common confusion: First find the grouping. Use precedence for different operator levels and associativity at the same level. Do not turn these grouping rules into a general rule that every operand runs from left to right.

21.12 Bitwise AND vs Logical AND

Operator Meaning Precedence Level
& Bitwise AND Higher than &&
&& Logical AND Lower than bitwise AND

For example:

a & b == 0

Because equality has higher precedence than bitwise AND, the expression is grouped as:

a & (b == 0)

This may be surprising. If the intended meaning is to test the bitwise result, write:

(a & b) == 0
When mixing bitwise and comparison operators, parentheses are strongly recommended.

21.13 Assignment Operators Are Right-Associative

a = b = c = 10;

The grouping is:

a = (b = (c = 10));

Therefore c receives 10, then b, then a.

21.14 Chained Assignment

int a, b, c; a = b = c = 25;

Conceptually:

c = 25 b = c a = b

All three objects end up containing 25.

21.15 Conditional Operator Associativity

The conditional operator ?: is right-associative.

a ? b : c ? d : e

is grouped as:

a ? b : (c ? d : e)

Nested conditional expressions can become difficult to read, so parentheses are often useful.

21.16 Unary Operators and Right-to-Left Associativity

For a chain of prefix unary operators, start with the operator nearest the operand and work outward.

!~x

can be understood as:

!(~x)

Read the inner operation first to understand what value the outer operator uses.

21.17 Function Calls and Array Access

Function call and array subscript operators have very high precedence.

arr[i + 1]

The expression between the brackets supplies the array index. The brackets form an array-access expression using arr.

Similarly:

printf("%d", a + b);

The parentheses after the function name form a function call. Commas separate the arguments; they do not specify which argument is evaluated first.

21.18 Structure Member Access

The operators . and -> are among the highest precedence operators.

student.age studentPtr->age

Parentheses can still be necessary when combining member access with other operators or pointer expressions.

21.19 Prefix vs Postfix Increment

++i i++

Both increment the object, but their values in an expression differ.

Expression Value Produced Object Update
++i Updated value Increment occurs before the value is used
i++ Previous value Increment occurs as part of the postfix operation

Postfix increment has higher precedence than prefix increment. This controls grouping, while the prefix/postfix rule determines whether the expression gives the new or old value.

21.20 Precedence Is Not Evaluation Order

Very important: Precedence determines how an expression is grouped. It does not automatically specify the order in which all operands are evaluated.

For example, do not reason incorrectly from precedence alone about:

f() + g()

The precedence of + does not tell you whether f() or g() is called first.

When the call order matters, call each function in a separate statement. Store the results and then calculate their sum.

21.21 Associativity Is Not Evaluation Order Either

Associativity answers a grouping question. It does not guarantee the execution order of separate function calls or other operands.

For example:

a - b - c

is grouped as:

(a - b) - c

because subtraction is left-associative.

For values already stored in variables, follow this grouping to calculate the answer. If the operands are function calls, do not assume that the leftmost call runs first.

21.22 A Complete Expression Trace

int result = 10 + 2 * 5 - 8 / 2;
 10 + 2 * 5 - 8 / 2 โ”‚ โ”‚ โ–ผ โ–ผ 2 * 5 8 / 2 โ”‚ โ”‚ โ–ผ โ–ผ 10 4 Expression becomes: 10 + 10 - 4 + and - have equal precedence. Associativity = Left โ†’ Right. (10 + 10) - 4 20 - 4 = 16 

21.23 Another Expression Trace

int result = 8 + 4 * 3 - 6 / 2;

Step 1:

4 * 3 = 12 6 / 2 = 3

Now:

8 + 12 - 3

Left-to-right for equal-precedence + and -:

(8 + 12) - 3 20 - 3 17

21.24 Parentheses Can Improve Readability

Compare:

if (a & mask == 0)

with:

if ((a & mask) == 0)

The second version communicates the intended grouping much more clearly.

Professional rule: Keep parentheses that make an expression easier to read. Removing them rarely helps a student understand the calculation.

21.25 Common Precedence Trap โ€” Arithmetic

int x = 2 + 3 * 4;

Correct:

14

Incorrect assumption:

20

21.26 Common Precedence Trap โ€” Division and Multiplication

int x = 24 / 6 * 2;

Both operators have the same precedence and are left-associative:

(24 / 6) * 2 4 * 2 8

21.27 Common Precedence Trap โ€” Logical Operators

if (age >= 18 && score >= 50 || bonus)

Grouping:

((age >= 18) && (score >= 50)) || bonus

Logical AND has higher precedence than logical OR.

21.28 Common Precedence Trap โ€” Assignment

if (x = 10)

This condition assigns a value instead of comparing values. The assigned value becomes the condition: zero is false and a nonzero value is true. Use equality comparison when you only want to test the value.

For comparison, use:

if (x == 10)
Remember: = assigns. == compares for equality.

21.29 Comma Operator

The comma operator has very low precedence compared with most other operators.

int x = (a = 5, b = 10, a + b);

The comma operator evaluates the expressions from left to right and the value of the whole comma expression is the value of its rightmost operand.

Here:

a = 5 b = 10 a + b = 15

So:

x = 15
Commas separating function arguments or declarations are not comma operators. In particular, argument separators do not guarantee left-to-right evaluation.

21.30 The Cast Operator

double result = (double)5 / 2;

A cast groups tightly with its operand. Here, it converts 5 to double before division, so the division uses floating-point arithmetic.

Therefore:

(double)5 

becomes a floating-point value before division.

Without the cast:

5 / 2

is integer division when both operands are integers.

21.31 Pointer Expressions and Precedence

Consider:

*p++

The postfix increment operator has higher precedence than unary dereference, so it is grouped as:

*(p++)

It is not:

(*p)++

These expressions have different effects.

With *p++, the expression uses the old pointer value for dereferencing, and p advances to the next element. With (*p)++, the pointed-to object changes and p stays in place.

21.32 Another Pointer Example

(*p)++;

Here parentheses force the dereferenced object to be incremented.

Compare:

*p++; 

which groups as:

*(p++);
Expression Grouping Main Effect
*p++ *(p++) Use pointed value, then advance pointer
(*p)++ Explicitly dereference first Increment pointed object

21.33 Array and Pointer Precedence

*p[i]

The array subscript operator has higher precedence than unary dereference. Therefore it is grouped as:

*(p[i])

not:

(*p)[i]

Parentheses are required for the second interpretation.

21.34 Macro Expressions and Precedence

Precedence becomes especially important when writing C preprocessor macros.

Unsafe macro:

#define SQUARE(x) x * x

Consider:

int result = SQUARE(5 + 1);

Expansion:

5 + 1 * 5 + 1

Due to multiplication precedence:

5 + 5 + 1 = 11 

Safe form:

#define SQUARE(x) ((x) * (x))

Expansion:

((5 + 1) * (5 + 1)) = 36 
Put parentheses around each parameter and around the whole macro expression. This protects the intended grouping when an argument contains another operator.

21.35 Side Effects in Expressions

Parentheses do not prevent a macro from using an argument twice. If the argument changes a variable, the expanded expression may have undefined behavior.

#define SQUARE(x) ((x) * (x)) int i = 5; int result = SQUARE(i++);

Expansion:

((i++) * (i++))

The expression modifies i more than once without the sequencing required to make the behavior defined. The behavior is therefore undefined.

A function is often safer when an argument may have side effects:

static inline int square_int(int x) { return x * x; }

21.36 Precedence and the Conditional Operator

int max = a > b ? a : b;

Relational comparison binds more strongly than the conditional operator, so the expression is effectively:

int max = (a > b) ? a : b;

Adding parentheses can still improve readability.

21.37 Precedence and Assignment

x = a + b * c;

Grouping:

x = (a + (b * c));

The multiplication is grouped before addition, and the resulting expression is then assigned to x.

21.38 How to Solve Precedence Questions

 Expression | v Check parentheses | v Find higher-precedence operators | v Group equal-precedence operators using associativity | v Check casts / unary operators | v Check logical and relational grouping | v Check assignment | v Evaluate the grouped expression | v Final result 

21.39 A Reliable Exam Method

  1. Write the expression clearly.
  2. Resolve explicit parentheses first.
  3. Identify the highest-precedence operators.
  4. Apply associativity where operators share precedence.
  5. Rewrite the expression with parentheses.
  6. Evaluate only after the grouping is clear.
  7. Check for side effects or undefined behavior.

21.40 Example โ€” Placement Style Question

int x = 5; int y = 2; int result = x + y * 3;

Multiplication first:

5 + (2 * 3) 5 + 6 11

Therefore:

result = 11

21.41 Example โ€” Same Precedence

int result = 100 / 10 * 2;

Because / and * have the same precedence:

(100 / 10) * 2 10 * 2 20

21.42 Example โ€” Logical Expression

int result = 1 || 0 && 0;

AND first:

1 || (0 && 0)

Then:

1 || 0 = 1 

21.43 Example โ€” Comparison and Logical Operators

int result = 5 > 2 && 8 > 4;

Comparisons are grouped before logical AND:

(5 > 2) && (8 > 4)

Both comparisons are true, so:

1 && 1 = 1 

21.44 Example โ€” Assignment Chain

int a, b, c; a = b = c = 50;

Because assignment is right-associative:

a = (b = (c = 50));

Final values:

a = 50 b = 50 c = 50 

21.45 Example โ€” Parentheses Change Everything

int a = 2; int b = 3; int c = 4; int x = a + b * c; int y = (a + b) * c;

First:

x = 2 + (3 * 4) x = 14

Second:

y = (2 + 3) * 4 y = 20

21.46 Precedence vs Evaluation vs Sequencing

Concept Meaning
Precedence Determines operator binding/grouping relative to other operators.
Associativity Determines grouping among operators sharing a precedence level.
Evaluation order Describes when operand expressions are evaluated.
Sequencing Describes ordering relationships important for side effects.
Check grouping first, then check which evaluations are ordered by C. Parentheses alone cannot make unsequenced changes safe.

21.47 Conditional Expressions with Mixed Types

The conditional operator uses only the selected alternative, but both alternatives help determine the result type. For example, mixing -1 and 10U can make the result unsigned. The program below uses two int alternatives, so the selected value stays an int.

Complete C program:

#include <stdio.h>

int main(void)
{
    int valid = 1;
    int points = valid ? 10 : -1;
    printf("Points = %d\n", points);
    return 0;
}

Expected output:

Points = 10

Step-by-step explanation:

  1. Only the chosen second or third operand is evaluated.
  2. Both alternatives are int in this example, so no unsigned conversion is involved.
  3. The result is assigned to points.
Remember: Precedence determines grouping; it does not mean that all operands are evaluated left to right.

21.48 Quick Revision

๐Ÿ“Œ Precedence โ†’ Determines how operators are grouped.

๐Ÿ“Œ Associativity โ†’ Resolves operators of the same precedence.

๐Ÿ“Œ * / % โ†’ Higher than + -

๐Ÿ“Œ + - โ†’ Higher than relational operators

๐Ÿ“Œ < <= > >= โ†’ Higher than == !=

๐Ÿ“Œ == != โ†’ Higher than bitwise AND

๐Ÿ“Œ & โ†’ Higher than ^

๐Ÿ“Œ ^ โ†’ Higher than |

๐Ÿ“Œ | โ†’ Higher than &&

๐Ÿ“Œ && โ†’ Higher than ||

๐Ÿ“Œ Assignment โ†’ Right-to-left

๐Ÿ“Œ Comma โ†’ Lowest precedence

๐Ÿ“Œ Parentheses โ†’ Use them to make intended grouping explicit.
INTERACTIVE LEARNING

๐ŸŽฌ Operator Precedence โ€” Expression Grouping

Follow how C groups 10 + 5 * 2 > 15 && 1 according to operator precedence.

PROGRAM TRACING

๐Ÿ”Ž Program Tracing โ€” Operator Precedence & Associativity

The combined expression is decomposed into clear steps so students can see the precedence relationship without relying on a tricky one-line statement.

21.49 Quick MCQs

Select an answer first, then click Check Answer. A correct choice becomes green. If the answer is wrong, your choice becomes red and the correct option becomes green. The explanation appears below.

1. Which operator has higher precedence?
2. What is the associativity of multiplication?
3. Which has higher precedence?
4. What is the result of 10 + 5 * 2?
5. What is the result of 20 / 5 * 2?
6. Which operator has lower precedence than ==?
7. Which operator associates right-to-left?
8. What is the result of 1 << 2 + 1?
9. What is *p++ interpreted as?
10. Which operator has the lowest precedence?
PRACTICE

21.50 ๐ŸŽฏ Practice Problems

Practice precedence, associativity, increments, pointer expressions, conditional and comma operators, parentheses, and safe expression analysis. Use ๐Ÿ’ป Solve It Yourself first, open Hint only when needed, and use Show Program after attempting the problem.

๐Ÿ“ˆ Operator Precedence & Associativity Practice Progress
Solved 0 / 20
Completed with Solution 0
Total Score 0 / 400
Completion 0%
A problem counts as Solved when all test cases pass without opening the full solution. Problems completed after viewing the official solution are tracked separately.
1. Evaluate 10 + 5 * 2

Problem 1: Find the output of the expression 10 + 5 * 2.

Input: No input.

Output: Print the evaluated result.

2. Evaluate 20 / 5 * 2

Problem 2: Find the output of the expression 20 / 5 * 2.

Input: No input.

Output: Print the evaluated result.

3. Evaluate 10 + 5 > 12

Problem 3: Evaluate the expression 10 + 5 > 12.

Input: No input.

Output: Print 1 for true or 0 for false.

4. Evaluate 5 | 3 & 1

Problem 4: Evaluate the expression 5 | 3 & 1.

Input: No input.

Output: Print the result.

5. Evaluate 1 << 2 + 1

Problem 5: Evaluate the expression 1 << 2 + 1.

Input: No input.

Output: Print the result.

6. Evaluate 1 || 0 && 0

Problem 6: Determine the result of 1 || 0 && 0.

Input: No input.

Output: Print 1 or 0.

7. Right-to-Left Assignment

Problem 7: Determine the values of a and b after a = b = 20.

Input: No input.

Output: Print a and b.

8. Pre-Increment Expression

Problem 8: Find the output of a pre-increment expression using x = 5 and y = ++x.

Input: No input.

Output: Print x and y.

9. Post-Increment Expression

Problem 9: Find the output of a post-increment expression using x = 5 and y = x++.

Input: No input.

Output: Print x and y.

10. *p++ vs (*p)++

Problem 10: Demonstrate the difference between *p++ and (*p)++ using an integer array.

Input: No input.

Output: Show the value read by *p++, the next pointed value, and the changed first element from (*p)++.

11. Nested Conditional Operator

Problem 11: Evaluate a nested conditional expression that assigns A for marks >= 90, B for marks >= 75, otherwise C.

Input: One integer marks.

Output: Print A, B, or C.

12. Comma Operator Expression

Problem 12: Find the result of a comma operator expression where y = (x = 5, x + 3).

Input: No input.

Output: Print x and y.

13. a + b * c - d

Problem 13: Identify the precedence order in a + b * c - d by evaluating it for supplied values.

Input: Four integers a b c d.

Output: Print the result of a + b * c - d.

14. a && b || c

Problem 14: Identify the precedence order in a && b || c by evaluating it for supplied logical values.

Input: Three integers a b c.

Output: Print 1 or 0.

15. Evaluate 10 > 5 == 1

Problem 15: Evaluate the expression 10 > 5 == 1.

Input: No input.

Output: Print the result.

16. 5 & 3 == 1

Problem 16: Evaluate 5 & 3 == 1 and compare it with the clearer parenthesized expression (5 & 3) == 1.

Input: No input.

Output: Print both results.

17. Rewrite with Parentheses

Problem 17: Rewrite a complicated expression using parentheses to make its grouping clear: a + b * c > d && e.

Input: Five integers a b c d e.

Output: Print the result using explicit parentheses.

18. Precedence vs Evaluation Order

Problem 18: Explain why precedence does not determine the complete evaluation order of an expression by printing two concise statements.

Input: No input.

Output: Print the required explanation on two lines.

19. Well-Defined vs Undefined Modification

Problem 19: Identify whether modifying the same variable multiple times in one unsequenced expression is well-defined. Do not execute undefined code.

Input: No input.

Output: Classify i = i++ + 1 as Undefined and two separate increment statements as Well-defined.

20. Ten Tricky C Expressions

Problem 20: Create a program containing ten defined but tricky C expressions, evaluate them, and print each result.

Input: No input.

Output: Print results E1 through E10, one per line.

21.51 Key Takeaway

๐ŸŽฏ Remember:

Precedence = grouping priority.

Associativity = direction for equal-precedence operators.

*, /, % come before + and -.

Arithmetic operators come before relational operators.

Relational operators come before equality operators.

Bitwise AND comes before XOR, which comes before OR.

&& comes before ||.

Assignment associates right-to-left.

Postfix operators such as p++ bind very tightly.

Precedence is not the same as evaluation order.

Use parentheses when an expression may be difficult to understand.
INTERVIEW PREPARATION

๐ŸŽค Operator Precedence & Associativity โ€” Interview Questions

1. What is operator precedence?
2. What is associativity?
3. Does precedence determine the runtime evaluation order of operands?
4. Why does *p++ mean *(p++)?
5. Why is a = b = 20 valid?
6. How is 1 << 2 + 1 grouped?
7. Why can 5 & 3 == 1 surprise programmers?
8. What is the safest way to write complex expressions in production code?
PLACEMENT TIPS

๐Ÿ’ก Operator Precedence & Associativity โ€” Placement Tips

  • Memorize the major operator groups, but use parentheses whenever a reader could reasonably misinterpret an expression.
  • When operators have the same precedence, check associativity: many arithmetic operators are left-to-right, while assignment is right-to-left.
  • Do not confuse grouping with evaluation order; precedence does not guarantee which operand runs first.
  • Be especially careful when mixing equality with bitwise operators, shifts with arithmetic, and pointer dereference with postfix increment.
  • An expression with unsequenced changes to the same variable has undefined behavior. Identify the error instead of guessing a numeric output.
  • In interviews, show the grouping first with parentheses, then evaluate the grouped expression step by step.
EXTRA PRACTICE

โœ๏ธ Operator Precedence & Associativity โ€” Extra Practice Questions

  1. Parenthesize a + b << c & d exactly as C groups it.
  2. Compare *p++, (*p)++, *++p, and ++*p using a small array.
  3. Evaluate a mixed expression containing arithmetic, relational, equality, logical AND, and logical OR operators.
  4. Write a nested conditional expression, then rewrite it using if/else for readability.
  5. Find three expressions where adding parentheses changes the result.
  6. Review five expressions and identify which are merely tricky and which contain undefined behavior.
โ† Previous Topic: Enumerations & typedef Next Topic: Storage Classes โ†’