Cracking C++ (5): Conditional Statement

lamoon·2025년 8월 3일

Cracking C++

목록 보기
5/8

if/else Statements

if (i > 4) { 
	// Do sth 
} else if (i > 2) {
	// Do sth else
} else { // Do sth else }
  • must be a Boolean value or evaluate to Boolean value
    • 0 = false, non-zero = true

Initializers for if Statements

Format

if (<initializer>; <conditional_expression>) {
	<if_body>
} else if (<else_if_expression>){
	<else_if_body>
} else { <else_body>}

Example
if (Employee employee { getEmployee() }; employee.salary > 1000) { ... }

The Conditional Operator

  • aka ternary operator.
  • “If [something], then [perform action], otherwise [perform some other action].”
    cout << ((i > 2) ? "yes" : "no");

Logical Operators

OperatorDescriptionUsage
<, <=, >, >=Relational comparisons (same as math)if (i < 0) { … }
==Equalityif (i == 3) { … }
!=Inequalityif (i != 3) { … }
<=>Three-way comparison (spaceship)auto r = i <=> 0;
!Logical NOTif (!flag) { … }
&&Logical ANDif (a && b) { … }
\|\|Logical ORif (a \|\| b) { … }
  • C++ uses short-circuit logic when evaluating logical expressions (if final result is certain, rest of expression is not considered)
    • bool result { bool1 || bool2 || (i > 7) || (27 / 13 % i + 1) < 2 };
      • If bool1 is true, rest is not checked <
      • Better for performance but potential source of bugs
    • Can be useful in context of pointers to avoid parts of expressions to be executed wehn pointer is not valid

Three-Way Comparisons (C++20)

  • <=> (spaceship operator): can tell whether value is equal, less than or greater than another value
  • Cannot be boolean since it returns more than true or false - returns enumeration-like type defined in <compare> and in the std namespace
  • returns either std::strong_ordering (for integrals operand), std::weak_ordering (for custom-defined types), or std::partial_ordering (for floating-point types) (example 1)
    • In <compare> header, there's predicates s.t. we don't have to write strong_ordering::less every time (example 2)
      Example 1
int i { 11 }; 
    strong_ordering result { i <=> 0 }; 
    if (result == strong_ordering::less) { 
        cout << "less" << endl; } 
    if (result == strong_ordering::greater) { 
        cout << "greater" << endl; } 
    if (result == strong_ordering::equal) { 
        cout << "equal" << endl; }

Example 2

#include <compare>
using namespace std;

int main() {
    int i{11};

    // 1) Use the spaceship operator; it yields a strong_ordering
    strong_ordering result = (i <=> 0);

    // 2) Interpret that ordering with the helper functions:
    if (is_lt(result))    cout << "i is less than 0\n";
    if (is_eq(result))    cout << "i is equal to 0\n";
    if (is_gt(result))    cout << "i is greater than 0\n";

    return 0;
}

switch Statements

  • must be of an integral type (int, char, etc.) , a type convertible to an integral type (bool), enumerated type, or strongly typed enumeration (enum class), and must be compared to constants
  • Can also use initializers: switch (<initializer>; <expression>) { <body> }

Fallthrough

  • Fallthrough: continuation of execution of case expression even though it's been caught at some point
    • Example 1 will go through Standard and Default even though if it gets caught in Standard
    • Can be source of bugs if break not implemented correctly. Compiler will usually issue warning, but if this is intentional, use [[fallthrough]] to tell compiler this is intentional (example 2)

Example 1

enum class Mode { Default, Custom, Standard };

int main() {
    int value { 42 };
    Mode mode { /* ... */ };

    switch (mode) {
        using enum Mode; // Allows direct use of enum values without qualification

        case Custom:
            value = 84;
            break; // Added break to prevent fallthrough

        case Standard:
        case Default:
            // Do something with value
            std::cout << "Value: " << value << std::endl;
            break;
    }

    return 0;
}

Example 2

switch (mode) {
        using enum Mode; // Allows direct use of enum values without qualification

        case Custom:
            value = 84;
            [[fallthrough]];

        case Standard:
        case Default:
            // Do something with value
            std::cout << "Value: " << value << std::endl;
            break;
    }

0개의 댓글