Understanding both is essential—not just to write correct programs, but to write readable, efficient, and maintainable code, especially in systems programming, embedded development, and high-performance applications.
Operators in C and C++
In C and C++, operators are special symbols that instruct the compiler to perform specific operations on one or more operands (values or variables).
Operators are commonly classified in two ways:
- By arity – how many operands they require
- _Unary_ (one operand)
- _Binary_ (two operands)
- _Ternary_ (three operands)
- By purpose – arithmetic, logical, bitwise, assignment, etc.
Let’s explore them category by category.
Arithmetic Operators
Arithmetic operators perform basic mathematical operations. They are among the most frequently used operators in any program.
Unary Arithmetic Operators
Unary operators act on a single operand.
+: Unary plus (rarely used explicitly)-: Unary minus (sign inversion)++: Increment--: Decrement
int a = 1;
// Prefix increment
int b = ++a; // a = 2, b = 2
// Postfix increment
b = a++; // a = 3, b = 2
Prefix vs Postfix Increment (Important Detail)
**Pre-increment (`++i`) is generally more efficient than post-increment (`i++`)**, especially for complex types (like iterators or user-defined classes).
Why? (Temp memory avoided)
i++must create a temporary copy of the original value before incrementing.++iincrements directly and returns the updated value.
For primitive types, the difference is often optimized away, but for iterators and objects, prefer prefix increment unless you explicitly need the old value.
Binary Arithmetic Operators
Binary arithmetic operators work on two operands.
+: Addition-: Subtraction*: Multiplication/: Division%: Modulus (remainder, integers only)
int x = 10;
int y = 3;
int sum = x + y; // 13
int div = x / y; // 3 (integer division!)
int mod = x % y; // 1
**Integer division truncates toward zero**, which is a common source of bugs.
Comparison (Relational) Operators
Comparison operators compare two values and always produce 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
int a = 5;
int b = 10;
bool result = (a < b); // true
These operators are the backbone of decision making and looping constructs.
Logical Operators
Logical operators combine or invert boolean expressions.
&&: Logical AND||: Logical OR!: Logical NOT
if (x > 0 && y > 0) {
// both conditions must be true
}
Short-Circuit Evaluation
C and C++ use short-circuit evaluation:
A && B→ ifAis false,Bis never evaluatedA || B→ ifAis true,Bis never evaluated
This behavior is frequently used for safety checks (e.g., null-pointer validation).
Bitwise Operators
Bitwise operators operate directly on the binary representation of integers. They are heavily used in embedded systems, drivers, and performance-critical code.
&: Bitwise AND|: Bitwise OR^: Bitwise XOR~: Bitwise NOT<<: Left shift (often equivalent to multiply by 2ⁿ)>>: Right shift (often equivalent to divide by 2ⁿ)
unsigned int flags = 0b0010;
flags |= 0b0100; // set a bit
flags &= ~0b0010; // clear a bit
Shifts on signed integers can be implementation-defined, prefer unsigned types.
Assignment Operators
Assignment operators store values into variables.
Simple Assignment
=: Assign value
int x = 10;
Compound Assignment Operators
Compound operators combine an operation with assignment.
+=,-=,*=,/=,%=&=,|=,^=<<=,>>=
int x = 5;
x += 3; // x = 8
x <<= 1; // x = 16
These operators improve clarity and reduce repetition.
Preprocessor Operators
Used inside macros during preprocessing (before compilation).
#: Stringizing operator##: Token-pasting operator
#define TO_STRING(x) #x
#define CONCAT(a,b) a##b
These are powerful but should be used carefully due to readability and debugging complexity.
Operator Precedence
Operator precedence determines how expressions are grouped when parentheses are not explicitly used.
| Operator Type | Operators |
|---|---|
| Parentheses | () |
| Unary | +, -, !, ~, ++, -- |
| Multiplication / Division | *, /, % |
| Addition / Subtraction | +, - |
| Bitwise Shifts | <<, >> |
| Bitwise AND / XOR / OR | &, ^, ` |
| Comparison | <, <=, >, >= |
| Equality | ==, != |
| Logical AND / OR | &&, ` |
| Ternary | ?: |
| Assignment | =, +=, -=, etc. |
Best practice: use parentheses to make intent explicit, even if precedence is known.
Flow Control in C and C++
By default, C and C++ programs execute sequentially, from top to bottom, starting in main().
Flow-control constructs allow you to branch, repeat, and alter execution paths based on conditions.
These mechanisms form the _decision-making logic_ of your program.
Conditional Execution
`if`, `else if`, `else`
int x = 7;
if (x > 10) {
printf("x is greater than 10\n");
} else if (x > 5) {
printf("x is greater than 5 but less than or equal to 10\n");
} else {
printf("x is 5 or less\n");
}
Conditions must be enclosed in parentheses and evaluate to a boolean expression.
Ternary Operator (`?:`)
A compact alternative to simple if-else statements.
int a = 10;
int b = 20;
int max = (a > b) ? a : b;
Nested ternary expressions are possible but should be used with caution for readability:
int max = (x > y) ? ((x > z) ? x : z) : ((y > z) ? y : z);
`switch` Statement
Used for multi-branch selection based on integral or enum values.
int in = 0;
switch (in) {
case 0:
printf("Zero");
break;
case 1:
printf("One");
break;
default:
printf("Unknown");
}
Always include break unless intentional fall-through is desired.
Looping Constructs
`while` Loop
Repeats as long as the condition remains true.
while (keepgoing) {
if (answer == 0) {
break;
}
continue;
}
`do-while` Loop
Guarantees at least one execution.
int i = 0;
do {
printf("i = %d\n", i);
i++;
} while (i < 5);
`for` Loop
Traditional counted loop with three components:
- Initialization
- Condition
- Increment
for (int loop = 0; loop < 10; loop++) {
// ...
}
Range-Based `for` Loop (C++11)
Ideal for containers and arrays.
int arr[] = {1, 2, 3, 4};
for (int x : arr) {
cout << x;
}
Jump Statements
Jump statements abruptly alter execution flow.
`break`
Exits loops or switch.
`continue`
Skips to the next iteration.
`goto` (Discouraged)
goto label;
While legal, goto often leads to unmaintainable code and should be avoided in modern C++.
Exception Handling (C++ Only)
C++ provides structured error handling using try, catch, and throw.
try {
if (x < 0) {
throw std::invalid_argument("Negative value not allowed");
}
} catch (const std::exception& e) {
std::cerr << e.what();
}
This mechanism separates error handling from normal logic, improving robustness.
`return` Statement
Terminates a function and optionally returns a value.
int add(int a, int b) {
return a + b;
}
In main(), returning 0 typically indicates successful program termination.
Final Thoughts
Operators define what your program computes.
Flow control defines how and when it executes.
Mastering both is foundational to:
- Writing correct logic
- Avoiding subtle bugs
- Understanding performance and execution flow
- Progressing toward advanced C++ topics (RAII, templates, concurrency)
This knowledge forms the backbone of every serious C and C++ codebase.