C ProgrammingUnit 514 min read

Loops & Iteration in C: for, while, do-while, break, continue

Unit 5 of C Programming covers iterative control structures—for, while, do-while loops, and their modifiers (break, continue, goto)—with step-by-step traces, real-world applications (e.g., Pathao’s order processing), and comparisons of efficiency, readability, and use cases.

TAKEAWAYS:

  • for loops excel for count-controlled iterations (e.g., processing 100 orders in Daraz).
  • while loops handle condition-controlled tasks (e.g., NTC’s traffic light cycle until a sensor triggers).
  • do-while loops guarantee at least one execution (e.g., WhatsApp’s "retry failed message" logic).
  • break/continue refine loop flow: break exits early (e.g., skipping invalid NEPSE stock entries), continue skips iterations (e.g., filtering spam in emails).
  • Infinite loops (while(1)) power real-time systems (e.g., Ncell’s call routing server).
  • Nested loops solve multi-dimensional problems (e.g., calculating Khalti’s transaction fees for bulk transfers).

1. Introduction to Iteration

Iteration (or looping) repeats a block of code until a condition is met. Loops reduce redundant code and improve efficiency. In C, three primary loop constructs exist:

  • for: Best for known iterations (e.g., "run 5 times").
  • while: Runs while a condition is true (e.g., "keep checking until user inputs valid data").
  • do-while: Runs at least once, then checks the condition (e.g., "prompt user until they quit").

Real-world analogy: Imagine Pathao’s order processing:

  1. A rider picks up an order.
  2. The app checks if the order is complete (while loop).
  3. If not, it prompts the rider again (do-while ensures at least one attempt).
  4. Once done, it updates the status (break exits the loop).

2. The for Loop

Syntax:

for (initialization; condition; increment/decrement) {
    // Code to repeat
}

How it works:

  1. Initialization: Runs once (e.g., int i = 0).
  2. Condition: Checked before each iteration (e.g., i < 10).
  3. Increment/Decrement: Executed after each iteration (e.g., i++).

Example: Sum of First 10 Natural Numbers

Code:

#include <stdio.h>
int main() {
    int sum = 0;
    for (int i = 1; i <= 10; i++) {
        sum += i;
    }
    printf("Sum = %d\n", sum); // Output: 55
    return 0;
}

Trace Table:

Iteration i (value) sum (value) Condition (i <= 10)
1 1 1 True
2 2 3 True
... ... ... ...
10 10 55 True
11 11 55 False (loop ends)

Visualization:

flowchart TD
    A["Start"] --> B["Initialize i=1"]
    B --> C["Check i <= 10?"]
    C -->|"Yes"| D["sum += i"]
    D --> E["i++"]
    E --> C
    C -->|"No"| F["End"]

Real-world tie-in: NEPSE’s daily stock price checker:

for (int stock = 1; stock <= 100; stock++) {
    if (price[stock] > threshold) {
        alert("Buy signal!");
    }
}
  • Why for? Fixed number of stocks (100) → predictable iterations.

3. The while Loop

Syntax:

while (condition) {
    // Code to repeat
}

Key feature: Checks the condition before executing the loop body. May never run if the condition is initially false.

Example: User Input Validation (Khalti PIN Entry)

Code:

#include <stdio.h>
int main() {
    int pin;
    printf("Enter PIN: ");
    scanf("%d", &pin);
    while (pin != 1234) { // Correct PIN is 1234
        printf("Invalid! Try again: ");
        scanf("%d", &pin);
    }
    printf("Access granted!\n");
    return 0;
}

Trace Table:

Iteration pin (input) Condition (pin != 1234) Action
1 9999 True Prompt again
2 5678 True Prompt again
3 1234 False Exit loop, grant access

Visualization:

flowchart TD
    A["Start"] --> B["Prompt for PIN"]
    B --> C["Check PIN == 1234?"]
    C -->|"No"| D["Invalid! Retry"]
    D --> B
    C -->|"Yes"| E["Grant Access"]

Real-world tie-in: NTC’s Traffic Light System:

while (sensor == "car_present") {
    light = "RED";
    delay(30); // Hold for 30 seconds
    light = "GREEN";
    delay(20);
}
  • Why while? The loop runs only if cars are detected (condition-driven).

4. The do-while Loop

Syntax:

do {
    // Code to repeat
} while (condition);

Key feature: Checks the condition after executing the loop body. Guarantees at least one execution.

Example: WhatsApp Message Retry Logic

Code:

#include <stdio.h>
int main() {
    int retry = 0;
    char message[100];
    do {
        printf("Enter message: ");
        gets(message);
        retry++;
    } while (strlen(message) == 0 && retry < 3); // Retry if empty, max 3 times
    printf("Message sent: %s\n", message);
    return 0;
}

Trace Table:

Iteration message (input) strlen(message) == 0 retry Condition (strlen == 0 && retry < 3)
1 "" True 1 True
2 "" True 2 True
3 "Hi!" False 3 False (loop ends)

Visualization:

flowchart TD
    A["Start"] --> B["Prompt for message"]
    B --> C["Check message empty AND retries < 3?"]
    C -->|"Yes"| D["Retry"]
    D --> B
    C -->|"No"| E["Send message"]

Real-world tie-in: eSewa’s Payment Retry:

do {
    status = process_payment();
    if (status == "failed") {
        delay(5); // Wait 5 seconds
    }
} while (status == "failed" && attempts < 3);
  • Why do-while? Must attempt payment at least once, even if it fails immediately.

5. Loop Control Statements

break Statement

Exits the loop immediately. Used to terminate early when a condition is met.

Example: Finding the First Even Number in a List Code:

#include <stdio.h>
int main() {
    int numbers[] = {1, 3, 5, 6, 7};
    for (int i = 0; i < 5; i++) {
        if (numbers[i] % 2 == 0) {
            printf("First even: %d\n", numbers[i]);
            break; // Exit loop after first match
        }
    }
    return 0;
}

Output: First even: 6 Visualization:

flowchart TD
    A["Start"] --> B["Check numbers[0] even?"]
    B -->|"No"| C["Check numbers[1] even?"]
    C -->|"No"| D["Check numbers[2] even?"]
    D -->|"No"| E["Check numbers[3] even?"]
    E -->|"Yes"| F["Print 6\nBreak"]

Real-world tie-in: Daraz’s Order Fulfillment:

for (int order = 0; order < 100; order++) {
    if (order_status[order] == "shipped") {
        notify_customer(order);
        break; // No need to check further
    }
}

continue Statement

Skips the current iteration and moves to the next. Used to filter unwanted cases.

Example: Skipping Negative Numbers in a Sum Code:

#include <stdio.h>
int main() {
    int numbers[] = {1, -2, 3, -4, 5};
    int sum = 0;
    for (int i = 0; i < 5; i++) {
        if (numbers[i] < 0) {
            continue; // Skip negatives
        }
        sum += numbers[i];
    }
    printf("Sum of positives: %d\n", sum); // Output: 9
    return 0;
}

Trace Table:

Iteration numbers[i] Condition (< 0) Action
1 1 False Add to sum (sum = 1)
2 -2 True Skip (continue)
3 3 False Add to sum (sum = 4)
4 -4 True Skip (continue)
5 5 False Add to sum (sum = 9)

Visualization:

flowchart TD
    A["Start"] --> B["Check numbers[0] >= 0?"]
    B -->|"Yes"| C["Add to sum"]
    C --> D["Next iteration"]
    D --> E["Check numbers[1] >= 0?"]
    E -->|"No"| F["Skip (continue)"]
    F --> D
    D --> G["Check numbers[2] >= 0?"]
    G -->|"Yes"| H["Add to sum"]
    H --> D

Real-world tie-in: Ncell’s Call Barring:

for (int call = 0; call < 100; call++) {
    if (blocked_numbers[call] == current_call) {
        continue; // Skip blocked calls
    }
    process_call(call);
}

goto Statement (Use with Caution)

Jumps to a labeled statement. Rarely used due to readability risks.

Example: Simulating a Menu System Code:

#include <stdio.h>
int main() {
    int choice;
    start:
    printf("1. Deposit\n2. Withdraw\n3. Exit\n");
    scanf("%d", &choice);
    switch (choice) {
        case 1: printf("Deposit\n"); goto start;
        case 2: printf("Withdraw\n"); goto start;
        case 3: break;
    }
    return 0;
}

Warning: Overuse makes code hard to debug. Prefer structured loops.


6. Nested Loops

Loops inside loops. Used for multi-dimensional tasks (e.g., matrices, grids).

Example: Printing a Multiplication Table (5x5)

Code:

#include <stdio.h>
int main() {
    for (int i = 1; i <= 5; i++) {       // Rows
        for (int j = 1; j <= 5; j++) {   // Columns
            printf("%d ", i * j);
        }
        printf("\n");
    }
    return 0;
}

Output:

1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25

Visualization:

flowchart TD
    A["Start"] --> B["i=1"]
    B --> C["j=1"]
    C --> D["Print i*j"]
    D --> E["j++"]
    E --> F["Check j <= 5?"]
    F -->|"Yes"| C
    F -->|"No"| G["Newline"]
    G --> H["i++"]
    H --> I["Check i <= 5?"]
    I -->|"Yes"| B
    I -->|"No"| J["End"]

Real-world tie-in: Khalti’s Transaction Fee Calculator for Bulk Transfers:

for (int customer = 0; customer < 100; customer++) {
    for (int transaction = 0; transaction < 5; transaction++) {
        fee = calculate_fee(transaction);
        total_fee += fee;
    }
}
  • Why nested? Each customer may have multiple transactions.

7. Infinite Loops

Loops that run forever unless manually terminated (e.g., while(1)). Used in servers, games, or real-time systems.

Example: Simple Server Loop (Ncell Call Router) Code:

#include <stdio.h>
int main() {
    while (1) { // Infinite loop
        printf("Waiting for call...\n");
        int call = receive_call();
        if (call == -1) break; // Exit on shutdown signal
        process_call(call);
    }
    return 0;
}

Real-world tie-in: Pathao’s Rider Assignment Server:

while (1) {
    rider = assign_rider(order);
    if (rider == "none") {
        wait_for_new_order();
    } else {
        update_status(order, rider);
    }
}

8. Loop Performance and Best Practices

Loop Type Best Use Case Efficiency Readability
for Known iterations (e.g., arrays) High High
while Unknown iterations (e.g., user input) Medium Medium
do-while At least one execution required Medium Low
Nested Loops Multi-dimensional data (e.g., grids) Low (O(n²)) Medium

Best Practices:

  1. Initialize counters inside for loops (e.g., for (int i = 0; ...)).
  2. Avoid infinite loops unless intentional (use break for exits).
  3. Use continue for filtering, not if-else inside loops.
  4. Prefer for for arrays, while for dynamic conditions.
  5. Comment complex loops to explain logic.

9. Common Pitfalls and Debugging

  1. Off-by-One Errors:

    • Cause: Incorrect loop bounds (e.g., for (int i = 0; i <= 10; i++) runs 11 times).
    • Fix: Use < for "up to but not including" (e.g., i < 10).
  2. Infinite Loops:

    • Cause: Missing increment/decrement or condition that never becomes false.
    • Debug: Add printf to trace loop variables.
  3. Uninitialized Counters:

    • Cause: Using i before declaration (e.g., for (i = 0; ...) without int i).
    • Fix: Declare variables inside the loop header.

Example Debugging: Buggy Code:

for (int i = 0; i <= 10; i++) { // Off-by-one: runs 11 times
    printf("%d ", i * i);
}

Output: 0 1 4 9 16 25 36 49 64 81 100 (extra 100). Fix:

for (int i = 0; i < 10; i++) { // Correct: runs 10 times
    printf("%d ", i * i);
}

10. Real-World Applications

Example 1: Pathao’s Order Processing

flowchart TD
    A["Order Received"] --> B["while (order_status != 'delivered')"]
    B --> C["Check Rider Location"]
    C -->|"Rider Nearby"| D["Assign Order"]
    C -->|"Rider Far"| E["Wait 5 mins\nRetry"]
    D --> F["Update Status: 'in_transit'"]
    F --> B
    B -->|"Delivered"| G["Mark as Complete"]
  • Loops used: while to track order status until delivery.

Example 2: NTC’s Traffic Light Cycle

flowchart TD
    A["Start"] --> B["while (true)"]
    B --> C["if (sensor == 'car')"]
    C -->|"Yes"| D["Light = RED\nDelay 30s"]
    C -->|"No"| E["Light = GREEN\nDelay 20s"]
    D --> B
    E --> B
  • Loops used: while(1) for continuous operation.

Example 3: Khalti’s Bulk Transaction Fee Calculation

flowchart TD
    A["for (customer = 0; customer < 100; customer++)"] --> B["for (txn = 0; txn < 5; txn++)"]
    B --> C["fee = calculate_fee(txn)"]
    C --> D["total_fee += fee"]
    D --> B
    B --> A
  • Loops used: Nested for for multi-dimensional data (customers × transactions).

Exam Tip

  1. Understand the Loop Condition:

    • Exams often ask to predict loop outputs. Trace tables are your friend!
    • Example: For for (int i = 2; i <= 5; i += 2), list i values: 2, 4.
  2. Practice Writing Loops:

    • Given a problem (e.g., "print even numbers from 1 to 20"), write the loop and trace it.
    • Example:
      for (int i = 2; i <= 20; i += 2) {
          printf("%d ", i);
      }
      
  3. Watch for Tricky Conditions:

    • Questions may test edge cases like:
      • Empty loops (while(0)).
      • Post-increment vs. pre-increment (i++ vs. ++i in conditions).
      • Floating-point comparisons (use fabs(a - b) < 0.001 instead of a == b).
  4. Nested Loops in Exams:

    • If asked to print a pattern (e.g., right-angled triangle), use nested loops.
    • Example:
      for (int i = 1; i <= 4; i++) {
          for (int j = 1; j <= i; j++) {
              printf("* ");
          }
          printf("\n");
      }
      
      Output:
      *
      * *
      * * *
      * * * *
      
  5. Common Exam Questions:

    • Output Prediction: Given a loop, what is printed?
    • Loop Correction: Fix a buggy loop (e.g., infinite loop).
    • Algorithm Design: Write a loop to solve a problem (e.g., find the largest number in an array).
    • Trace Tables: Fill in missing values for loop variables.

Final Note: Loops are the backbone of iterative problems. Master them by:

  1. Tracing loops step-by-step.
  2. Relating them to real-world systems (e.g., Pathao, Khalti).
  3. Practicing edge cases (empty inputs, large datasets).
  4. Avoiding goto unless absolutely necessary.

Based on the TU BIM syllabus for C Programming (IT232), unit 5.

Discussion

Loading…