Operators Precedence and Associativity

Basic Terms

1️⃣ Operands

Operands are the value or entities that participate in an operation. Or we can say that operands are the inputs on which an operator acts. These can be variables, constants, or expressions that evaluate to a value.

int a = 5;        // 'a' is an operand
float b = 2.5;    // 'b' is an operand
int result = a + 3;  // 'a' and '3' are operands in the addition operation

2️⃣ Operators

Operators are symbols that specify the type of computation or manipulation to perform on operands. Operators can be unary (operate on one operand), binary (operate on two operands), or ternary (operate on three operands).

int sum = a + b;   // '+' is the addition operator
float product = a * b;  // '*' is the multiplication operator
bool isEqual = (a == 5);  // '==' is the equality comparison operator

3️⃣ Operation:

An operation refers to the action or computation performed by an operator on one or more operands. It produces a result based on the specified operation and the values of the operands.

int sum = a + b;   // Addition operation
float product = a * b;  // Multiplication operation
bool isEqual = (a == 5);  // Equality comparison operation

Categories of Operators:

1️⃣ Arithmetic Operators:

These operators are used to perform basic mathematical operations.

  • Addition (+)
  • Subtraction (-)
  • Multiplication (*)
  • Division (/)
  • Modulus (%): Remainder of a division

 

  • These can be classified into two types: Unary Operators and Binary Operators.
int result = a + b; // Addition

Unary Operators = Operate or work with a single operand. For example, Increment (++) and Decrement (--) operators.

Binary Operators = Operate or work with two operands. For example, Addition (+), Subtraction (-), etc.

Increment (++) and Decrement (--) = These operators change the value of an operand by 1. These include only one operand.

When we use the pre-fix operator, it adds 1 to the operand and assigns the result to the variable on the left. On the other hand, when the operator is used as a post-fix, it first assigns a value to the left variable and then increases the operand by 1.

OperatorDescription
++It is used to increase the integer value by 1.
--This operator is used to decrease the integer value by 1.

Prefix, Postfix Example:

#include <iostream>
using namespace std;

int main() {
  int x = 10; // x is 10
  int y = ++x; // y is 11, x is 11
  int z = x++; // z is 11, x is 12
  cout << "x = " << x << endl; // x is 12
  cout << "y = " << y << endl; // y is 11
  cout << "z = " << z << endl; // z is 11
  return 0;
}

2️⃣ Relational (Comparison) Operators:

These operators compare two operands, determine relationships between them and return a boolean result (true or false).

  • Equal to (==)
  • Not equal to (!=)
  • Greater than (>)
  • Less than (<)
  • Greater than or equal to (>=)
  • Less than or equal to (<=)
bool isEqual = (a == b);  // Equality comparison
Operator Description
==This operator is used to check if the values of the two operands are equal. If their values are equal, then the condition becomes true.
!=It checks if the two operands are equal or not. The condition is true if the values are not equal.
>It checks if the value of the left operand is greater than the value of right operand. If the left operand is greater, the condition becomes true.
<It checks if the value of the left operand is less than the value of the right one. If the left operand is smaller, the condition becomes true.
>=Checks if the left operand is greater than or equal to the right operand. If the value of the left operand is greater than or equal to the right operand, the condition becomes true.
<=Checks if the left operand is less than or equal to the right operand. If left operand’s value is less than or equal to the right one, the condition becomes true.

3️⃣ Logical Operators:

  • Combine multiple conditions and return Boolean results (AND, OR, NOT).
  • Combines two or more relational expressions and return a Boolean value.
  • It include  && (logical AND), ||(logical OR), !(logical NOT).
bool condition = (a > 0 && b < 10);  // Logical AND
OperatorDescription
&&It is called the AND operator and performs logical conjunction of two given expressions. If both expressions are checked true, the result is true. However, if even one of the two expressions evaluates to be false, the result is also false.
||It is known as OR operator, which performs a logical disjunction on two given expressions. If one or both expressions evaluate to be true, the result is true.
!It is the Logical NOT Operator that is used to reverse the logical state of the operand. If a condition is true, the Logical NOT operator will reverse it and make it false and vice versa.

4️⃣ Bitwise Operators:

These operators perform operations on individual bits of integer types.

  • Bitwise AND (&)
  • Bitwise OR (|)
  • Bitwise XOR (^): Exclusive OR.
  • Bitwise NOT (~)
  • Left Shift (<<): Shift bits to the left.
  • Right Shift (>>): Shift bits to the right
int result = a & b;   // Bitwise AND
OperatorDescription
& (Binary AND Operator)It takes the binary values of both the left and right operands and performs the logical AND operation over them on the bit level, i.e. if both the operands have 1 on the specified position then the result will also have 1 in the corresponding position or else there will be 0.
| (Binary OR Operator)The bitwise OR operator is much similar to the bitwise AND, the only difference is that the bitwise OR operator performs logical OR instead of logical AND on the bit level, i.e. if at least any one of the operands have 1, then the result will also have 1 in the corresponding position, and 0 if they both have 0 in the corresponding position.
^ (Binary XOR Operator)If both the operands have the same value, the the result would be 0 otherwise 1.
~ (One's Complement Operator)It is a unary operator that has the effect of 'flipping' bits. This is the only bitwise operator that requires only one operand. All other bitwise operators require 2 operators. It does one's complement of a number is obtained by changing all the 0's in its binary value to 1's and by changing the 1's to 0's.
<< (Left Shift Operator)It moves the value of the right operand to the left by the number of bits specified by the right operand.
>> (Right Shift Operator)It moves the value of the left operands to the right by the number of bits mentioned by the right operand.

5️⃣ Assignment Operators:

These operators are used to assign values to variables. Compound assignment operators perform an operation and assignment in one step.

  • Assignment (=)
  • Add and assign (+=)
  • Subtract and assign (-=)
  • Multiply and assign (*=)
  • Divide and assign (/=)
  • Modulus and assign (%=)
  • Bitwise AND and assign (&=)
  • Bitwise OR and assign (|=)
  • Bitwise XOR and assign (^=)
  • Left Shift and assign (<<=)
  • Right Shift and assign (>>=)
a += b;   // Addition assignment
OperatorDescription
 = (Assigns)Assigns values from the right side operands to the left side operand.
+= (Add then assign)Adds the value of the right operand to the left operand and assigns it the result
-= (Add then assign)Subtracts the value of the right operand from the left operand and assigns it the result.
*= (Multiply then assign)Multiplies the value of the right operand with the left and assigns the result to the left one.
/= (Divide then assign)Divides the value of the left operand with the right and assigns the result to the left one.
%= (Modulus then assign)Takes modulus using the values of left and right operands and assigns the result to the left one.
<<= (Left shift and assign)Left shift AND assignment operator.
>>= (Right shift and assign)Right shift AND assignment operator.
&= (Bitwise AND assign)Bitwise AND assignment operator.
^= (Bitwise exclusive OR and assign)Bitwise exclusive OR and assignment operator.
|= (Bitwise inclusive OR and assign)Bitwise inclusive OR and assignment operator.

6️⃣ Increment and Decrement Operators:

These operators increase or decrease the value of a variable by 1.

  • Increment (++)
  • Decrement (--)
  • Prefix (++x, --x): Changes the value before using it in an expression.
  • Postfix (x++, x--): Uses the value in the expression, then changes it.
int a = 10;
int b = ++a;  // b = 11, a = 11 (prefix)
int c = a--;  // c = 11, a = 10 (postfix)

7️⃣ Ternary (Conditional) Operator:

Conditional or Ternary Operator (? :):

  • Syntax: condition ? expression_if_true : expression_if_false;
  • It's a shorthand for an if-else statement.
  • Evaluates the condition; if true, returns the value of expression_if_true, otherwise returns the value of expression_if_false.
condition ? expression_if_true : expression_if_false;
int a = 10, b = 5;
int max = (a > b) ? a : b;  // max = 10

8️⃣ Pointer Operators:

Pointer Operators (& and *): The address-of operator (&) returns the memory address of a variable, while the dereference operator (*) is used to access the value at a given memory address through a pointer.

  • Address-of (&): Returns the memory address of a variable.
    • Used to get the address of a variable.
  • Dereference (*): Accesses the value stored at a pointer’s address
    • Used for pointer declaration and dereferencing.
int a = 10;
int *p = &a;  // p holds the address of a
int b = *p;   // b = 10, dereferencing p

9️⃣ Special Operators:

sizeof Operator: The sizeof operator is used to determine the size, in bytes, of a data type or a variable. It is often used in dynamic memory allocation and working with arrays.

  • Returns the size, in bytes, of a type or an object.
  • Useful for memory allocation and manipulation.
int sizeOfInt = sizeof(int);
int array[5];
int sizeOfArray = sizeof(array);

Comma Operator (,): The comma operator allows multiple expressions to be grouped together, and allows them from left to right. The result of the entire expression is the value of the rightmost expression.

  • Evaluates multiple expressions by commas.
  • Returns the value of the last expression.
int a = 5, b = 10, c = 15;
int result = (a += b, b += c, c += a);
// The result is the value of c after all the expressions are evaluated.

Scope  Resolution Operator (::):

  • Used to access global or class scope.
int globalVar = 5;

class MyClass {
public:
    int classVar;
    void myFunction();
};

void MyClass::myFunction() {
    classVar = ::globalVar; // Using the scope resolution operator to access the global variable
}

Member Access Operator (. and ->):

  • . is used to access members of an object.
  • -> is used to access members through a pointer.
struct Point {
    int x;
    int y;
};

Point p;
p.x = 5; // Using the dot operator
Point* ptr = &p;
ptr->y = 10; // Using the arrow operator

Type Cast Operator:

This operator is used to convert one data type to another.

  • Syntax: (type)
int a = 10;
double b = (double)a / 3;  // Cast a to double before division

Operator Precedence and Associativity

Operator Precedence

Definition: Precedence defines the priority of operators in expressions. Operators with higher precedence are evaluated before those with lower precedence.

int result = 2 + 3 * 4;  // result = 14

In this case, the multiplication (*) has higher precedence than addition (+), so 3 * 4 is evaluated first, followed by 2 + 12.

Associativity

  • Definition: Associativity defines the direction in which operators of the same precedence are evaluated (left-to-right or right-to-left).
  • Left-to-Right Associativity: Operators are evaluated from left to right.
  • Right-to-Left Associativity: Operators are evaluated from right to left.
int a = 10, b = 5, c = 3;
int result = a - b - c;  // result = (a - b) - c = (10 - 5) - 3 = 2

Subtraction has left-to-right associativity, so a - b is evaluated first.

Operator Precedence and Associativity Table

Below is a table of operators arranged by precedence from highest to lowest. Operators with the same precedence are grouped, and the associativity indicates the direction in which expressions are evaluated.

PrecedenceOperatorAssociativityCategory
1 (Highest)()[]->.Left-to-RightFunction call, array, member access
 ++-- (postfix)Left-to-RightPost-increment, post-decrement
2++-- (prefix) +-!~Right-to-LeftUnary increment, decrement, logical NOT, bitwise NOT, unary plus and minus
 * (dereference) & (address-of)Right-to-LeftPointer dereference, address-of
 (type) (cast) sizeofRight-to-LeftType cast, size of
 newdeleteRight-to-LeftDynamic memory allocation
3*/%Left-to-RightMultiplication, division, modulus
4+-Left-to-RightAddition, subtraction
5<<>>Left-to-RightBitwise left shift, right shift
6<<=>>=Left-to-RightRelational less than, greater than
7==!=Left-to-RightEquality, inequality
8&Left-to-RightBitwise AND
9^Left-to-RightBitwise XOR
10|Left-to-RightBitwise OR
11&&Left-to-RightLogical AND
12||Left-to-RightLogical OR
13?:Right-to-LeftTernary conditional
14=+=-=*=/=%=<<=>>=&=^=|=Right-to-LeftAssignment and compound assignment
15 (Lowest),Left-to-RightComma operator