C if else Statement - Conditional Logic Decision Making Guide 2026
|

C if else Statement: Conditional Branching Complete Guide 2026

C if else Statement

Programs need to make decisions. Should the user see an error message or a success screen? Is the password correct or wrong? Does the sensor reading exceed the safety threshold? Every decision in a C program is handled by conditional statements, and the if statement is the most fundamental one.

The if statement evaluates a condition — an expression that resolves to true (non-zero) or false (zero) — and executes a block of code only when that condition is true. Combined with else and else if, you can build decision trees that handle any number of scenarios.

Basic if Statement

The simplest form evaluates one condition:

#include <stdio.h>

int main(void) {
    int temperature = 38;

    if (temperature > 37) {
        printf("Warning: fever detected!\n");
    }

    printf("Temperature: %d°C\n", temperature);
    return 0;
}

If temperature is greater than 37, the warning prints. Regardless of the condition, the temperature line always executes because it is outside the if block. The curly braces {} define the block of code controlled by the if.

How C Evaluates Conditions

In C, there is no dedicated boolean type in the traditional sense (before C99). Instead, C uses integers: zero is false, and any non-zero value is true. This means these are all valid conditions:

int x = 5;

if (x)         // true, because x is non-zero
if (x > 0)     // true, explicit comparison
if (x == 5)    // true, equality check
if (x != 0)    // true, same as just (x)

// Pointers
int *ptr = &x;
if (ptr)       // true if ptr is not NULL
if (ptr != NULL) // same thing, more explicit

This zero/non-zero convention is deeply embedded in C. Functions often return 0 for failure and non-zero for success (or vice versa), and you will see if (ptr) instead of if (ptr != NULL) in idiomatic C code.

if else Statement

The else clause executes when the condition is false:

int age = 16;

if (age >= 18) {
    printf("You can vote.\n");
} else {
    printf("You cannot vote yet.\n");
}

Exactly one of the two blocks executes — never both, never neither. This is a binary decision: the condition is either true or false.

else if Chains

For multiple conditions, chain else if clauses:

int score = 75;

if (score >= 90) {
    printf("Grade: A\n");
} else if (score >= 80) {
    printf("Grade: B\n");
} else if (score >= 70) {
    printf("Grade: C\n");
} else if (score >= 60) {
    printf("Grade: D\n");
} else {
    printf("Grade: F\n");
}

C evaluates conditions from top to bottom and executes the first matching block. Once a match is found, all remaining else if and else blocks are skipped. Order matters — if you put score >= 60 first, a score of 95 would get grade D instead of A.

Why Order Matters

// WRONG: every passing score gets D
if (score >= 60) {
    printf("D\n");
} else if (score >= 70) {
    printf("C\n");  // never reached for 70+ scores
} else if (score >= 80) {
    printf("B\n");  // never reached
}

// CORRECT: check from highest to lowest
if (score >= 90) {
    printf("A\n");
} else if (score >= 80) {
    printf("B\n");
} else if (score >= 70) {
    printf("C\n");
}

Nested if Statements

You can place if statements inside other if statements:

int age = 25;
int has_license = 1;

if (age >= 18) {
    if (has_license) {
        printf("You can drive.\n");
    } else {
        printf("You need a license first.\n");
    }
} else {
    printf("You are too young to drive.\n");
}

However, deeply nested conditions become hard to read. When you find yourself nesting more than 2-3 levels deep, consider refactoring with early returns or combining conditions with logical operators:

// Better: combine conditions
if (age >= 18 && has_license) {
    printf("You can drive.\n");
} else if (age >= 18) {
    printf("You need a license first.\n");
} else {
    printf("You are too young to drive.\n");
}

Single-Line if (Without Braces)

C allows you to omit braces when the if body is a single statement:

if (x > 0)
    printf("Positive\n");

if (x > 0) printf("Positive\n"); // same, on one line

This is legal but dangerous. Adding a second line creates a subtle bug:

// BUG: the second line ALWAYS executes
if (x > 0)
    printf("Positive\n");
    printf("Processing...\n");  // not inside the if!

The indentation is misleading — only the first printf is controlled by the if. The second printf always runs. This exact bug caused the famous Apple “goto fail” SSL vulnerability in 2014. Always use braces, even for single-line bodies.

The Dangling else Problem

When you have nested if statements without braces, else binds to the nearest if:

// Which if does the else belong to?
if (a > 0)
    if (b > 0)
        printf("Both positive\n");
else
    printf("This runs when b <= 0, NOT when a <= 0!\n");

Despite the indentation suggesting the else pairs with the outer if, C pairs it with the inner if. The fix is always braces:

if (a > 0) {
    if (b > 0) {
        printf("Both positive\n");
    }
} else {
    printf("a is not positive\n");  // now correctly paired
}

Common Pitfall: Assignment vs Comparison

The most notorious C bug is using = (assignment) instead of == (comparison):

int x = 5;

// BUG: assigns 10 to x, then evaluates as true (10 != 0)
if (x = 10) {
    printf("This always runs! x is now %d\n", x);
}

// CORRECT: compares x to 10
if (x == 10) {
    printf("x is ten\n");
}

The assignment x = 10 is an expression that evaluates to 10 (the assigned value), which is non-zero (true). So the if body always executes, and x gets silently changed to 10.

Compile with -Wall and GCC warns: "suggest parentheses around assignment used as truth value." Some teams use the "Yoda condition" style — if (10 == x) — because if (10 = x) would be a compiler error. However, modern compilers catch this with -Wall, so Yoda conditions are less necessary today.

Combining Conditions with Logical Operators

Use && (AND), || (OR), and ! (NOT) to build complex conditions:

int age = 25;
int income = 50000;
int credit_score = 720;

// All conditions must be true
if (age >= 18 && income > 30000 && credit_score >= 700) {
    printf("Loan approved\n");
}

// At least one condition must be true
if (age < 18 || age > 65) {
    printf("Special pricing available\n");
}

// Negation
int is_blocked = 0;
if (!is_blocked) {
    printf("Access granted\n");
}

Short-Circuit Evaluation in Practice

C stops evaluating a logical expression as soon as the result is known. This is not just an optimization — it is a safety pattern:

// Safe null-pointer check
// If ptr is NULL, ptr->value is never accessed
if (ptr != NULL && ptr->value > 100) {
    printf("High value: %d\n", ptr->value);
}

// Safe division
// If divisor is 0, the division never happens
if (divisor != 0 && (number / divisor) > threshold) {
    printf("Ratio exceeds threshold\n");
}

Without short-circuit evaluation, the second condition would crash the program (null pointer dereference or division by zero). This pattern appears constantly in production C code.

Conditional Expressions as Variables

You can store comparison results in variables:

int a = 10, b = 20;
int is_greater = (a > b);  // 0 (false)
int is_equal = (a == b);   // 0 (false)
int is_valid = (a > 0 && b > 0); // 1 (true)

printf("is_greater: %d\n", is_greater);
printf("is_valid: %d\n", is_valid);

This is useful when you need to check the same condition multiple times, or when you want to make complex conditions more readable by giving them descriptive names.

Practical Example: Simple Login System

#include <stdio.h>
#include <string.h>

int main(void) {
    char username[50];
    char password[50];
    int attempts = 3;

    while (attempts > 0) {
        printf("Username: ");
        scanf("%49s", username);
        printf("Password: ");
        scanf("%49s", password);

        if (strcmp(username, "admin") == 0 &&
            strcmp(password, "secret123") == 0) {
            printf("Login successful! Welcome, %s.\n", username);
            return 0;
        } else {
            attempts--;
            if (attempts > 0) {
                printf("Invalid credentials. %d attempt(s) remaining.\n",
                       attempts);
            } else {
                printf("Account locked. Too many failed attempts.\n");
                return 1;
            }
        }
    }
    return 1;
}

This example combines if/else with a while loop (covered in a later lesson), string comparison with strcmp, and early returns to exit the program on success or lockout.

Best Practices for if else Statements

Always use braces, even for single-line bodies. Put the most likely condition first for readability. Use early returns to reduce nesting. Give complex conditions descriptive variable names. Never use assignment (=) inside conditions unless you specifically intend to and wrap it in extra parentheses. Compile with -Wall -Wextra to catch common mistakes.

What Comes Next

The if/else chain handles any number of conditions, but when you are comparing a single variable against many fixed values, the switch statement is cleaner and faster. The next lesson covers switch & Ternary — multi-way branching and compact conditional expressions.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *