Skip to main content

Control Flow

Conditional Control Statements

Master Types of if Statements and the Switch Statement using LEARNCODEGURU’s 6-level learning model.

Level 1 Basics Content

C Conditionals Overview

Decision making (also called conditional control flow) lets a program choose different paths based on conditions. In C, the main tools are the family of if statements and the switch statement.

This level covers every major form of if, when to use each, then switch with case, break, and default — plus one complete sample program.

Topic 1

Overview — decision making & control flow

Programs are not only sequential. Conditions test expressions that are true (non-zero) or false (zero), then run the matching statements. That is the heart of control flow for decisions.

  • Condition — a relational / logical expression (e.g. marks >= 40)
  • Branch — the block that runs when the condition matches
  • if family — flexible for ranges, compound logic, nested checks
  • switch — clear when one value maps to many discrete alternatives
Decision making in C: a condition is evaluated as true or false, and control flows to the matching branch — covering simple if, if-else, else-if ladder, nested if, and the switch statement.
Decision making in C — how a condition selects the branch that runs
Evaluate condition → true path / false path → continue program
Topic 2

Simple if

A simple if runs a statement (or block) only when the condition is true. If the condition is false, that body is skipped and execution continues after the if.

Syntax:


if (condition) {
    /* statements when condition is true */
}

Example:


int n = 12;
if (n > 0)
    printf("Positive\n");
Use when: you only need to act on the true case and have nothing special for false.
Topic 3

if-else

if-else chooses exactly one of two paths: the if body when true, or the else body when false.

Syntax:


if (condition) {
    /* true branch */
} else {
    /* false branch */
}

Example — even / odd:


if (n % 2 == 0)
    printf("Even\n");
else
    printf("Odd\n");
Use when: there are exactly two mutually exclusive outcomes (pass/fail, even/odd).
Topic 4

Nested if

A nested if places an if inside another if (or else). Use it when a second decision depends on the first being true.

Syntax idea:


if (condition1) {
    if (condition2) {
        /* both true */
    }
}

Example:


if (age >= 18) {
    if (marks >= 40)
        printf("Eligible\n");
    else
        printf("Adult but marks low\n");
} else {
    printf("Underage\n");
}
Use when: decisions are hierarchical (must pass gate A before checking B). Prefer braces.
Topic 5

if-else-if ladder

An if-else-if ladder checks conditions in order and runs the first true branch, then skips the rest. Ideal for mutually exclusive ranges such as grades.

Syntax:


if (condition1) {
    /* branch 1 */
} else if (condition2) {
    /* branch 2 */
} else {
    /* none matched */
}

Example — grades:


if (marks >= 90)
    printf("Grade A\n");
else if (marks >= 75)
    printf("Grade B\n");
else if (marks >= 60)
    printf("Grade C\n");
else
    printf("Grade F\n");
Use when: many exclusive alternatives based on ranges or ordered checks.
Topic 6

Comparison — when to use each if form

Form Best for Avoid when
if Optional action; false does nothing You need an explicit false branch
if-else Exactly two outcomes Many ordered ranges (use ladder)
Nested if Dependent / hierarchical checks Deep nesting without braces (hard to read)
if-else-if Mutually exclusive ranges / categories One discrete value among many labels (prefer switch)
  • Prefer else-if ladders over deep nesting for grade/slab problems
  • Prefer nested if when later checks only make sense after an earlier gate
  • Always use braces so structure stays clear
Topic 7

Switch statement — syntax, case, break, default

switch compares one integral expression against a list of constant case labels. break exits the switch; default handles values that match no case.

Syntax:


switch (expression) {
    case constant1:
        /* statements */
        break;
    case constant2:
        /* statements */
        break;
    default:
        /* optional */
        break;
}

Example — day of week:


switch (day) {
    case 1: printf("Monday\n"); break;
    case 2: printf("Tuesday\n"); break;
    case 3: printf("Wednesday\n"); break;
    case 4: printf("Thursday\n"); break;
    case 5: printf("Friday\n"); break;
    case 6: printf("Saturday\n"); break;
    case 7: printf("Sunday\n"); break;
    default: printf("Invalid day\n"); break;
}
Topic 8

Switch case rules (quick table)

Element Rule Purpose
case label Must be a unique constant expression Marks the entry point for a matching value
break Exits the switch immediately Prevents falling into the next case
default Optional; runs when no case matches Handles invalid / unexpected values
Controlling expression Integral type (int, char, enum, …) Value compared against each case
Beginner tip: after every case body, write break; unless you intentionally want fall-through (covered in Level 2).
Example

Sample program — if-else-if grade ladder

This complete program reads marks and prints a letter grade using an if-else-if ladder:


/* Conditionals — if-else-if grade sample */
#include <stdio.h>

int main(void) {
    int marks;

    printf("Enter marks (0-100): ");
    scanf("%d", &marks);

    if (marks >= 90)
        printf("Grade A\n");
    else if (marks >= 75)
        printf("Grade B\n");
    else if (marks >= 60)
        printf("Grade C\n");
    else if (marks >= 40)
        printf("Grade D\n");
    else
        printf("Grade F\n");

    return 0;
}
What to observe: conditions are checked top-down; the first true branch wins. Order matters — put higher thresholds first.

Level 2 Advanced Content

Going deeper into conditionals

Level 1 showed the forms. Level 2 explains how conditions are evaluated, the dangling-else problem, switch fall-through and limitations, when to prefer switch vs if-else-if, and the most common mistakes.

Topic 1

Boolean expressions — relational & logical operators

Conditions use relational operators (== != < > <= >=) and logical operators (&& || !). In C, zero is false; any non-zero value is true.

  • if (a > 0 && a < 100) — both must be true (short-circuit)
  • if (ch == 'y' || ch == 'Y') — either is enough
  • if (!done) — true when done is zero
  • Prefer == for equality; never confuse with assignment =
Short-circuit: if the left of && is false, the right is not evaluated — useful for safe checks like ptr != NULL && *ptr == 0.
Topic 2

The dangling else problem

An else always binds to the nearest unmatched if. Without braces, that can surprise you:


if (a)
    if (b)
        printf("both\n");
else
    printf("which if?\n");  /* belongs to if (b) */

Fix with braces so intent is unmistakable:


if (a) {
    if (b)
        printf("both\n");
} else {
    printf("a was false\n");
}
Rule: always brace nested if/else. Interviewers love dangling-else questions.
Topic 3

Nested if vs else-if ladder — clarity

  • else-if ladder — exclusive alternatives; only one branch runs; easy to scan
  • Nested if — later tests depend on earlier success; structure mirrors hierarchy
  • Deep nesting without ladders often means you should flatten into else-if or extract functions
  • For grades/slabs, ladders almost always read better than nested ifs
Topic 4

Switch fall-through — intentional vs accidental

Without break, control falls through to the next case. That can be intentional (shared logic) or accidental (bug).

Intentional fall-through:


switch (code) {
    case 1:
    case 2:
    case 3:
        printf("Low priority\n");
        break;
    default:
        printf("Other\n");
}
Accidental fall-through usually happens when someone forgets break after a full case body. Always review every case for a break (or a comment marking intentional fall-through).
Topic 5

Switch limitations

  • Controlling expression: integral types / char / enums — not float or double
  • case labels must be constant expressions (not variables)
  • No ranges like case 1 ... 10: in standard C (use if-else-if for ranges)
  • Strings cannot be switched directly — compare with strcmp and if/else
Topic 6

switch vs if-else-if — when to choose

Prefer When Example
switch One discrete value, many constant labels Day number, menu choice, enum state
if-else-if Ranges, floats, complex boolean logic Marks ≥ 90 / ≥ 75 / ≥ 60
Either Small set of equality checks on ints/chars Operator +/- menu
Topic 7

Common mistakes

  • Using = instead of == inside conditions
  • Missing break in switch (unwanted fall-through)
  • Semicolon after if (cond); creating an empty body
  • Forgetting braces → dangling else or wrong nesting
  • Trying to switch on a float or a variable case label
Topic 8

Optional flowchart — if-else-if grade flow

Visual path for assigning a grade from marks:

1 Read marks Input score from the user
2 marks ≥ 90? Yes → Grade A; No → next check
3 marks ≥ 75? then ≥ 60? … First true branch wins; rest skipped
4 else → Grade F No higher band matched

Level 3 C Tricky Interview Points

Advanced tricky interview points on if / else, dangling else, switch fall-through, = vs ==, and switch limitations.

Tricky Interview Point-1:

if (x = 0) is always false — assignment, not comparison

A single = assigns 0 to x and the condition value is 0 (false), so the if body never runs. Use == for comparison. Many compilers warn; treat this as a classic interview trap.

Tricky Interview Point-2:

Dangling else binds to the nearest unmatched if

In if (a) if (b) stmt1; else stmt2; the else belongs to if (b), not if (a). Always use braces { } to make nesting explicit and avoid this ambiguity.

Tricky Interview Point-3:

Missing break causes accidental fall-through

Without break, execution continues into the next case. That is intentional only when you design shared logic; otherwise it is a bug. Interviewers ask you to predict output with missing breaks.

Tricky Interview Point-4:

switch cannot test float or string ranges directly

The controlling expression must be an integral type (int, char, enum, etc.). You cannot switch on float/double, and case labels must be constant expressions — not variables or ranges like case 1..5.

Tricky Interview Point-5:

default is optional and need not be last

If no case matches and there is no default, the switch does nothing. Putting default in the middle is legal but confusing; still use break if you do not want fall-through into later cases.

Tricky Interview Point-6:

case labels must be unique compile-time constants

Duplicate case values are a compile error. Labels cannot be variables: case n: is invalid. Enums and character constants like case 'A': are fine.

Tricky Interview Point-7:

Empty if body with a trailing semicolon is a silent bug

if (n > 0); { printf("positive"); } — the semicolon ends the if with an empty statement, so the block always runs. Never put ; immediately after if (...) or while (...).

Tricky Interview Point-8:

Nested if vs else-if ladder changes which conditions run

An else-if ladder checks conditions in order and stops at the first true branch. Deep nested ifs can re-check or skip paths differently. Prefer else-if for mutually exclusive ranges (grades, tax brackets).

Tricky Interview Point-9:

Boolean in C is historically 0 / non-zero

Any non-zero value is true; zero is false. if (ptr) is idiomatic for non-null. C99 adds _Bool / bool from <stdbool.h>, but conditions still follow the zero / non-zero rule.

Tricky Interview Point-10:

switch fall-through can be intentional for shared actions

case 1: case 2: case 3: printf("low"); break; is a valid pattern — several labels share one body. Document intentional fall-through; accidental fall-through is a defect.

Tricky Interview Point-11:

Relational results are 0 or 1, usable in expressions

a > b yields 1 if true, 0 if false. You can write count += (x > 0); but prefer clear if statements in beginner code. Mixing assignment and comparison still trips people up.

Tricky Interview Point-12:

Prefer braces even for one-line if bodies

if (ok) doSomething(); looks fine until someone adds a second line without braces. Consistent braces prevent dangling-else bugs and make reviews safer — a common “best practice” interview answer.

Interview tip: When predicting switch output, locate the matching case first, then walk downward until a break. For nested if, bind each else to the nearest unmatched if — or insist on braces.

Level 4 Simple Programs

Short programs demonstrating if-else, if-else-if, and switch.

Program 1 — if-else (even / odd)


/* if-else: even or odd */
#include <stdio.h>

int main(void) {
    int n;

    printf("Enter an integer: ");
    scanf("%d", &n);

    if (n % 2 == 0)
        printf("%d is even\n", n);
    else
        printf("%d is odd\n", n);

    return 0;
}

Program 2 — if-else-if ladder (grades)


/* if-else-if ladder: letter grade */
#include <stdio.h>

int main(void) {
    int marks;

    printf("Enter marks: ");
    scanf("%d", &marks);

    if (marks >= 90)
        printf("Grade A\n");
    else if (marks >= 75)
        printf("Grade B\n");
    else if (marks >= 60)
        printf("Grade C\n");
    else if (marks >= 40)
        printf("Grade D\n");
    else
        printf("Grade F\n");

    return 0;
}

Program 3 — switch (day name)


/* switch: day number to name */
#include <stdio.h>

int main(void) {
    int day;

    printf("Enter day (1-7): ");
    scanf("%d", &day);

    switch (day) {
        case 1: printf("Monday\n"); break;
        case 2: printf("Tuesday\n"); break;
        case 3: printf("Wednesday\n"); break;
        case 4: printf("Thursday\n"); break;
        case 5: printf("Friday\n"); break;
        case 6: printf("Saturday\n"); break;
        case 7: printf("Sunday\n"); break;
        default: printf("Invalid day\n"); break;
    }

    return 0;
}
Comment Directive Type Keyword Function Variable String Number

Level 5 Problem Solving Tricks

How to master conditionals while solving problems

Most conditional bugs come from = vs ==, missing braces, forgotten break, and choosing nested if when an else-if ladder or switch would be clearer. Use these colorful habits every time you write a decision.

Trick 1

Always brace if / else / switch bodies

Write if (cond) { ... } else { ... } even for one statement. Braces kill dangling-else bugs and keep future edits safe when you add logging or a second statement.

Trick 2

Compare with ==; never assign inside conditions by accident

Say the condition aloud: “if n equals zero.” If you wrote =, you assigned. Prefer if (0 == n) only if your team likes Yoda style; clearer habit: pause and verify every = vs ==.

Trick 3

Use else-if for exclusive ranges (grades, slabs)

Marks ≥ 90, else ≥ 75, else ≥ 60 — mutually exclusive buckets fit an else-if ladder. Nested ifs that re-open every range are harder to read and easier to get wrong.

Trick 4

Put break after every case unless fall-through is deliberate

After writing each case body, add break immediately. If you intentionally fall through, leave a short comment: /* fall through */ so reviewers know it is not a mistake.

Trick 5

Choose switch for discrete values; if for ranges and floats

Day numbers, menu choices, and enum states → switch. Score bands, float thresholds, and complex boolean logic → if / else-if. Matching the tool to the problem saves bugs.

Trick 6

Trace switch on paper when breaks are missing

For output questions, circle the matching case, then draw an arrow downward through every following case until a break or the end of the switch. That predicts fall-through output every time.

Trick 7

Keep conditions simple; extract complex tests

If a condition has many && / || parts, compute a named flag first: int eligible = age >= 18 && marks >= 40; if (eligible) .... Named booleans document intent and ease debugging.

Trick 8

Draw a tiny flowchart before coding multi-branch logic

For if-else-if or switch menus, sketch Start → condition → Yes/No paths → End. Coding from the sketch reduces missed branches and forgotten default/else cases.

Quick success checklist

  • Before run: == not =? braces present? every case has break (or intentional fall-through)?
  • Debug order: fix empty if(;); → check nesting/else binding → trace switch fall-through on paper
  • Choose form: ranges → else-if; discrete ints/chars → switch; dependent gates → nested if with braces
Level-5 goal: pick the right conditional form quickly, brace everything, and never ship a switch without reviewing breaks — then loops and functions become easier to reason about.

Level 6 Practice Programs List

Programming questions only — focused on types of if statements and switch.

  1. 1. Write a C program that reads an integer and uses a simple if to print whether it is positive.
  2. 2. Write a C program that uses if-else to check whether a number is even or odd.
  3. 3. Write a C program that uses nested if to check whether a year is a leap year (divisible by 4, with century rules).
  4. 4. Write a C program that uses an if-else-if ladder to assign a letter grade (A/B/C/D/F) from marks.
  5. 5. Write a C program that uses switch to print the day name for a day number 1–7 (with default for invalid input).
  6. 6. Write a C program that shows intentional switch fall-through: map several menu codes to the same message.
  7. 7. Write a C program that demonstrates the dangling-else problem with and without braces (print which branch runs).
  8. 8. Write a C program that compares if-else-if vs switch for a simple calculator menu (+, -, *, /).