Operator Precedence and Associativity
Operator Precedence
Operator precedence determines which operation is performed first in an expression.
It refers to the order in which operators are evaluated in an expression. Operators with higher precedence are evaluated before operators with lower precedence.
For example:
- In the expression
a + b * c
, the multiplication operator(*)
has higher precedence than the addition operator(+)
, sob * c
is evaluated first, and then the result is added to a.
Operator Associativity
Operators Associativity is used when two operators of same precedence appear in an expression.
Determines the order in which operations with the same precedence are evaluated. There are two types of associativity: left-to-right and right-to-left.
Operators with left-to-right associativity are evaluated from left to right.
For example:
- In the expression
a - b - c,
the subtraction operator(-)
has left-to-right associativity, so the expression is evaluated as(a - b) - c
.
Operators with right-to-left associativity are evaluated from right to left.
For example:
- In the expression
a = b = c
, the assignment operator(=)
has right-to-left associativity, so the expression is evaluated asa = (b = c)
.
Operator Precedence and Associativity Table
Following table shows the Operator Precedence and Associatvity in C:
Operator | Operator Name | Precedence | Associativity | Description |
---|---|---|---|---|
() | Function call | 1 | Left-to-right | Function call |
[] | Array subscript | 2 | Left-to-right | Array subscript |
. | Structure member access | 3 | Left-to-right | Structure member access |
-> | Structure pointer member access | 4 | Left-to-right | Structure pointer member access |
++ | postfix increment | 5 | Left-to-right | Increments the value of the operand by 1 after the expression is evaluated |
-- | postfix decrement | 5 | Left-to-right | Decrements the value of the operand by 1 after the expression is evaluated |
++ | prefix increment | 6 | Right-to-left | Increments the value of the operand by 1 before the expression is evaluated |
-- | prefix decrement | 6 | Right-to-left | Decrements the value of the operand by 1 before the expression is evaluated |
+ | unary plus | 7 | Right-to-left | Unary plus operator |
- | unary minus | 7 | Right-to-left | Unary minus operator |
! | logical NOT | 8 | Right-to-left | Logical NOT operator |
~ | bitwise NOT | 8 | Right-to-left | Bitwise NOT operator |
* | dereference | 9 | Right-to-left | Dereference operator |
& | address-of | 9 | Right-to-left | Address-of operator |
sizeof | sizeof | 9 | Right-to-left | Size |
* | multiplication | 10 | Left-to-right | Multiplication operator |
/ | division | 10 | Left-to-right | Division operator |
% | modulo | 10 | Left-to-right | Modulo operator |
+ | addition | 11 | Left-to-right | Addition operator |
- | subtraction | 11 | Left-to-right | Subtraction operator |
<< | bitwise left shift | 12 | Left-to-right | Bitwise left shift operator |
>> | bitwise right shift | 12 | Left-to-right | Bitwise right shift operator |
< | less than | 13 | Left-to-right | Less than operator |
<= | less than or equal to | 13 | Left-to-right | Less than or equal to operator |
> | greater than | 13 | Left-to-right | Greater than operator |
>= | greater than or equal to | 13 | Left-to-right | Greater than or equal to operator |
== | equal to | 14 | Left-to-right | Equal to operator |
!= | not equal to | 14 | Left-to-right | Not equal to operator |
& | bitwise AND | 15 | Left-to-right | Bitwise AND operator |
^ | bitwise XOR | 16 | Left-to-right | Bitwise XOR operator |
" | " | bitwise OR | 17 | Left-to-right |
&& | logical AND | 18 | Left-to-right | Logical AND operator |
" | " | logical OR | 19 | |
?: | ternary operator | 20 | Right-to-left | ternary operator |
"=" | assignment | 21 | Right-to-left | assignment |
+= | addition assignment | 21 | Right-to-left | Ternary operator (conditional operator) |
-= | subtraction assignment | 21 | Right-to-left | Assignment operator |
*= | multiplication assignment | 21 | Right-to-left | Addition assignment operator |
/= | division assignment | 21 | Right-to-left | Subtraction assignment operator |
%= | modulo assignment | 21 | Right-to-left | Multiplication assignment operator |
&= | bitwise AND assignment | 21 | Right-to-left | Division assignment operator |
^= | bitwise XOR assignment | 21 | Right-to-left | Modulo assignment operator |
= | bitwise OR assignment | 21 | Right-to-left | |
<<= | bitwise left shift assignment | 21 | Right-to-left | Bitwise left shift assignment operator |
>>= | bitwise right shift assignment | 21 | Right-to-left | Bitwise right shift assignment operator |
, | comma operator | 22 | Left-to-right | Comma operator |
Operator Precedence Example
Below program shows the operator precedence in C:
#include <stdio.h>
int main() {
int x = 10;
int y = 20;
int z = 30;
printf("x + y * z = %d\n", x + y * z); // x + y * z = 210
printf("x * y + z = %d\n", x * y + z); // x * y + z = 650
printf("x / y + z = %d\n", x / y + z); // x / y + z = 30
printf("x / (y + z) = %d\n", x / (y + z)); // x / (y + z) = 0
printf("x / y * z = %d\n", x / y * z); // x / y * z = 0
printf("(x + y) * z = %d\n", (x + y) * z); // (x + y) * z = 900
return 0;
}
Output:
Explanation
- In the first line of the program, the multiplication is done first, and then the addition.
- In the second line of the program, the multiplication is done first, and then the addition.
- In the third line of the program, the division is done first, and then the addition.
- In the fourth line of the program, the parentheses are used to change the order of evaluation, so the addition is done first, and then the division.
- In the fifth line of the program, the division is done first, and then the multiplication
- In the sixth line, the addition is done first, and then the multiplication.
Operator Associativity Example
Below program shows the Operator Associativity in C:
#include <stdio.h>
int main() {
int x = 10;
int y = 20;
int z = 30;
printf("x - y - z = %d\n", x - y - z); // x - y - z = -40
printf("x / y / z = %d\n", x / y / z); // x / y / z = 0
printf("x - (y - z) = %d\n", x - (y - z)); // x - (y - z) = 20
printf("(x / y) / z = %d\n", (x / y) / z); // (x / y) / z = 0
printf("x / (y / z) = %d\n", x / (y / z)); // x / (y / z) = 2
return 0;
}
Output:
Explanation
- In the first line of the program, the subtraction is done from left to right, so the value of
x
is subtracted from the value ofy
, and then the value ofz
is subtracted from the result. - In the second line of the program, the division is done from left to right, so the value of
x
is divided by the value ofy
, and then the result is divided by the value ofz
. - In the third line of the program, the parentheses are used to change the order of evaluation, so the subtraction is done first, and then the value of
x
is subtracted from the result. - In the fourth line of the program, the division inside the parenthesis is done first, and then the division outside the parenthesis is done.
- In the fifth line, the division inside the parenthesis is done first, and then the division outside the parenthesis is done.
Best Practices
Lastly, Below are some of the best practices when dealing with Operator Precedence and Associativity in your programming:
Use parentheses: Always use parentheses to indicate the intended order of evaluation, making your code easier to read and understand.
Default operator precedence and associativity: Always be aware of the default operator precedence and associativity of C programming language, and use them consistently throughout your code.
Whitespaces around operators: Use whitespaces around operators to make the code more readable and easy to understand.
Multiple operators with the same precedence: Avoid using multiple operators with the same precedence in the same line of code, as it can be confusing.
Thoroughly test your code: Thoroughly test your code with a variety of inputs and edge cases to ensure that it is robust and reliable.
Document complex expressions: Always document any non-standard or complex expressions in your code to help other developers understand the intended behavior. When in doubt, use parentheses to make the order of operations explicit.
Follow the conventions: Follow the conventions of the language, if any, to make the code easy to understand by other developers who might read it in the future.