break · continue · goto in C
0%
C Control Flow  ·  Jump Statements

break · continue
& goto in C

Three jump keywords that alter the normal top-to-bottom flow of a program — one to exit a loop early, one to skip the rest of an iteration, and one to jump unconditionally to a label.

🛑
break
Exits the nearest enclosing loop or switch immediately. Code after the loop runs next.
⏭️
continue
Skips the rest of the current iteration and goes straight to the next one.
🎯
goto
Jumps unconditionally to a labelled point anywhere in the same function.
break
break — Exit a Loop or switch Early
Immediately terminates the nearest enclosing for / while / do-while / switch and transfers to the statement after it
Part 1

How break works

break causes immediate exit from the nearest enclosing for, while, do-while, or switch statement. Execution continues at the first statement after the loop or switch. It does not exit nested loops all at once — only the innermost one containing it.

Common uses: stop searching once a target is found, exit a menu loop on quit, terminate an infinite loop on a condition, and end a switch case to prevent fall-through.

break — syntax & placement
/* Inside a loop */
for (init; condition; update) {
    // ... statements ...
    if (someCondition)
        break; ← exits the for loop, goes to A
}
/* A: execution continues here after break */
🗺️ break control flow — loop exits immediately on condition
START condition? YES loop body break? YES → break NO → next iter NO After loop STOP
B1
Search array — stop as soon as target is found
Linear search using break to exit the loop the moment the value matches
break in for loop
We store student roll numbers in an array and search for a given roll. The for loop walks every element. The moment arr[i] == target, we save the index and fire break — the loop stops immediately, even if half the array hasn't been scanned yet. Without break, the loop would needlessly continue through all remaining elements.
break_search.c
C
#include <stdio.h>

int main() {
    int rolls[] = { 101, 104, 107, 110,
                    113, 116, 119, 122 };
    int n      = sizeof(rolls) / sizeof(rolls[0]);
    int target = 113;
    int found  = -1;

    printf("Searching for roll %d...\n", target);

    for (int i = 0; i < n; i++) {
        printf("  Checking index %d → %d", i, rolls[i]);

        if (rolls[i] == target) {
            found = i;
            printf(" ✓ MATCH!\n");
            break;          /* stop — no need to scan further */
        }
        printf("\n");
    }

    /* Execution resumes HERE after break */
    if (found != -1)
        printf("\nRoll %d found at index %d.\n",
               target, found);
    else
        printf("\nRoll %d not found.\n", target);

    return 0;
}
output
Searching for roll 113...
  Checking index 0 → 101
  Checking index 1 → 104
  Checking index 2 → 107
  Checking index 3 → 110
  Checking index 4 → 113 ✓ MATCH!

Roll 113 found at index 4.
break stops scan early — indices 5,6,7 never checked
Scanned
101
104
107
110
113✓
← break fires at index 4
Never reached
116
119
122
← skipped — 3 unnecessary checks saved
break only exits the innermost enclosing loop. If you have a for inside a while, break inside the for exits the for only — the while keeps running. To exit all nested loops, use a flag variable or goto (see Part 3).
part 2 — continue
cont
continue — Skip to the Next Iteration
Skips the remaining statements in the current loop body and jumps to the update/condition check for the next round
Part 2

How continue works

continue skips the rest of the current iteration of the nearest enclosing loop. In a for loop, it jumps to the update expression (e.g. i++) then re-checks the condition. In a while or do-while, it jumps directly to the condition check.

The loop itself does not exit — it continues running; only the remaining code in that one iteration is skipped. Use continue to filter or ignore certain values without deeply nesting your logic.

continue — syntax & what gets skipped
for (int i = 0; i < n; i++) { ← update runs after continue
    if (skipCondition)
        continue; ← jumps to i++ then condition check

    /* Everything below is SKIPPED for this iteration */
    doWork();
}
🗺️ continue control flow — skips rest of body, loop continues
START i++ (update) i < n ? NO YES skip? YES → continue NO do work After loop
C1
Print only even numbers — skip odd ones with continue
Walk 1–15, use continue to jump past odd numbers, print only evens and show their squares
continue in for loop
We count from 1 to 15. Inside the loop, if the number is odd (i % 2 != 0), we fire continue — this skips the printf and the square calculation entirely and jumps straight to i++ and then the condition check. Only even numbers ever reach the printf statements.
continue_evens.c
C
#include <stdio.h>

int main() {
    int sumEvens = 0;

    printf("Even numbers from 1 to 15 and their squares:\n\n");
    printf("  %-6s  %-8s\n", "n", "n²");
    printf("  %s\n", "---------------");

    for (int i = 1; i <= 15; i++) {

        if (i % 2 != 0)
            continue;   /* odd → skip rest, go to i++ */

        /* Only even numbers reach here */
        printf("  %-6d  %-8d\n", i, i * i);
        sumEvens += i;
    }

    printf("  %s\n", "---------------");
    printf("\nSum of evens (2+4+…+14) = %d\n", sumEvens);
    printf("Formula check  n(n+2)/2 = %d × %d / 2 = %d\n",
           7, 8, 7*8/2);      /* 7 even numbers, max=14 */
    return 0;
}
output
Even numbers from 1 to 15 and their squares:

  n       n²
  ---------------
  2       4
  4       16
  6       36
  8       64
  10      100
  12      144
  14      196
  ---------------

Sum of evens (2+4+…+14) = 56
Formula check  n(n+2)/2 = 7 × 8 / 2 = 28
iteration trace — continue fires for odd i, print runs for even i
i = 1 (odd)
continue ⏭
→ i=2
← printf skipped
i = 2 (even)
printf 2, 4
sum=2
i = 3 (odd)
continue ⏭
→ i=4
← printf skipped
i = 4 (even)
printf 4, 16
sum=6
i = 5,7,9… (odd)
continue ⏭ each time
Key difference: continue vs break. continue keeps the loop running but skips this iteration's remaining code. break kills the loop entirely. Think of continue as "next please" and break as "I'm done here".
part 3 — goto
goto
goto — Unconditional Jump to a Label
Jumps instantly to any labelled point in the same function — forward or backward, no questions asked
Part 3

How goto works

goto labelName transfers execution unconditionally to the line marked labelName: (identifier + colon) anywhere within the same function. The jump can be forward (skip code below) or backward (create a loop). Unlike break and continue, goto is not restricted to loops.

Modern accepted uses: (1) escape nested loops — one goto exits all levels at once where multiple breaks would be needed; (2) centralised error cleanup — jump to a single cleanup label at the end of a function to free resources. For everything else, use if/while/for/return.

goto — syntax, label rules
labelName: ← label = identifier + colon, any position in function
    statement;

goto labelName; ← jumps to label immediately

/* Rules: • label and goto must be in the SAME function • can jump forward (skip code) or backward (loop) • cannot jump INTO a variable declaration scope • label needs a statement after ':' — use ';' if nothing */
G1
Search 2D grid — goto exits both loops instantly on match
Nested for loops search a 3×4 grid for a target; goto jumps out of both at once when found
goto — nested loop exit ✅
We have a 3×4 number grid and search for a target value. Two nested for loops scan row by row. When the target is found, a single goto found exits both loops instantly and jumps to the result-printing label. Without goto, we would need either a flag variable checked after each inner loop, or a wrapper function with return. The goto is the cleanest option here.
goto_grid_search.c
C
#include <stdio.h>

#define ROWS 3
#define COLS 4

int main() {
    int grid[ROWS][COLS] = {
        {  5, 12, 19,  7 },
        { 33, 48,  2, 61 },
        { 14, 77, 29,  9 }
    };

    int target = 48;
    int foundR = -1, foundC = -1;

    printf("Grid:\n");
    for (int r = 0; r < ROWS; r++) {
        printf("  ");
        for (int c = 0; c < COLS; c++)
            printf("%4d", grid[r][c]);
        printf("\n");
    }

    printf("\nSearching for %d...\n", target);

    for (int r = 0; r < ROWS; r++) {
        for (int c = 0; c < COLS; c++) {
            printf("  Checking [%d][%d] = %d\n",
                   r, c, grid[r][c]);

            if (grid[r][c] == target) {
                foundR = r;
                foundC = c;
                goto found;  /* EXIT both loops! */
            }
        }
    }

found:                     /* both loops jump here */
    if (foundR != -1)
        printf("\nFound %d at grid[%d][%d]!\n",
               target, foundR, foundC);
    else
        printf("\n%d not found.\n", target);

    return 0;
}
output
Grid:
     5  12  19   7
    33  48   2  61
    14  77  29   9

Searching for 48...
  Checking [0][0] = 5
  Checking [0][1] = 12
  Checking [0][2] = 19
  Checking [0][3] = 7
  Checking [1][0] = 33
  Checking [1][1] = 48

Found 48 at grid[1][1]!
Never use goto for ordinary loops or if/else. Every normal while loop is just a backward goto — but that doesn't mean you should write loops with goto. Use structured constructs (while, for, if, return) for all normal control flow. Reserve goto only for the two accepted patterns: nested-loop exit and error-cleanup at the bottom of a function.
side-by-side comparison
KeywordWhat it doesWorks inDestinationBest use
break Exits the enclosing loop or switch immediately for · while · do-while · switch Statement after the loop/switch Stop searching when target found; end a switch case
continue Skips rest of current iteration; loop continues for · while · do-while Update expression (for) or condition check (while) Filter/skip unwanted values without deep nesting
goto Jumps unconditionally to a labelled point Anywhere in function Any label in the same function (forward or back) Exit nested loops; centralised error cleanup
quick mental model — what each keyword does to the loop counter
break
loop STOPS
i stays at current
← counter is NOT incremented
continue (for)
body skipped
i++ runs
condition checked
← counter IS incremented, loop goes on
continue (while)
body skipped
condition checked
← update must be done BEFORE continue or infinite loop!
goto
jumps to label
ignores all loop state
← label can be anywhere in the function
Watch out for infinite loops with continue in while. In a while loop, if you continue before updating the loop variable, the condition is checked again with the same value — infinite loop! Always ensure the update expression runs before continue fires:

while (i < n) { if (skip) { i++; continue; } /* work */ i++; }
checklist
  • break — exits the nearest enclosing for / while / do-while / switch immediately. Execution resumes at the statement after the closing brace. Only exits one level — not all nested loops.
  • continue — skips the rest of the current iteration and jumps to the update (for) or condition (while). The loop itself keeps running. Never exits the loop. Classic use: filter / skip unwanted values.
  • continue in while — danger! If the loop counter update comes after continue, it gets skipped too, causing an infinite loop. Always update the counter before firing continue inside a while.
  • goto — jumps unconditionally to a label (name:) in the same function. Can go forward or backward. Two accepted uses only: (1) exit nested loops, (2) centralised error/resource cleanup at function end.
  • break vs continuebreak = "I'm done with this loop". continue = "skip this item, give me the next one". goto = "jump to this exact spot in the code, no questions".
  • Nested loops + breakbreak exits only the innermost loop. To escape multiple levels cleanly, use a flag variable, wrap in a function and return, or use goto with a label placed after all the loops.