#047 – Chained, independent, and nested ifs

Everyone’s familiar with if/else conditional statements.

However, there are three variants that differ slightly:

  1. chained (if/else if)
  2. Independent (multiple ifs)
  3. Nested (if inside if)

Chained vs. independent: a side-by-side

Consider two functions modelling a security system. securityPriority() uses a chained if/else if; securityDiagnostic() uses independent ifs.

#include <iostream>

void securityPriority(bool intruder, bool windowOpen, bool motion) {
    std::cout << "Priority System:   ";
    if (intruder) 
        std::cout << "[POLICE CALLED]";
    else if (windowOpen) 
        std::cout << "[WINDOW ALERT]";
    else if (motion) 
        std::cout << "[LIGHTS ON]";

    std::cout << '\\n';
}

void securityDiagnostic(bool intruder, bool windowOpen, bool motion) {
    std::cout << "Diagnostic System: ";
    if (intruder) 
        std::cout << "[POLICE CALLED] ";
    if (windowOpen) 
        std::cout << "[WINDOW ALERT] ";
    if (motion) 
        std::cout << "[LIGHTS ON] ";

    std::cout << '\\n';
}

int main() {
    securityPriority(true, false, true);
    securityDiagnostic(false, true, true);
}

// Terminal
Priority System:   [POLICE CALLED]
Diagnostic System: [WINDOW ALERT] [LIGHTS ON] 

In the first function, which is a if/else if block despite the third argument being true, [LIGHTS ON] didn’t print. This is because the first if statement failed. Thus, subsequent statements do not get evaluated. Thus, the conditional statements form a sort of hallway. A door can only be opened if the previous door is open.

An intruder takes precedence over an open window, which takes precedence over motion.

This is useful when the outcomes are mutually exclusive e.g. a student cannot get a C and an A on the same test.

The 2nd function implements an if/if/if block. In this instance, the order of the conditional statements doesn’t matter. Each parameter is test independently of the others. The lights can be enabled without the police being called.

Additionally, there is a performance consideration. In an if/else if chain only evaluates one condition. A if/if/if block evaluates them all.

Nested ifs: narrowing the check

Thus, the conditional statements form a sort of funnel.

Multiple if statements can be used to test a condition repeatedly.

#include <iostream>

int main() {
    std::cout << "Enter a number: ";
    int n{};
    std::cin >> n;

    if (n > 0 && n < 50) {
        if (n % 2 == 0 && n % 3 == 0) {
            std::cout << "In range, even, and divisible by 3\\n";
        } else {
            std::cout << "In range, but not both even and divisible by 3\\n";
        }
    } else {
        std::cout << "Out of range\\n";
    }
}

// Output
Enter a number: 12
In range, even, and divisible by 3

The outer if filters for the valid range. Only inside that branch does the divisibility check run. This can be used to build layers of successive checks.

In Summary

Conditional blocks are frequently used. Choose the right variant for the job.

  1. if/else if when the cases are mutually exclusive
  2. if/if when they are not
  3. Nested when one condition is a precondition for the next.