upgrade
upgrade

🧑🏽‍💻Intro to C Programming

Control Flow Statements

Study smarter with Fiveable

Get study guides, practice questions, and cheatsheets for all your subjects. Join 500,000+ students with a 96% pass rate.

Get Started

Why This Matters

Control flow is the backbone of every C program you'll write. Without it, your code would execute line by line from top to bottom with no ability to make decisions, repeat tasks, or respond to different inputs. When you're tested on control flow, you're really being tested on your understanding of conditional logic, iteration patterns, and program execution order—concepts that appear in virtually every programming problem you'll encounter.

The key insight is this: control flow statements fall into distinct categories based on what they do—branching (choosing a path), looping (repeating code), and jumping (moving execution elsewhere). Don't just memorize syntax; know which statement solves which problem and why you'd choose one over another. That's what separates students who can write working code from those who just recognize keywords.


Conditional Branching: Making Decisions

These statements let your program choose different execution paths based on conditions. The core mechanism is Boolean evaluation—every condition resolves to either true (non-zero) or false (zero).

if Statement

  • Simplest conditional—evaluates an expression and executes the code block only when the condition is true (non-zero)
  • Syntax: if (condition) { /* code */ }—parentheses around the condition are required, braces optional for single statements but always recommended
  • Foundation for all branching logic—understanding if is prerequisite to mastering every other control structure

if-else Statement

  • Binary branching—provides two mutually exclusive paths, one for true and one for false conditions
  • Syntax: if (condition) { /* true path */ } else { /* false path */ }—exactly one block will always execute
  • Can be nested or chained with else if for multiple conditions, though switch is often cleaner for many discrete values

switch Statement

  • Multi-way branching—matches a single expression against multiple constant values efficiently
  • Fall-through behavior—execution continues to the next case unless stopped by break; this is both a feature and a common bug source
  • Requires integer-compatible types—works with int, char, and enums, but not with strings or floating-point values
switch (grade) {
    case 'A': printf("Excellent"); break;
    case 'B': printf("Good"); break;
    default: printf("Keep trying");
}

Compare: if-else chains vs. switch—both handle multiple conditions, but switch is cleaner and potentially faster when comparing one variable against many constant values. Use if-else when conditions involve ranges, comparisons, or non-constant expressions.


Iteration: Repeating Code

Loops execute a block of code multiple times. The key distinction is when the condition is checked and whether the number of iterations is known in advance.

for Loop

  • Count-controlled iteration—combines initialization, condition, and update in one line: for (init; condition; update)
  • Best when iterations are predetermined—use when you know exactly how many times to repeat (e.g., processing array elements)
  • All three components are optionalfor (;;) creates an infinite loop, and any part can be omitted or contain multiple expressions
for (int i = 0; i < 10; i++) {
    printf("%d ", i);
}

while Loop

  • Pre-test loop—evaluates condition before each iteration, meaning the body might never execute if initially false
  • Best for unknown iteration counts—use when looping depends on dynamic conditions like user input or file reading
  • Syntax: while (condition) { /* body */ }—you must update the condition variable inside the loop or risk infinite loops

do-while Loop

  • Post-test loop—evaluates condition after each iteration, guaranteeing the body executes at least once
  • Syntax: do { /* body */ } while (condition);—note the semicolon after the closing parenthesis (easy to forget!)
  • Ideal for input validation—when you need to prompt the user at least once before checking if their input is valid

Compare: while vs. do-while—both are condition-controlled loops, but while may skip the body entirely while do-while always runs once. If an exam asks about "guaranteed execution," do-while is your answer.

Compare: for vs. while—functionally equivalent (any for can be rewritten as while), but for is conventional when the iteration count is known, while when it depends on runtime conditions.


Jump Statements: Altering Flow

These statements transfer control to another point in the program. They interrupt normal sequential execution and should be used deliberately.

break Statement

  • Immediate exit—terminates the nearest enclosing for, while, do-while, or switch statement
  • Single-level only—breaks out of one loop; for nested loops, you'd need multiple breaks or a different approach
  • Essential in switch—without break, execution "falls through" to subsequent cases unintentionally

continue Statement

  • Skip current iteration—jumps to the next iteration of the enclosing loop, bypassing remaining code in the body
  • Works with all loop types—in for loops, the update expression still executes; in while/do-while, control goes directly to the condition
  • Useful for filtering—skip processing certain elements without complex nested if statements
for (int i = 0; i < 10; i++) {
    if (i % 2 == 0) continue;  // Skip even numbers
    printf("%d ", i);  // Prints: 1 3 5 7 9
}

Compare: break vs. continuebreak exits the loop entirely, continue skips to the next iteration. Both affect only the innermost loop, and both are commonly tested in trace-the-output questions.

goto Statement

  • Unconditional jump—transfers control to a labeled statement anywhere in the same function
  • Generally avoided—creates "spaghetti code" that's hard to read, debug, and maintain; most problems have cleaner solutions
  • Rare valid use—breaking out of deeply nested loops where multiple break statements would be awkward

return Statement

  • Exits the function—immediately terminates execution of the current function and returns control to the caller
  • Passes values backreturn value; sends a result to the calling code; return; exits void functions without a value
  • Can appear anywhere—useful for early exits when error conditions are detected, avoiding deeply nested logic

Compare: break vs. returnbreak exits a loop but continues the function, return exits the entire function. In main(), return also ends the program.


Quick Reference Table

ConceptBest Examples
Binary decisionsif, if-else
Multi-way branchingswitch, else if chains
Count-controlled loopsfor
Condition-controlled loopswhile, do-while
Guaranteed single executiondo-while
Early loop terminationbreak
Skip iterationcontinue
Function exitreturn
Unconditional jump (avoid)goto

Self-Check Questions

  1. What's the key difference between while and do-while? Write a scenario where choosing the wrong one would cause a bug.

  2. If you need to check a variable against the values 1, 2, 3, 4, and 5, which control structure would be most appropriate—if-else chain or switch? Why?

  3. Compare break and continue: what happens to loop execution after each? In a for loop, does the update expression run after continue?

  4. Convert this for loop to an equivalent while loop:

    for (int i = 0; i < n; i++) { printf("%d", i); }
    
  5. A function needs to validate user input, prompting repeatedly until valid data is entered. Which loop type is most appropriate, and why would the alternatives be problematic?