C ProgrammingUnit 316 min read
Operators & Expressions: Types, Precedence, Bitwise & Conditional Logic
Unit 3 of C Programming covers operators (arithmetic, relational, logical, bitwise, conditional, assignment, and special operators like sizeof and ?:), their precedence/associativity, and how to construct valid expressions. It explains operator overloading (via implicit conversions), side effects, and practical applica
TAKEAWAYS:
- Operators in C are classified by utility (arithmetic, relational, logical, bitwise, etc.) and operand count (unary, binary, ternary).
- Precedence rules dictate evaluation order; parentheses override defaults.
- Bitwise operators (
&,|,^,~,<<,>>) manipulate individual bits for memory efficiency (e.g., flags, compression). - The conditional operator (
?:) is a shorthand forif-elsein expressions. - Side effects (e.g.,
i++in expressions) can lead to undefined behavior if misused. sizeofreturns the size in bytes of a variable or type, critical for dynamic memory allocation.
1. Introduction to Operators
Operators in C are symbols that perform operations on variables and values. They are the building blocks of expressions, which combine variables, operators, and literals to produce a result.
Classification of Operators
Operators are categorized based on their utility (function) and number of operands they require:
| Category | Operators | Example |
|---|---|---|
| Arithmetic | +, -, *, /, %, ++, -- |
a + b, x++ |
| Relational | ==, !=, >, <, >=, <= |
a > b |
| Logical | &&, ||, ! |
a && b |
| Bitwise | &, |, ^, ~, <<, >> |
a & b, x << 2 |
| Assignment | =, +=, -=, *=, /=, %=, <<=, >>=, &=, |=, ^= |
a += b |
| Conditional | ?: (ternary operator) |
a > b ? x : y |
| Special | sizeof, , (comma), & (address-of), * (dereference) |
sizeof(int), &var |
2. Arithmetic Operators
Arithmetic operators perform mathematical operations. They include:
- Binary operators:
+,-,*,/,%(modulus) - Unary operators:
++(increment),--(decrement)
Example: Modulus Operator (%)
The modulus operator returns the remainder of division.
#include <stdio.h>
int main() {
int a = 10, b = 3;
printf("Remainder: %d\n", a % b); // Output: 1
return 0;
}
Trace:
| Step | Operation | Result |
|---|---|---|
| 1 | 10 % 3 |
1 |
Real-world use in Nepal:
- Ncell’s call duration billing: If a call lasts 10 minutes and the rate is 3 minutes per unit, the extra charge is calculated as
10 % 3 = 1(extra minute). - NEPSE stock trading: If a trader buys 10 shares and sells 3, the remaining shares are
10 % 3 = 1.
3. Relational Operators
Relational operators compare two values and return 1 (true) or 0 (false).
| Operator | Meaning | Example (a=5, b=3) |
Result |
|---|---|---|---|
== |
Equal to | a == b |
0 |
!= |
Not equal | a != b |
1 |
> |
Greater than | a > b |
1 |
< |
Less than | a < b |
0 |
>= |
Greater/equal | a >= b |
1 |
<= |
Less/equal | a <= b |
0 |
Example: Checking Even/Odd
#include <stdio.h>
int main() {
int num = 7;
if (num % 2 == 0)
printf("Even\n");
else
printf("Odd\n"); // Output: Odd
return 0;
}
4. Logical Operators
Logical operators combine boolean expressions.
| Operator | Name | Example (a=1, b=0) |
Result |
|---|---|---|---|
&& |
Logical AND | a && b |
0 |
|| |
Logical OR | a || b |
1 |
! |
Logical NOT | !a |
0 |
Example: Multiple Conditions
#include <stdio.h>
int main() {
int age = 20, hasLicense = 1;
if (age >= 18 && hasLicense)
printf("Eligible to drive\n"); // Output: Eligible
return 0;
}
Real-world use in Nepal:
- eSewa’s transaction approval: A payment is processed only if:
balance >= amountANDaccount is active.- Logical AND (
&&) ensures both conditions are met.
5. Bitwise Operators
Bitwise operators manipulate individual bits of integers. They are faster than arithmetic operations and used in:
- Memory optimization (e.g., flags in structures).
- Cryptography (e.g., XOR operations).
- Graphics programming (e.g., pixel manipulation).
| Operator | Name | Example (a=5 (0101), b=3 (0011)) |
Result (Binary) | Result (Decimal) |
|---|---|---|---|---|
& |
Bitwise AND | a & b |
0001 |
1 |
| |
Bitwise OR | a | b |
0111 |
7 |
^ |
Bitwise XOR | a ^ b |
0110 |
6 |
~ |
Bitwise NOT | ~a |
1010 |
-6 (two’s complement) |
<< |
Left Shift | a << 1 |
1010 |
10 |
>> |
Right Shift | a >> 1 |
0010 |
2 |
Example: Setting a Flag
#include <stdio.h>
int main() {
int flags = 0b0000; // Binary literal (C99)
flags |= 0b0010; // Set the 2nd bit (value = 2)
printf("Flags: %d\n", flags); // Output: 2
return 0;
}
Trace:
| Step | Operation | Binary (flags) |
Decimal |
|---|---|---|---|
| 1 | flags = 0b0000 |
0000 |
0 |
| 2 | `flags | = 0b0010` | 0010 |
Real-world use in Nepal:
- Khalti’s transaction status: A transaction may have multiple flags (e.g.,
0b0001= pending,0b0010= failed). Using bitwise OR (|) updates the status:int status = 0b0001; // Pending status |= 0b0010; // Now: 0b0011 (Pending + Failed)
6. Assignment Operators
Assignment operators assign values to variables. The compound assignment operators (+=, -=, etc.) combine an operation with assignment.
| Operator | Example | Equivalent To |
|---|---|---|
= |
a = b |
a = b |
+= |
a += b |
a = a + b |
-= |
a -= b |
a = a - b |
*= |
a *= b |
a = a * b |
/= |
a /= b |
a = a / b |
%= |
a %= b |
a = a % b |
<<= |
a <<= b |
a = a << b |
>>= |
a >>= b |
a = a >> b |
&= |
a &= b |
a = a & b |
|= |
a |= b |
a = a | b |
^= |
a ^= b |
a = a ^ b |
Example: Compound Assignment
#include <stdio.h>
int main() {
int x = 5;
x += 3; // Equivalent to x = x + 3
printf("x = %d\n", x); // Output: 8
return 0;
}
7. Conditional (Ternary) Operator (?:)
The ternary operator is a shorthand for if-else in expressions.
Syntax:
condition ? expression1 : expression2;
Example: Maximum of Two Numbers
#include <stdio.h>
int main() {
int a = 10, b = 20;
int max = (a > b) ? a : b;
printf("Max: %d\n", max); // Output: 20
return 0;
}
Real-world use in Nepal:
- Pathao’s fare calculation: If
distance <= 2km, fare = 100 NPR; else, fare = 150 NPR.int fare = (distance <= 2) ? 100 : 150;
8. Special Operators
(a) sizeof Operator
Returns the size in bytes of a variable or data type.
#include <stdio.h>
int main() {
printf("Size of int: %zu bytes\n", sizeof(int)); // Typically 4
printf("Size of float: %zu bytes\n", sizeof(float)); // Typically 4
return 0;
}
Real-world use in Nepal:
- Bank loan calculations: If a bank stores 10,000 customer records, and each record is
sizeof(struct Customer) = 100 bytes, total memory needed is10,000 * 100 = 1,000,000 bytes.
(b) Comma Operator (,)
Evaluates expressions left to right and returns the last value.
#include <stdio.h>
int main() {
int a = (5, 10, 15); // Returns 15
printf("a = %d\n", a); // Output: 15
return 0;
}
9. Operator Precedence and Associativity
Operators have precedence (evaluation order) and associativity (left-to-right or right-to-left).
| Precedence (High to Low) | Operators | Associativity |
|---|---|---|
| 1 | (), [], ., -> |
Left to Right |
| 2 | !, ~, ++, --, sizeof, &, * |
Right to Left |
| 3 | *, /, % |
Left to Right |
| 4 | +, - |
Left to Right |
| 5 | <<, >> |
Left to Right |
| 6 | <, <=, >, >= |
Left to Right |
| 7 | ==, != |
Left to Right |
| 8 | & |
Left to Right |
| 9 | ^ |
Left to Right |
| 10 | | |
Left to Right |
| 11 | && |
Left to Right |
| 12 | || |
Left to Right |
| 13 | ?: (ternary) |
Right to Left |
| 14 | =, +=, -=, etc. |
Right to Left |
| 15 | , |
Left to Right |
Example: Precedence in Action
#include <stdio.h>
int main() {
int a = 5, b = 3, c = 2;
int result = a + b * c; // Multiplication first (6), then addition (11)
printf("Result: %d\n", result); // Output: 11
return 0;
}
Mermaid Diagram: Operator Precedence Flow
10. Side Effects and Undefined Behavior
- Side effects occur when an operator modifies a variable (e.g.,
i++inx = i++ + 1). - Undefined behavior happens when side effects interfere with evaluation order (e.g., modifying a variable twice in one expression).
Bad Example (Undefined Behavior):
int x = 5;
int y = x++ + ++x; // Undefined! (x is modified twice)
Correct Way:
int x = 5;
int y = x + 1; // Safe
x++;
11. Swapping Without a Temporary Variable
A common interview question: Swap two numbers without a third variable using arithmetic or bitwise operations.
Method 1: Arithmetic (Using + and -)
#include <stdio.h>
int main() {
int a = 5, b = 10;
printf("Before swap: a = %d, b = %d\n", a, b);
a = a + b; // 15
b = a - b; // 5
a = a - b; // 10
printf("After swap: a = %d, b = %d\n", a, b); // Output: 10, 5
return 0;
}
Trace:
| Step | Operation | a |
b |
|---|---|---|---|
| 1 | a = a + b |
15 | 10 |
| 2 | b = a - b |
15 | 5 |
| 3 | a = a - b |
10 | 5 |
Real-world use in Nepal:
- Daraz’s order processing: If two orders have IDs
5and10, swapping them without a temp variable avoids extra memory usage in high-throughput systems.
Method 2: Bitwise XOR (No Arithmetic Overflow)
#include <stdio.h>
int main() {
int a = 5, b = 10;
printf("Before swap: a = %d, b = %d\n", a, b);
a = a ^ b; // 15 (0101 ^ 1010 = 1111)
b = a ^ b; // 5 (1111 ^ 1010 = 0101)
a = a ^ b; // 10 (1111 ^ 0101 = 1010)
printf("After swap: a = %d, b = %d\n", a, b); // Output: 10, 5
return 0;
}
Trace:
| Step | Operation | a (Binary) |
b (Binary) |
|---|---|---|---|
| 1 | a = a ^ b |
1111 (15) |
1010 (10) |
| 2 | b = a ^ b |
1111 (15) |
0101 (5) |
| 3 | a = a ^ b |
1010 (10) |
0101 (5) |
12. Evaluating Complex Expressions
Problem: Calculate for , . Solution:
#include <stdio.h>
#include <math.h>
int main() {
int x = 3, y = 4;
double result = 5 * x * sqrt(y * y) + 5;
printf("Result: %.2f\n", result); // Output: 65.00
return 0;
}
Trace:
| Step | Operation | Value |
|---|---|---|
| 1 | y * y |
16 |
| 2 | sqrt(16) |
4.0 |
| 3 | 5 * x * 4.0 |
60.0 |
| 4 | 60.0 + 5 |
65.0 |
Real-world use in Nepal:
- NTC’s electricity billing: If a consumer uses units and the rate is (where is demand factor), the bill is calculated similarly.
In the Real World
Khalti’s Transaction Flags
- Idea Used: Bitwise operators (
&,|,^). - How? Khalti uses bitmasking to store multiple transaction states (e.g.,
0b0001= pending,0b0010= failed). A singleintcan represent multiple flags efficiently. - Example:
int status = 0b0001; // Pending status |= 0b0010; // Now: 0b0011 (Pending + Failed)
- Idea Used: Bitwise operators (
Ncell’s Call Duration Calculation
- Idea Used: Modulus operator (
%). - How? If a call lasts 10 minutes and billing is per 3-minute unit, the extra charge is
10 % 3 = 1minute. - Example:
int minutes = 10, unit = 3; int extra = minutes % unit; // 1
- Idea Used: Modulus operator (
Pathao’s Dynamic Fare Adjustment
- Idea Used: Ternary operator (
?:). - How? If
distance <= 2km, fare = 100 NPR; else, fare = 150 NPR. - Example:
int fare = (distance <= 2) ? 100 : 150;
- Idea Used: Ternary operator (
Bank Loan Interest Calculation
- Idea Used: Arithmetic operators (
*,/). - How? Simple interest is calculated as: where = principal, = rate, = time.
- Example:
float interest = (principal * rate * time) / 100;
- Idea Used: Arithmetic operators (
Exam Tip
Operator Precedence is Critical
- Always use parentheses to clarify intent. For example:
- Correct:
(a + b) * c - Ambiguous:
a + b * c(multiplication has higher precedence).
- Correct:
- Exam Pitfall: Forgetting precedence leads to wrong answers. Example:
int x = 2 + 3 * 4; // x = 14 (not 20)
- Always use parentheses to clarify intent. For example:
Bitwise Operators are High-Weightage
- Questions often ask for bitwise AND/OR/XOR operations or flag manipulation.
- Example Question:
"Given
a = 5(0101) andb = 3(0011), computea & b,a | b, anda ^ b."
Swapping Without Temp Variable
- A common 5-mark question. Know both arithmetic and bitwise methods.
- Exam Tip: Show binary traces for bitwise swapping to get full marks.
sizeofOperator- Often tested with structures or arrays. Example:
"Write a program to find the size of an array of 10 integers."
int arr[10]; printf("Size: %zu bytes\n", sizeof(arr)); // Typically 40 (10 * 4)
- Often tested with structures or arrays. Example:
"Write a program to find the size of an array of 10 integers."
Side Effects and Undefined Behavior
- Avoid modifying a variable twice in one expression (e.g.,
x = ++x + 1). - Exam Tip: If asked to explain undefined behavior, cite:
- Modifying a variable multiple times in one expression.
- Unsequenced modifications (e.g.,
i++andi--in the same statement).
- Avoid modifying a variable twice in one expression (e.g.,
Ternary Operator Shortcuts
- Replace
if-elsewith?:where possible. Example:// Instead of: if (x > y) max = x; else max = y; // Use: int max = (x > y) ? x : y;
- Replace
Real-World Applications
- Expect 1-2 questions linking operators to real-world scenarios (e.g., billing, flags, swapping).
- Example: "How would you use bitwise operators to optimize memory in a system storing user permissions?"
Based on the TU BCA syllabus for C Programming (CACS151), unit 3.
Discussion
Loading…