Search Knowledge

© 2026 LIBREUNI PROJECT

C Programming Mastery / Program Logic

Control Flow and Branching Logic

The Concept of Selection

Control flow determines the path execution takes through a program. In C, branching is achieved primarily through if-else constructs and switch statements. Unlike high-level languages with dedicated bool types, C treats logic as a numerical property.

Truthiness: The Zero Rule

In C, there is no native boolean type in the core language (prior to C99’s <stdbool.h>). The rules for truth are simple:

  • 0 (Zero) is False. This applies to integers, floating-point numbers, and the NULL pointer.
  • Anything Non-Zero is True. This includes negative numbers.
if (5) { /* This will always execute */ }
if (0) { /* This will never execute */ }
if (-1) { /* This will execute! */ }

The if-else Construct

The if statement evaluates an expression. If it is non-zero, the following block executes.

Dangling Else Problem

When nesting if statements, an else always associates with the nearest preceding if that doesn’t have an else. This can lead to logic errors if braces are omitted.

if (a > 0)
    if (b > 0)
        do_thing();
else // This else belongs to (b > 0), not (a > 0)!
    do_other_thing();

Best Practice: Always use curly braces {} to avoid ambiguity and improve maintainability.

The switch Statement and Jump Tables

The switch statement is used for multi-way branching based on an integer constant.

switch (expression) {
    case CONSTANT_1:
        // statement
        break;
    case CONSTANT_2:
        // statement
        break;
    default:
        // statement
}

Performance: why use Switch?

When a switch has many cases, the compiler often optimizes it using a Jump Table. Instead of checking every condition sequentially (as in an if-else if chain), the CPU can jump directly to the correct code block using an offset in an array of addresses. This makes switch statements in terms of time complexity in many scenarios.

Fall-through Behavior

Unlike modern languages (like Swift or Go), C cases “fall through” by default. If you omit the break keyword, execution continues into the next case. This is occasionally useful for mapping multiple inputs to the same output:

Interactive Lab

Fall-through Logic

switch(input) {
    case 'y':
    case 'Y':
        confirmed = 1;
        ;
    case 'n':
        confirmed = 0;
        break;
}

Branch Prediction and Performance

Modern CPUs use Branch Predictors to guess the outcome of if statements before they are fully evaluated. This allows the CPU to pre-fetch instructions.

  • Predictable Branches: If a branch is almost always true (e.g., checking for errors that rarely occur), the CPU stays fast.
  • Mispredictions: If a branch’s outcome is random (e.g., processing unsorted data), the CPU must flush its pipeline when it guesses wrong, leading to a significant performance hit.
Runtime Environment

Interactive Lab

1#include <stdio.h>
2 
3int main() {
4 int x = 10;
5 // Using ternary for compact branching
6 const char* result = (x % 2 == 0) ? "Even" : "Odd";
7 printf("Number %d is %s\n", x, result);
8 return 0;
9}
System Console

Waiting for signal...