Introduction
Control-flow statements decide which statement runs next. C has selection statements (if, if-else, switch), iteration statements (while, do-while, for) and jump statements (break, continue, goto, return). Every algorithm is built from them, and a large share of GATE C questions reduce to tracing them exactly: how many times a loop body runs, which case labels execute, which if an else belongs to.
Conventions: C11, LP64. A condition in C is any scalar expression; it is "true" when it compares unequal to 0.
Prerequisites
- Operators, Precedence and Side Effects: relational and logical operators, short-circuit evaluation, the value of an assignment.
Core concepts
Statements and blocks
A compound statement (block) { ... } groups statements into one. Every control statement controls exactly one statement; use a block to control several. A lone ; is the null statement, which does nothing. A misplaced ; therefore changes meaning:
for (i = 0; i < 5; i++); /* the body is the null statement */
printf("%d\n", i); /* runs once, prints 5 */if and the dangling else
if (c) S1 else S2 runs S1 when c is nonzero, otherwise S2. The else part is optional.
Rule: an else belongs to the nearest preceding unmatched if in the same block. Indentation is ignored by the compiler.
int a = 0, b = 5;
if (a > 0)
if (b > 0) printf("A");
else
printf("B"); /* belongs to "if (b > 0)": prints nothing here */With a = 0, the outer if fails, so nothing is printed, despite the indentation suggesting B. Braces fix the intent: if (a > 0) { if (b > 0) printf("A"); } else printf("C"); prints C.
switch
switch (expression) {
case constant-1: statements
case constant-2: statements
default: statements
}- The controlling expression must have integer type (after the integer promotions);
switchon adoubleor a string does not compile. - Each
caselabel must be an integer constant expression, and no two labels may have the same value.defaultis optional and may appear anywhere. - Execution jumps to the matching label (or to
default, or past the wholeswitchif there is no match and nodefault) and then runs sequentially, through later labels, until abreakor the end of theswitch. Falling into the next case is called fall-through. caselabels are just labels: they do not start new scopes, and the order of labels does not matter for matching.
Loops
| Loop | Test | Body runs at least once? | Typical use |
|---|---|---|---|
while (c) S | before each iteration | no | unknown number of iterations |
do S while (c); | after each iteration | yes | input validation, menus |
for (init; c; step) S | before each iteration | no | counting loops |
for (init; c; step) S behaves like init; while (c) { S step; } with one difference: continue inside S jumps to step, not straight to the test. Any of the three parts may be omitted; a missing condition is treated as true, so for (;;) is an infinite loop. Since C99, init may declare variables, whose scope is the loop.

for loop, continue goes to the step expression and break leaves the loop; in while and do-while, continue goes to the test.Jump statements
breakleaves the innermost enclosing loop orswitch. It does not leave anif, and it leaves only one level of nesting.continueskips the rest of the current iteration of the innermost enclosing loop (it has no meaning forswitch). Inwhileanddo-whileit goes to the test; inforit goes to the step.goto label;jumps to a labelled statement in the same function. It is legal but rarely needed; the usual legitimate use is leaving several nested loops or jumping to a common clean-up block.returnends the current function, optionally with a value (Functions and Parameter Passing).
How to trace a loop
- Write the initial values of every variable the loop reads.
- For each iteration, evaluate the test with the current values, run the body, then the step.
- Stop at the first failed test; record the final values. The loop variable of a
forloop usually ends one step past the last value for which the body ran. - For counting questions, find a formula and check it on small inputs.
Counting iterations
Let be an integer.
| Loop | Body executions | Reason |
|---|---|---|
for (i = 0; i < n; i++) | ||
for (i = 1; i <= n; i *= 2) | ||
for (i = n; i > 0; i /= 3) | integer division by 3 until 0 | |
for (i = 1; i * i <= n; i++) | runs to the largest square root | |
for (i = 0; i < n; i++) for (j = i; j < n; j++) | inner runs times | |
for (i = 0; i < n; i++) for (j = 0; j < i; j++) | inner runs times |
For the first four give 100, 7, 5 and 10, and the nested loop gives 5050. In the division loop, takes the values 100, 33, 11, 3, 1; integer division makes iterations. Asymptotic costs of such loops are treated in Complexity Analysis of Loops and Space.
Worked examples
All outputs below are for C11 with gcc on x86-64 Linux (LP64).
Example 1 (switch fall-through).
for (int x = 1; x <= 4; x++) {
switch (x) {
case 1: printf("one ");
case 2: printf("two "); break;
case 3: printf("three ");
default: printf("other ");
}
printf("| ");
}Output: one two | two | three other | other | . For x = 1 execution falls from case 1 into case 2 and stops at its break. For x = 3 it falls into default.
Example 2 (continue and break in a for loop).
int s = 0;
for (int k = 1; k <= 10; k++) {
if (k % 3 == 0) continue; /* skip 3, 6, 9: goes to k++ */
if (k > 8) break; /* leave the loop at k = 10 */
s += k;
}The body adds 1, 2, 4, 5, 7, 8, so s is 27. At continue runs first; at break ends the loop.
Example 3 (do-while versus while). do { n++; } while (0); runs once; while (0) { w++; } runs zero times.
Example 4 (assignment as a condition). int x = 5, cnt = 0; while (x = 0) cnt++; assigns 0 to x; the condition's value is 0, so the body never runs. Final: x = 0, cnt = 0.
Example 5 (comma operator in a for loop). for (i = 0, j = 10; i < j; i += 3, j -= 2) ; passes through and stops with i = 6, j = 6.
Example 6 (leaving nested loops).
int found = 0;
for (int a = 1; a <= 3 && !found; a++)
for (int b = 1; b <= 3; b++)
if (a * b == 4) { found = a * 10 + b; break; }The break leaves only the inner loop; the !found test stops the outer one. The first pair with product 4 is , so found is 22.
goto, labelled loops and multi-level exit
C's goto targets a label in the same function. It may cross ordinary nested blocks, but shall not jump from outside into the scope of an identifier having a variably modified type (C11 6.8.6.1). This is a scope restriction, not merely a ban on skipping initializers; skipping an ordinary initialization can instead leave a later read invalid.
Pattern. A small program may use goto to build a loop or to break out of two levels of nesting. Trace it exactly as written; do not rewrite it into while in your head before counting iterations. Nested break leaves only the innermost loop; goto is the portable way in C to leave two levels without a flag variable.
Important properties and observations
- An
elsematches the nearest unmatchedif; braces override. switchneeds an integer expression and integer constant case labels; withoutbreak, control falls through.do-whilealways runs its body at least once and ends with a semicolon.continuein aforloop runs the step expression; inwhileit goes directly to the test.breakexits only one level, and only loops andswitch.- A stray semicolon after
for (...)orwhile (...)makes an empty body. if (x = 5)is an assignment, always true;if (x == 5)is a comparison.
Loop arithmetic convention. Iteration-count tables above use mathematical unbounded integers, with positive integer n. They are not safe C templates without representability checks, including the final update. For C doubling, after each body use if (i > n / 2) break; before i *= 2; for positive square-test loops use i <= n / i, not i * i <= n. The loop variable must also be wide enough for its remaining updates.
GATE examination perspective
- Count the prints. Nested loops with dependent bounds; use the iteration table and confirm with .
- Doubling and halving loops give logarithmic counts; be exact about
<versus<=and about the starting value ( withi *= 2never terminates). - Fall-through traces in
switchwithoutbreak, anddefaultplaced in the middle. - Dangling
elsewith misleading indentation. - Final value of the loop variable after the loop, especially with an empty body.
Summary
Sources
- ISO/IEC 9899:2011 (C11), committee draft N1570, (consulted 2026-11-09): Section 6.8.4 (selection statements, including 6.8.4.2 on switch), 6.8.5 (iteration statements), 6.8.6 (jump statements).
- B. W. Kernighan and D. M. Ritchie, The C Programming Language, 2nd ed., Prentice Hall, 1988: Chapter 3 (control flow).