IT232 C Programming

C ProgrammingUnit 1213 min read

C Programming Review & Practical Mastery

Unit 12 of C Programming consolidates all core concepts—syntax, algorithms, data structures, and real-world applications—through structured review sessions, debugging exercises, and hands-on projects to ensure exam readiness and practical fluency.

TAKEAWAYS:

  • Synthesize all C concepts (variables, loops, functions, pointers, and structures) into cohesive programs.
  • Debug systematically using tools like gdb or printf() to identify and fix logical and syntax errors.
  • Apply algorithms (sorting, searching, graph traversals) to solve practical problems like scheduling (Pathao drivers) or inventory (Daraz).
  • Optimize code for efficiency (time/space complexity) and readability using best practices.
  • Integrate real-world data (e.g., NEPSE stock prices, NTC call records) into programs for analysis.
  • Prepare for exams by solving past papers and simulating practical scenarios under time constraints.

1. Unit Recap: The Big Picture

Unit 12 is your final synthesis of C Programming. It bridges theory and practice by:

  • Reviewing all syntax (keywords, operators, control structures).
  • Reinforcing algorithmic thinking (loops, recursion, data structures).
  • Practicing debugging and code optimization.
  • Building mini-projects (e.g., a simple banking system, a student grade analyzer).
  • Simulating exam conditions with timed problem-solving.

2. Key Review Topics

2.1. Syntax and Semantics Deep Dive

What it covers:

  • Correct usage of C keywords (int, float, for, if), operators (++, ->, &&), and punctuation (;, {}).
  • Common pitfalls (e.g., missing semicolons, incorrect scope of variables).

Why it matters: Syntax errors are the #1 cause of failed programs. Unit 12 teaches you to spot and fix them efficiently.

Visual: Syntax Error Examples

flowchart TD
    A["Correct: int x = 5;"] --> B["Valid program"]
    C["Error: int x = 5"] --> D["Compiler error: missing semicolon"]
    E["Error: int x = 5; int y ="] --> F["Compiler error: incomplete statement"]

Trace:

Code Snippet Error Type Fix
int x = 5 Missing semicolon Add ; → int x = 5;
for(i=0; i<5; i++) Missing int Add int i → for(int i=0...)

2.2. Debugging Techniques

Tools and Methods:

  1. printf() Debugging: Print intermediate values to track logic.
    int a = 10, b = 20;
    printf("Before swap: a=%d, b=%d\n", a, b);
    // Swap logic here
    printf("After swap: a=%d, b=%d\n", a, b);
    
    Output:
    Before swap: a=10, b=20
    After swap: a=20, b=10
    
startMissing semicolonDivision by zeroAdd semicolonFix logicNo ErrorSyntax ErrorRuntime Error
Debugging state transitions (simplified)
  1. gdb (GNU Debugger): Step through code line-by-line.

    gcc swap.c -g
    gdb ./a.out
    (gdb) run
    (gdb) print a  # Check variable value
    
  2. Logical Error Traces: Use tables to track variable changes.

    Step a b Action
    1 10 20 Start
    2 10 20 temp = a
    3 10 20 a = b
    4 20 20 b = temp

Real-World Link:

  • Pathao Drivers: Debugging helps ensure ride assignments are correct, avoiding misrouted trips (like a queue implementation gone wrong).

2.3. Algorithm Optimization

Goal: Write efficient code (low time/space complexity). Example: Bubble Sort vs. Quick Sort

Algorithm Best Case Average Case Worst Case Space Complexity Use Case
Bubble Sort O(n) O(n²) O(n²) O(1) Small datasets
Quick Sort O(n log n) O(n log n) O(n²) O(log n) Large datasets (e.g., NEPSE stock sorting)

Visual: Quick Sort Partitioning

3061821031425
Step 1: Pivot (10) selection and initial partition

Code Example: Quick Sort

#include <stdio.h>
void quickSort(int arr[], int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);  // Partition logic
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}
int partition(int arr[], int low, int high) {
    int pivot = arr[high];
    int i = low - 1;
    for (int j = low; j < high; j++) {
        if (arr[j] < pivot) i++;
        swap(arr[i], arr[j]);
    }
    swap(arr[i + 1], arr[high]);
    return i + 1;
}

Trace (Step-by-Step):

Step Array State Pivot Partition Index
1 [3, 6, 8, 10, 1, 2] 10 3
2 [1, 2, 3, 6, 8, 10] 8 2

2.4. Data Structure Review

Focus Areas:

  1. Arrays: Fixed-size, contiguous memory.
    int arr[5] = {1, 2, 3, 4, 5};
    
    Visual: Array Insertion
102132
Before insertion (index 2)
  1. Linked Lists: Dynamic, non-contiguous.

    struct Node {
        int data;
        struct Node* next;
    };
    

    Visual: Linked List Insertion

    graph TD
        A["Before: 1 -> 2 -> NULL"] --> B["Insert 1.5 after 1"]
        B --> C["After: 1 -> 1.5 -> 2 -> NULL"]
  2. Stacks/Queues: LIFO/FIFO operations.

123TOP
After push(3)
  1. Trees: Hierarchical (e.g., BST for NEPSE stock searches).

2.5. Practical Projects

Example 1: Simple Banking System

  • Features:
    • Account creation/deletion.
    • Deposit/withdrawal (with balance check).
    • Display transactions.
  • Code Skeleton:
  struct Account {
      int id;
      char name[50];
      float balance;
  };
  struct Account accounts[100];
  int count = 0;

```figure
{"type":"network","nodes":["Student","Database","GUI","Report"],"edges":[["Student","Database","Query"],["Database","GUI","Data"],["GUI","Report","Generate"]],"caption":"Sample project workflow: Student Management System"}

void deposit(int id, float amount) { for (int i = 0; i < count; i++) { if (accounts[i].id == id) { accounts[i].balance += amount; return; } } printf("Account not found!\n"); } Trace (Deposit $200 to Account 101):

Step Action Account 101 Balance
1 Initial balance 500.00
2 Deposit $200 700.00

Real-World Link:

  • Ncell/Bhutan Telecom: Uses similar account management for call records and billing.

Example 2: Daraz Order Queue

  • Problem: Simulate a queue for processing orders.
  • Solution: Use a queue data structure.
    #include <stdio.h>
    #define MAX 100
    int queue[MAX], front = -1, rear = -1;
    
    void enqueue(int order) {
        if (rear == MAX - 1) printf("Queue full!\n");
        else {
            if (front == -1) front = 0;
            rear++;
            queue[rear] = order;
        }
    }
    

Visual: Queue Operations

graph TD
    A["Enqueue 101"] --> B["Queue: [101]"]
    C["Enqueue 102"] --> D["Queue: [101, 102]"]
    E["Dequeue"] --> F["Queue: [102]"]

2.6. Exam-Style Problem Solving

Past Paper Question (Adapted): Write a C program to read 10 integers and find the second largest number using an array and loops.

Solution Approach:

  1. Read 10 numbers into an array.
  2. Initialize largest and second_largest to INT_MIN.
  3. Loop through the array:
    • If num > largest, update second_largest = largest and largest = num.
    • Else if num > second_largest, update second_largest = num.
  4. Print second_largest.

Code:

#include <stdio.h>
#include <limits.h>
int main() {
    int arr[10], largest, second_largest;
    for (int i = 0; i < 10; i++) scanf("%d", &arr[i]);

    largest = second_largest = INT_MIN;
    for (int i = 0; i < 10; i++) {
        if (arr[i] > largest) {
            second_largest = largest;
            largest = arr[i];
        } else if (arr[i] > second_largest && arr[i] != largest)
            second_largest = arr[i];
    }
    printf("Second largest: %d\n", second_largest);
    return 0;
}

Trace (Input: [5, 2, 9, 1, 5, 6, 3, 8, 4, 7]):

Step Current Number Largest Second Largest
1 5 5 INT_MIN
2 2 5 2
3 9 9 5
4 1 9 5
5 5 9 5
... ... ... ...
Final - 9 8

3. In the Real World

  1. eSewa/Khalti:

    • Idea: Pointers and dynamic memory for secure transaction handling.
    • How: User credentials (e.g., phone numbers) are stored in dynamically allocated arrays to handle variable-length data (e.g., 10,000+ users).
  2. NEPSE (Nepal Stock Exchange):

    • Idea: Sorting algorithms for real-time stock price ranking.
    • How: Quick Sort or Merge Sort is used to display stocks in ascending/descending order by price or volume.
  3. Pathao Ride Scheduling:

    • Idea: Queue data structure for driver assignment.
    • How: New ride requests are enqueued, and the nearest available driver is dequeued for assignment (FIFO order).
  4. NTC/Ncell Call Records:

    • Idea: Arrays and structures for storing call logs.
    • How: Each call is stored as a struct Call { char caller[20], receiver[20]; float duration; } in an array, sorted by time for billing.

4. Exam Tips

  1. Time Management:

    • Spend ~10 minutes planning your code before writing. Sketch flowcharts for complex logic (e.g., tree traversals).
    • Allocate 20-25 minutes per question (adjust based on marks).
  2. Common Pitfalls to Avoid:

    • Off-by-one errors in loops (e.g., for (int i = 0; i <= n; i++) instead of <).
    • Uninitialized variables (always declare and initialize pointers/arrays).
    • Incorrect pointer arithmetic (e.g., *(ptr + 1) vs ptr++).
  3. Debugging Shortcuts:

    • Use printf() liberally to print variables at each step.
    • Test with edge cases (e.g., empty arrays, negative numbers, large inputs).
  4. Project-Based Questions:

    • If asked to design a program (e.g., "Write a program to manage student grades"), include:
      • Input: How data is taken (e.g., scanf for numbers, gets for names).
      • Processing: Logic (e.g., loops for calculations, functions for modularity).
      • Output: Formatted results (e.g., printf with %f for grades).
    • Example structure:
      #include <stdio.h>
      struct Student {
          char name[50];
          float marks[5];
      };
      int main() {
          struct Student s[10];
          // Input, processing, output...
      }
      
  5. Past Papers:

    • Practice 2-3 past exam papers under timed conditions. Focus on:
      • Short-answer questions (1-2 marks): Syntax, logic flow.
      • Long-answer questions (5-10 marks): Full programs with comments and traces.

5. Sample Exam Question with Solution

Question (10 marks): Write a C program to read 5 integers and display them in reverse order using a stack. Include comments and a trace table for input [10, 20, 30, 40, 50].

Solution:

#include <stdio.h>
#define MAX 5
int stack[MAX], top = -1;

void push(int item) {
    if (top == MAX - 1) printf("Stack overflow!\n");
    else stack[++top] = item;
}

int pop() {
    if (top == -1) {
        printf("Stack underflow!\n");
        return -1;
    }
    return stack[top--];
}

int main() {
    int arr[5];
    printf("Enter 5 numbers:\n");
    for (int i = 0; i < 5; i++) scanf("%d", &arr[i]);

    // Push to stack
    for (int i = 0; i < 5; i++) push(arr[i]);

    // Pop and print
    printf("Reverse order:\n");
    while (top != -1) printf("%d ", pop());
    return 0;
}

Trace Table:

Step Action Stack State Output
1 Push 10 [10] -
2 Push 20 [10, 20] -
3 Push 30 [10, 20, 30] -
4 Push 40 [10, 20, 30, 40] -
5 Push 50 [10, 20, 30, 40, 50] -
6 Pop [10, 20, 30, 40] 50
7 Pop [10, 20, 30] 50 40
... ... ... ...
Final - [] 50 40 30 20 10

6. Final Checklist Before Exam

  • Syntax: Check for semicolons, braces, and correct variable declarations.
  • Logic: Trace variables step-by-step for loops/recursion.
  • Memory: Ensure pointers and arrays are properly initialized.
  • Edge Cases: Test with 0, -1, NULL, or empty inputs.
  • Comments: Add brief comments for each major step (examiners love this!).
  • Formatting: Use consistent indentation and spacing.

Based on the TU BITM syllabus for C Programming (IT232), unit 12.

Discussion

Loading…