Beginner's Guide
    First Steps
    Input & Output
    Basic Custom Types
    Diagnostics
    Standard Library
    Code Organization
    Powerful Custom Types
    Generic Programming
    Memory Management
    Software Design Basics

    Control Flow (Basics)Control Flow (Basics)Control Flow

    Terminology: Expression / Statement Terminology

    Expressions
    • series of computations (operators + operands)
    • may produce a result
    Statements
    • program fragments that are evaluated in sequence
    • do not produce a result
    • can contain one or multiple expressions
    • delimited by ; and grouped by { }

    Conditional Branching Branching

    if (condition1) {
      // do this if condition1 is true
    }
    else if (condition2) {
      // else this if condition2 is true
    }
    else {
      // otherwise do this
    }
    • code is (not) executed based on result of condition
    • result of condition expression must be (convertible to) a boolean value
    • conditions will be checked from top to bottom
    if (true) { cout << "yes"; }  // yes
    if (23)   { cout << "yes"; }  // yes (23 → true)
    if (0)    { cout << "yes"; }  // yes (0 → false)
    
    int i = 0; cin >> i; if (i < 0) { cout << "negative"; } else if (i == 0) { cout << "zero"; } else { cout << "positive"; }
    if(statement; condition) { … }  

    useful for limiting the scope of temporary variables

    int i = 0;
    cin >> i;
    if ( int x = 2*i; x > 10) { cout << x; }

    Switching: Value-Based Branching Switching switch

    • over values of integer types (char, int, long, enums, …)
    • checked & executed from top to bottom
    • executes everything between matching case and next break (or the closing })
    int i = 0;
    cin >> i;
    int m = a % 5;
    switch (m) {
      case 0:   // do this if m is 0
        break;
      case 1:   // do this if m is 1
      case 3:   // do this if m is 1 or 3
        break;
      default:  // do this if m is not 0, 1 or 3
    }
    switch (statement; variable) { … }  

    useful for limiting the scope of temporary variables

    int i = 0;
    cin >> i;
    switch (int k = 2*i; k) { … }

    Ternary Conditional Operator Ternary Conditional ?: Operator

    Result = Condition ? If-Expression : Else-Expression
    int i = 8;
    int j = i > 10 ? 1 : 2;   
    
    int k = 20; int l = (k > 10) ? 1 : 2;
    int b = true; double d = b ? 2.0 : 0.5; double e = !b ? 2.0 : 0.5;
    
    j: 2
    
    l: 1
    d: 2.0 e: 0.5

    Loop Iteration Loops

    for (variable : range) { … }

    range = object with standard iterator interface, e.g., std::vector

    std::vector<int> v {1,2,3,4,5};
    // print all elements of vector to console
    for (int x : v)  { cout << x << '\n'; }
    for (initialization; condition; step) { … }
    // prints 0 1 2 3 4
    for (int i = 0; i < 5; ++i) {
      cout << i << ' ';
    }
    while (condition) { … }

    first check of condition: before first loop iteration

    int j = 5;  
    while (j < 10) {
      cout << j << ' ';
      ++j;
    }
    
    as long as j < 10
    prints 5 6 7 8 9
    
    
    do { … } while (condition);

    first check of condition: after first loop iteration

    int j = 10;
    do { 
      cout << j << ' ';
      --j;
    } while (j > 0);
    
    
    prints 10 9 8 … 1
    
    executed until j ≤ 0
    • Only write loops if there is no (standard) library function/algorithm for what you want to do (we will learn about the standard library in later chapters)!
    • Prefer range-based loops over all other types of loops! (no indexing/condition bugs possible)
    • Use (do) while loops only, if the number of iterations is not known beforehand!