Programming In CUnit 1415 min read
Practical C Programming: Problem Solving & Applications
Unit 14 of Programming In C bridges theory to real-world problem-solving, covering algorithm design, debugging, and practical applications like file handling, dynamic memory, and modular programming—essential for exams and industry projects.
TAKEAWAYS:
- Learn to translate real-world problems into structured C programs using loops, arrays, and functions.
- Master debugging techniques (logical errors, syntax, runtime) and testing strategies (unit testing, edge cases).
- Understand modular design (header files, scope rules) to build scalable programs.
- Apply file handling and dynamic memory to solve problems like data storage and memory-efficient operations.
- Compare algorithmic approaches (e.g., sorting, searching) for efficiency in exams and projects.
- Use practical examples (e.g., bank transactions, inventory systems) to reinforce concepts.
1. Problem-Solving Methodology in C
Step-by-Step Approach
Every problem requires a structured approach. Here’s how to break it down:
Understand the Problem
- Read carefully. Identify inputs, outputs, and constraints.
- Example: "Design a program to calculate the total bill for a restaurant, including a 13% VAT and a 10% service charge if the bill exceeds Rs. 1000."
Plan the Algorithm
- Use pseudocode or flowcharts to outline steps.
- Example pseudocode for the restaurant bill:
1. Input: bill_amount 2. If bill_amount > 1000: service_charge = 10% of bill_amount 3. vat = 13% of (bill_amount + service_charge) 4. total = bill_amount + service_charge + vat 5. Output: total
Design the Program Structure
- Decide on functions, loops, and data structures.
- Example: Use a function
calculate_total()to encapsulate the logic.
Write the Code
- Translate pseudocode into C, ensuring correctness.
Test and Debug
- Test with edge cases (e.g., bill = Rs. 0, Rs. 1000, Rs. 2000).
- Debug using
printf()for intermediate values.
Worked Example: Restaurant Bill Calculator
Code Implementation
#include <stdio.h>
float calculate_total(float bill_amount) {
float service_charge = 0, vat, total;
if (bill_amount > 1000) {
service_charge = 0.10 * bill_amount;
}
vat = 0.13 * (bill_amount + service_charge);
total = bill_amount + service_charge + vat;
return total;
}
int main() {
float bill;
printf("Enter bill amount: ");
scanf("%f", &bill);
printf("Total bill: Rs. %.2f\n", calculate_total(bill));
return 0;
}
Trace Table for calculate_total(1500)
| Step | service_charge |
vat |
total |
|---|---|---|---|
| 1. Input: 1500 | 0 | 0 | 0 |
2. if condition |
150 (10% of 1500) | 0 | 0 |
| 3. Calculate VAT | 150 | 239 (13% of 1750) | 0 |
| 4. Calculate total | 150 | 239 | 1889 (1500+150+239) |
2. Debugging and Testing
Common Types of Errors
| Error Type | Description | Example | How to Fix |
|---|---|---|---|
| Syntax Error | Violates C grammar rules. | Missing ; or } |
Compiler flags the line. |
| Logical Error | Program runs but gives wrong output. | Incorrect formula in calculate_total() |
Test with known inputs. |
| Runtime Error | Crashes during execution. | Division by zero. | Add checks (e.g., if (denominator != 0)). |
Debugging Techniques
Print Debugging Add
printf()statements to track variable values. Example:printf("Bill: %.2f, Service: %.2f\n", bill_amount, service_charge);Use a Debugger (GDB)
- Set breakpoints to pause execution.
- Step through code line by line.
Unit Testing Test individual functions with known inputs/outputs. Example for
calculate_total():Input ( bill_amount)Expected Output Actual Output Pass/Fail 500 565 565 Pass 1000 1130 1130 Pass 2000 2466 2466 Pass
3. Practical Applications
In the Real World
eSewa (Nepal)
- Idea Used: File Handling and Dynamic Memory
- How? eSewa stores transaction records in files (e.g.,
transactions.dat). When a user pays a bill, the program:- Reads the existing file.
- Dynamically allocates memory for a new transaction struct.
- Appends the transaction to the file.
- Frees memory to avoid leaks.
Khalti (Nepal)
- Idea Used: Modular Programming (Functions) and Debugging
- How? Khalti’s backend uses functions to:
- Validate user input (e.g.,
is_valid_amount()). - Process payments (
process_payment()). - Log errors (e.g., insufficient balance) for debugging.
- Validate user input (e.g.,
Bank Loan Calculations
- Idea Used: Loops and Algorithms
- How? A bank calculates monthly EMI (Equated Monthly Installment) using the formula:
where:
- = Principal loan amount,
- = Monthly interest rate,
- = Number of payments.
- C Implementation:
#include <stdio.h> #include <math.h> float calculate_emi(float principal, float annual_rate, int years) { float r = annual_rate / 12 / 100; // Monthly rate int n = years * 12; // Total payments return principal * r * pow(1 + r, n) / (pow(1 + r, n) - 1); } int main() { printf("EMI for Rs. 5,00,000 at 8%% for 5 years: Rs. %.2f\n", calculate_emi(500000, 8, 5)); return 0; } - Trace for
calculate_emi(500000, 8, 5):Variable Value r0.0066667 (8%/12) n60 (5 years * 12) pow(1 + r, n)~1.4859 (approx.) EMI ~9,802.65
4. File Handling in Practical Scenarios
Example: Student Gradebook
Problem: Store student grades in a file and calculate the average.
Steps:
- Create a File
Use
fopen()to create/write togrades.txt. - Write Data Append grades dynamically.
- Read and Calculate Average Read all grades, sum them, and compute the average.
Code
#include <stdio.h>
int main() {
FILE *file = fopen("grades.txt", "a+");
if (file == NULL) {
printf("Error opening file!\n");
return 1;
}
// Write grades (example)
fprintf(file, "85\n72\n90\n");
// Reset file pointer to start
rewind(file);
// Read and calculate average
int grade, sum = 0, count = 0;
while (fscanf(file, "%d", &grade) != EOF) {
sum += grade;
count++;
}
printf("Average grade: %.2f\n", (float)sum / count);
fclose(file);
return 0;
}
File State After Execution
grades.txt:
85
72
90
Output:
Average grade: 82.33
5. Dynamic Memory Management
Example: Inventory System for Daraz
Problem: Store product names and quantities dynamically (no fixed size).
Approach:
- Use
structto represent a product. - Dynamically allocate an array of products.
- Free memory when done.
Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Product {
char name[50];
int quantity;
};
int main() {
int n;
printf("Enter number of products: ");
scanf("%d", &n);
// Dynamically allocate memory
struct Product *inventory = (struct Product*)malloc(n * sizeof(struct Product));
if (inventory == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Input products
for (int i = 0; i < n; i++) {
printf("Enter product %d name and quantity: ", i + 1);
scanf("%s %d", inventory[i].name, &inventory[i].quantity);
}
// Display inventory
printf("\nInventory:\n");
for (int i = 0; i < n; i++) {
printf("%s: %d\n", inventory[i].name, inventory[i].quantity);
}
// Free memory
free(inventory);
return 0;
}
Memory State After Allocation
inventory (pointer) --> [Product 1] --> [Product 2] --> ... --> [Product n]
Example Output:
Enter number of products: 2
Enter product 1 name and quantity: Laptop 10
Enter product 2 name and quantity: Phone 25
Inventory:
Laptop: 10
Phone: 25
6. Modular Programming with Header Files
Example: Library Management System
Problem: Separate functions into header files for reusability.
Structure:
library.h(Header File)#ifndef LIBRARY_H #define LIBRARY_H void add_book(char title[], int id); void display_books(); #endiflibrary.c(Implementation)#include <stdio.h> #include "library.h" void add_book(char title[], int id) { FILE *file = fopen("books.txt", "a"); fprintf(file, "%s,%d\n", title, id); fclose(file); } void display_books() { FILE *file = fopen("books.txt", "r"); char line[100]; while (fgets(line, sizeof(line), file)) { printf("%s", line); } fclose(file); }main.c(Usage)#include <stdio.h> #include "library.h" int main() { add_book("C Programming", 101); display_books(); return 0; }
Compilation Command
gcc main.c library.c -o library
Output File (books.txt)
C Programming,101
7. Algorithmic Problem Solving
Example: Shortest Path in Kathmandu Traffic
Problem: Find the shortest path from Thamel to Tribhuvan International Airport (TIA) using Dijkstra’s algorithm.
Graph Representation (Adjacency Matrix)
Dijkstra’s Algorithm Steps
- Initialize distances: Thamel = 0, others = ∞.
- Update neighbors:
- Thamel → Kageshwori: 5 km
- Thamel → Kantipath: 8 km
- Select Kageshwori (smallest distance).
- Update TIA via Kageshwori: 5 + 3 = 8 km.
- Select Kantipath (next smallest).
- Update TIA via Kantipath: min(8, 8 + 6) = 8 km.
- Shortest path: Thamel → Kageshwori → TIA (8 km).
C Implementation
#include <stdio.h>
#include <limits.h>
#define V 4 // Vertices: Thamel(0), Kageshwori(1), Kantipath(2), TIA(3)
void dijkstra(int graph[V][V], int src) {
int dist[V];
for (int i = 0; i < V; i++) dist[i] = INT_MAX;
dist[src] = 0;
for (int count = 0; count < V - 1; count++) {
int u = -1, min = INT_MAX;
for (int v = 0; v < V; v++) {
if (dist[v] < min && dist[v] != INT_MAX) {
min = dist[v];
u = v;
}
}
if (u == -1) break;
for (int v = 0; v < V; v++) {
if (graph[u][v] && dist[u] != INT_MAX &&
dist[u] + graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
}
}
printf("Shortest distances from Thamel:\n");
for (int i = 0; i < V; i++) {
printf("%d: %d km\n", i, dist[i]);
}
}
int main() {
int graph[V][V] = {
{0, 5, 8, 0},
{0, 0, 0, 3},
{0, 0, 0, 6},
{0, 0, 0, 0}
};
dijkstra(graph, 0);
return 0;
}
Output
Shortest distances from Thamel:
0: 0 km
1: 5 km
2: 8 km
3: 8 km
Exam Tip
What to Expect in TU/PU Exams
Problem-Solving Questions (40-50%)
- Expect 2-3 problems requiring:
- File handling (read/write operations).
- Dynamic memory allocation (e.g., linked lists).
- Modular design (header files, functions).
- Tip: Always plan your algorithm on paper before coding.
- Expect 2-3 problems requiring:
Debugging (20%)
- Given a buggy code snippet, identify and fix errors.
- Example:
// Buggy code (missing return type in function) void add(int a, int b) { return a + b; // Error: void function cannot return value } - Fix: Change to
int add(int a, int b).
Short Answer (20%)
- Define terms like:
- Modularity: Breaking a program into independent modules (functions/header files).
- Dynamic Memory: Memory allocated at runtime using
malloc(),calloc().
- Tip: Use real-world analogies (e.g., "Dynamic memory is like renting a hotel room for your data temporarily").
- Define terms like:
Practical Implementation (20%)
- Write a complete program for scenarios like:
- Student record management (structures + file handling).
- Simple calculator (functions + user input).
- Tip: Start with
main(), then define helper functions.
- Write a complete program for scenarios like:
Common Pitfalls to Avoid
- Memory Leaks: Always
free()dynamically allocated memory.int *arr = malloc(10 * sizeof(int)); // ... use arr ... free(arr); // Critical! - Buffer Overflows: Use
fgets()instead ofgets()for strings. - Incorrect File Modes: Use
"r"for reading,"w"for writing (overwrites),"a"for appending. - Floating-Point Precision: Use
%.2finprintf()for 2 decimal places.
Final Checklist Before Submission
- Code Structure:
- Proper indentation and comments.
- Logical function separation.
- Testing:
- Test with edge cases (empty input, maximum values).
- Memory Management:
- No leaks; all
malloc()hasfree().
- No leaks; all
- File Handling:
- Check if
fopen()succeeded (if (file == NULL)).
- Check if
- Output Formatting:
- Use
\nfor newlines,%.2ffor floats.
- Use
A sample bill showing subtotal, VAT, and total. (Image: Peter Merholz from Berkeley, CA, United States, CC BY-SA 2.0, via Wikimedia Commons)
In the real world
- eSewa: Uses file handling to store transaction records (e.g.,
transactions_2081.dat) and dynamic memory to process payments in real-time, ensuring no data loss during high traffic. - Daraz Inventory System: Employs linked lists to manage product stock dynamically, allowing quick updates and searches without loading the entire database into memory.
- Nepal Telecom (NTC) Billing: Applies hash tables to map customer IDs to billing records for O(1) access time, improving efficiency in generating monthly bills for millions of users.
Based on the PU BE Computer (PU) syllabus for Programming In C, unit 14.
Discussion
Loading…