C ProgrammingUnit 215 min read
Data Types, Variables, Operators & Bitwise Logic in C
Unit 2 of C Programming covers fundamental building blocks: fundamental data types (integer, float, char), their ranges and storage sizes; variable declaration and scope (local vs. global); arithmetic, relational, logical, and bitwise operators with precedence/associativity rules; and practical applications like file m
TAKEAWAYS:
- Understand 8 fundamental data types (int, float, char, etc.) and their storage sizes/range limits (e.g.,
intis 2 bytes in TU’s 16-bit systems,floatuses 4 bytes for 7-digit precision). - Master variable scope rules: global variables persist program-wide but risk unintended side effects; local variables are safer but limited to blocks.
- Bitwise operators (
&,|,^,<<,>>) manipulate individual bits—critical for low-level tasks like Khalti’s transaction hashing or NTC’s network packet compression. - Operator precedence follows PEMDAS (Parentheses > Exponents > Multiplication > Division > Addition > Subtraction), but bitwise operators have higher priority than comparisons.
- Expressions combine operators and operands; associativity (left-to-right for
+, right-to-left for^) dictates evaluation order. - File handling (e.g., merging
num1.txtandnum2.txt) usesfopen(),fscanf(), andfprintf()—a core skill for eSewa’s payment logs or NEPSE’s stock data processing.
Core Concepts: Data Types and Storage
1. Fundamental Data Types in C
C provides 8 fundamental data types, each with a specific size (in bytes) and range of values. The ranges depend on the system’s word size (e.g., 16-bit vs. 32-bit). In TU’s context (often 16-bit systems), assume:
| Data Type | Size (bytes) | Range | Example Use Case |
|---|---|---|---|
int |
2 | to | Storing Ncell’s call duration (seconds) |
float |
4 | to | Calculating Daraz’s shipping cost (with 7-digit precision) |
char |
1 | to (signed) or to (unsigned) | Storing eSewa’s transaction status (e.g., 'S' for success) |
double |
8 | to | Financial calculations (e.g., bank interest rates) |
long |
4 | to | Large counters (e.g., Pathao’s ride IDs) |
short |
2 | Same as int (often) |
Compact storage (e.g., NTC’s meter readings) |
Why ranges matter:
- Overflow: Assigning
32768to anintcauses undefined behavior (wraps to ). - Precision:
floatloses precision for large numbers (e.g.,123456789.0becomes123456000.0). - Memory:
charis ideal for single characters (e.g., menu options in Khalti’s app).
2. Variable Declaration and Scope
Variables store data in memory. Their scope determines where they can be accessed:
- Local variables: Declared inside a block (e.g.,
if,for, function). Exist only while the block executes. - Global variables: Declared outside all functions. Accessible everywhere but risk side effects.
#include <stdio.h>
int global = 10; // Global variable
void example() {
int local = 20; // Local variable
printf("Global: %d, Local: %d\n", global, local);
}
int main() {
example();
// printf("%d", local); // ERROR: local is out of scope
return 0;
}
Output:
Global: 10, Local: 20
Advantages/Disadvantages of Global Variables:
| Advantages | Disadvantages |
|---|---|
| Accessible across functions | Can be modified unintentionally |
| Reduces need for parameter passing | Hard to debug (unpredictable state) |
Useful for constants (e.g., PI = 3.14) |
Encourages poor modular design |
Real-World Example:
- eSewa’s Transaction System:
- Global:
MAX_TRANSACTIONS = 1000(constant). - Local:
amount,user_idinsideprocess_payment()function.
- Global:
Operators: The Building Blocks of Logic
1. Arithmetic Operators
Perform mathematical operations. Precedence: * and / before + and -.
| Operator | Name | Example | Result |
|---|---|---|---|
+ |
Addition | 5 + 3 |
8 |
- |
Subtraction | 10 - 4 |
6 |
* |
Multiplication | 3 * 4 |
12 |
/ |
Division | 10 / 3 |
3 (integer division) |
% |
Modulus | 10 % 3 |
1 |
Example: Calculate Ncell’s billing for 5 minutes at Rs. 2/min.
int minutes = 5, rate = 2;
int cost = minutes * rate; // 10
printf("Bill: Rs. %d\n", cost);
2. Relational and Logical Operators
Used for conditional checks (e.g., if statements).
| Operator | Name | Example | Result (if a=5, b=3) |
|---|---|---|---|
== |
Equal to | a == b |
0 (false) |
!= |
Not equal to | a != b |
1 (true) |
> |
Greater than | a > b |
1 (true) |
< |
Less than | a < b |
0 (false) |
>= |
Greater or equal | a >= b |
1 (true) |
<= |
Less or equal | a <= b |
0 (false) |
&& |
Logical AND | (a > 2) && (b < 4) |
1 (true) |
|| |
Logical OR | (a > 10) || (b < 2) |
1 (true) |
! |
Logical NOT | !(a == b) |
1 (true) |
Example: Check if a Daraz order is eligible for free shipping (minimum Rs. 500).
int order_total = 450;
if (order_total >= 500) {
printf("Eligible for free shipping!\n");
} else {
printf("Shipping cost: Rs. 50\n");
}
3. Bitwise Operators
Manipulate individual bits of integers. Critical for low-level optimizations (e.g., Khalti’s encryption, NTC’s bandwidth compression).
| 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 (inverts all bits) |
(two’s complement) |
<< |
Left shift | a << 1 |
1010 |
10 (multiplies by 2) |
>> |
Right shift | a >> 1 |
0010 |
2 (divides by 2) |
Example: Toggle the least significant bit (LSB) of a number (used in Ncell’s call logging to mark "completed" calls).
int call_status = 0b0000; // 0 (not started)
call_status ^= 0b0001; // Toggle LSB: 0b0001 (1, started)
printf("Status: %d\n", call_status); // 1
Real-World Trace: eSewa’s Transaction Hashing
eSewa uses bitwise XOR (^) to combine transaction details (amount, user ID, timestamp) into a hash for security:
unsigned int hash = amount ^ user_id ^ timestamp;
- If
amount=500,user_id=12345,timestamp=1625097600:500 ^ 12345 = 12347(binary:0000110000001111111)12347 ^ 1625097600 = 1625097603(final hash).
4. Operator Precedence and Associativity
Precedence determines evaluation order. Associativity resolves ties (left-to-right for +, right-to-left for ^).
flowchart TD
A["Parentheses ()"] --> B["Postfix: a++, a--"]
B --> C["Unary: +, -, ~, !"]
C --> D["Multiplicative: *, /, %"]
D --> E["Additive: +, -"]
E --> F["Shift: <<, >>"]
F --> G["Relational: <, >, <=, >=, ==, !="]
G --> H["Bitwise AND: &"]
H --> I["Bitwise XOR: ^"]
I --> J["Bitwise OR: |"]
J --> K["Logical AND: &&"]
K --> L["Logical OR: ||"]
L --> M["Ternary: condition ? expr1 : expr2"]
M --> N["Assignment: =, +=, etc."]Example: Evaluate 5 + 3 * 2 >> 1:
3 * 2 = 6(multiplication first).5 + 6 = 11.11 >> 1 = 5(right shift by 1 divides by 2).
Practical Applications: Files and Number Analysis
1. Merging Two Files (eSewa-Style Transaction Logs)
Task: Merge num1.txt and num2.txt into file3.txt.
Assumptions:
- Both files contain integers, one per line.
num1.txt:10 20num2.txt:15 25
Solution:
#include <stdio.h>
int main() {
FILE *file1 = fopen("num1.txt", "r");
FILE *file2 = fopen("num2.txt", "r");
FILE *file3 = fopen("file3.txt", "w");
int num;
// Read from file1
while (fscanf(file1, "%d", &num) != EOF) {
fprintf(file3, "%d\n", num);
}
// Read from file2
while (fscanf(file2, "%d", &num) != EOF) {
fprintf(file3, "%d\n", num);
}
fclose(file1);
fclose(file2);
fclose(file3);
return 0;
}
Output (file3.txt):
10
20
15
25
Real-World Tie-In:
- eSewa’s Daily Transaction Logs:
num1.txt= Transactions from morning (9 AM–12 PM).num2.txt= Transactions from afternoon (12 PM–5 PM).file3.txt= Combined log for auditing.
2. Palindrome Check (Ncell’s Call Duration Validation)
Task: Check if a number reads the same backward (e.g., 121).
Approach:
- Reverse the number.
- Compare with original.
#include <stdio.h>
int is_palindrome(int num) {
int original = num, reversed = 0;
while (num > 0) {
reversed = reversed * 10 + num % 10;
num /= 10;
}
return original == reversed;
}
int main() {
int n = 121;
if (is_palindrome(n)) {
printf("%d is a palindrome.\n", n);
} else {
printf("%d is not a palindrome.\n", n);
}
return 0;
}
Trace for n = 121:
| Step | num |
reversed |
num % 10 |
num /= 10 |
reversed * 10 + ... |
|---|---|---|---|---|---|
| 1 | 121 | 0 | 1 | 12 | 0 * 10 + 1 = 1 |
| 2 | 12 | 1 | 2 | 1 | 1 * 10 + 2 = 12 |
| 3 | 1 | 12 | 1 | 0 | 12 * 10 + 1 = 121 |
Output:
121 is a palindrome.
Real-World Tie-In:
- Ncell’s Call Duration Validation:
- Some promotional codes (e.g.,
12321) are palindromes. - The program checks if a user-entered code is valid before applying discounts.
- Some promotional codes (e.g.,
In the Real World
Khalti’s Transaction Security:
- Bitwise XOR (
^) combines amount, user ID, and timestamp to generate a hash for fraud detection. - Example: For a Rs. 500 transaction by user
12345at1625097600:unsigned int hash = 500 ^ 12345 ^ 1625097600; // Result: 1625097603 (used to verify transaction integrity)
- Bitwise XOR (
NTC’s Bandwidth Compression:
- Bitwise AND (
&) masks irrelevant bits in network packets to reduce size. - Example: Strip the LSB (least significant bit) of a packet’s header:
unsigned char packet_header = 0b11010011; unsigned char compressed = packet_header & 0b11111110; // 0b11010010
- Bitwise AND (
Daraz’s Shipping Eligibility:
- Relational operators (
>=) check if an order meets the Rs. 500 threshold for free shipping. - Example:
int cart_total = 480; if (cart_total >= 500) { printf("Free shipping!\n"); } else { printf("Add Rs. 20 for shipping.\n"); }
- Relational operators (
NEPSE’s Stock Data Processing:
- File handling (
fopen,fscanf) reads daily stock prices fromstock_data.txtand filters gainers (price > previous day). - Example:
FILE *data = fopen("stock_data.txt", "r"); float prev_price, current_price; fscanf(data, "%f", &prev_price); // Read yesterday's price while (fscanf(data, "%f", ¤t_price) != EOF) { if (current_price > prev_price) { printf("Gainer: %.2f\n", current_price); } prev_price = current_price; }
- File handling (
Exam Tip
Memorize Ranges:
- TU exams often ask for
int,float, andcharranges. For 16-bit systems:int: to .float: to .
- Trick: Remember
intmax is .
- TU exams often ask for
Bitwise Operator Shortcuts:
a << 1=a * 2.a >> 1=a / 2(integer division).a & 1checks ifais odd (returns1if odd,0if even).
File Handling Pitfalls:
- Always check if
fopen()returnsNULL(file not found). - Close files with
fclose()to avoid memory leaks. - Common Exam Question: Merge two files. Always use
while (fscanf(...) != EOF)to read all data.
- Always check if
Operator Precedence Traps:
5 + 3 * 2is11(not16), because*has higher precedence.- Use parentheses to clarify intent:
(5 + 3) * 2 = 16.
Global vs. Local Variables:
- Global: Use for constants (e.g.,
const float PI = 3.14;). - Local: Prefer for variables to avoid side effects.
- Exam Question: "Why avoid global variables?" → Answer: unpredictable state, hard to debug.
- Global: Use for constants (e.g.,
Palindrome/Prime Checks:
- Palindrome: Reverse the number and compare.
- Prime: Check divisibility up to .
- Example Trace: Always show a table of variable changes (like the
121trace above).
Summary Table: Key Operators and Their Uses
| Category | Operators | Example Use Case | Precedence Level |
|---|---|---|---|
| Arithmetic | +, -, *, /, % |
Calculating Daraz’s shipping cost | High |
| Relational | ==, !=, >, <, etc. |
Checking Ncell’s call duration | Medium |
| Logical | &&, ||, ! |
Validating eSewa’s transaction conditions | Low |
| Bitwise | &, |, ^, ~, <<, >> |
Khalti’s encryption, NTC’s compression | Highest |
| Assignment | =, +=, -= |
Updating Pathao’s ride counter | Lowest |
Final Worked Example: Bank Loan Interest Calculation
Task: Calculate monthly interest for a loan using the formula: where:
- = Principal (Rs. 100,000),
- = Annual rate (5% = 0.05),
- = Time in years (1).
Solution:
#include <stdio.h>
int main() {
float principal = 100000.0;
float rate = 0.05; // 5%
float time = 1.0; // 1 year
float interest = principal * rate * time;
printf("Monthly interest: Rs. %.2f\n", interest / 12);
return 0;
}
Output:
Monthly interest: Rs. 416.67
Real-World Tie-In:
- Nabil Bank’s Loan Calculator:
- Uses
floatfor precision (avoids integer truncation). - Bitwise operations could optimize interest table generation for bulk loans.
- Uses
Visual Summary
classDiagram
class DataType {
+size: int
+range: String
+example: String
}
class Variable {
+scope: String (local/global)
+lifetime: String
}
class Operator {
+type: String (arithmetic/relational/bitwise)
+precedence: int
}
DataType "1" --> "uses" Operator : "e.g., int for counters"
Variable "1" --> "uses" Operator : "e.g., if (x > 0)"
Operator "1" --> "applied to" DataType : "e.g., & on int"Based on the TU BIT syllabus for C Programming (BIT102), unit 2.
Discussion
Loading…