Search

7.x — Chapter 7 summary and quiz

Quick review

The specific sequence of statements that the CPU executes in a program is called the program’s execution path. A straight-line program takes the same path every time it is run.

Control flow statements (also called Flow control statements) allow the programmer to change the normal path of execution. When a control flow statement causes the program to begin executing some non-sequential instruction sequence, this is called a branch.

A conditional statement is a statement that specifies whether some associated statement(s) should be executed or not.

If statements allow us to execute an associated statement based on whether some condition is true. Else statements execute if the associated condition is false. You can chain together multiple if and else statements.

A dangling else occurs when it is ambiguous which if statement an else statement is connected to. Dangling else statements are matched up with the last unmatched if statement in the same block. Thus, we trivially avoid dangling else statements by ensuring the body of an if statement is placed in a block.

A null statement is a statement that consists of just a semicolon. It does nothing, and is used when the language requires a statement to exist but the programmer does not need the statement to do anything.

Switch statements provide a cleaner and faster method for selecting between a number of matching items. Switch statements only work with integral types. Case labels are used to identify the values for the evaluated condition to match. The statements beneath a default label are executed if no matching case label can be found.

When execution flows from a statement underneath a label into statements underneath a subsequent label, this is called fallthrough. A break statement (or return statement) can be used to prevent fallthrough. The [[fallthrough]] attribute can be used to document intentional fallthrough.

Goto statements allow the program to jump to somewhere else in the code, either forward or backwards. These should generally be avoided, as they can create spaghetti code, which occurs when a program has a path of execution that resembles a bowl of spaghetti.

While loops allow the program to loop as long as a given condition evaluates to true. The condition is evaluated before the loop executes.

An infinite loop is a loop that has a condition that always evaluates to true. These loops will loop forever unless another control flow statement is used to stop them.

A loop variable (also called a counter) is an integer variable used to count how many times a loop has executed. Each execution of a loop is called an iteration.

Do while loops are similar to while loops, but the condition is evaluated after the loop executes instead of before.

For loops are the most used loop, and are ideal when you need to loop a specific number of times. An off-by-one error occurs when the loop iterates one too many or one too few times.

Break statements allow us to break out of a switch, while, do while, or for loop (also range-based for loops, which we haven’t covered yet). Continue statements allow us to move immediately to the next loop iteration.

Halts allow us to terminate our program. Normal termination means the program has exited in an expected way (and the status code will indicate whether it succeeded or not). std::exit() is automatically called at the end of main, or it can be called explicitly to terminate the program. It does some cleanup, but does not cleanup any local variables, or unwind the call stack.

Abnormal termination occurs when the program encountered some kind of unexpected error and had to be shut down. std::abort can be called for an abnormal termination.

Scope creep occurs when a project’s capabilities grow beyond what was originally intended at the start of the project or project phase.

Software verification is the process of testing whether or not the software works as expected in all cases. A unit test is a test designed to test a small portion of the code (typically a function or call) in isolation to ensure a particular behavior occurs as expected. Unit test frameworks can help you organize your unit tests. Integration testing tests the integration of a bunch of units together to ensure they work properly.

Code coverage refers to how much of the source code is executed while testing. Statement coverage refers to the percentage of statements in a program that have been exercised by testing routines. Branch coverage refers to the percentage of branches that have been executed by testing routines. Loop coverage (also called the 0, 1, 2 test) means that if you have a loop, you should ensure it works properly when it iterates 0 times, 1 time, and 2 times.

The happy path is the path of execution that occurs when there are no errors encountered. A sad path is one where an error or failure state occurs. A non-recoverable error (also called a fatal error) is an error that is severe enough that the program can’t continue running. A program that handles error cases well is robust.

A buffer is a piece of memory set aside for storing data temporarily while it is moved from one place to another.

The process of checking whether user input conforms to what the program is expecting is called input validation.

std::cerr is an output stream (like std::cout) designed to be used for error messages.

A precondition is any condition that must always be true prior to the execution of some segment of code. An invariant is a condition that must be true while some component is executing. A postcondition is any condition that must always be true after the execution of some code.

An assertion is an expression that will be true unless there is a bug in the program. In C++, runtime assertions are typically implemented using the assert preprocessor macro. Assertions are usually turned off in non-debug code. A static_assert is an assertion that is evaluated at compile-time.

Assertions should be used to document cases that should be logically impossible. Error handling should be used to handle cases that are possible.

Quiz time

Warning: The quizzes start getting harder from this point forward, but you can do it. Let’s rock these quizzes!

Question #1

In the chapter 4 comprehensive quiz, we wrote a program to simulate a ball falling off of a tower. Because we didn’t have loops yet, the ball could only fall for 5 seconds.

Take the program below and modify it so that the ball falls for as many seconds as needed until it reaches the ground.

In constants.h:

In your main code file:

Show Solution

Question #2

A prime number is a natural number greater than 1 that is evenly divisible (with no remainder) only by 1 and itself. Complete the following program by writing the isPrime() function using a for loop.

Show Solution


8.1 -- Implicit type conversion (coercion)
Index
7.17 -- Assert and static_assert

851 comments to 7.x — Chapter 7 summary and quiz

  • Struggleboat

    So I'm staring at question 2, and haven't looked at the answer yet, but I honestly have no idea what I'm supposed to do.

    It tells me to rewrite the program with a for loop, but not what the expected result is.
    Am I supposed to cram the asserts into one for loop and remove them?
    Am I supposed to run the loop from 0 up to that number?
    I really, honestly don't know.

    Perhaps this is written under the basic assumption that math is an understood concept by the participants, but I deeply struggle with it to a point I can't intuit what I'm supposed to be doing. It's not that I don't know what prime numbers are, but this seems to imply I have some basic understanding as to how they relate to this program. I had a similar issue with question 1, but since the math was already written previously (I had to refer to the example in chapter 4), I was able to troubleshoot and reset until I figured it out.

    This one, however, doesn't have such an example.  As such, I won't be able to even guess as to what the code should be prior to looking, which is very discouraging.

    Just my two cents.

    Edit: Having looked at it, and having copied and run it, I still felt in the dark as to what exactly the purpose was. I have to assume the concept is that it would have provided an error if a number marked prime was not (or vice versa), but it would've been nice if that were explained or in some way visible.

  • Armando IG

    This worked for me in question #2, but is this not preferable bc of early returns compared to the answer?

    Thanks in advance

    • Alex

      There are three things I find weird about this:
      1) Your loop doesn't execute if x is 0 or 1. Your assert executes in that case, and your code returns 0 despite your comment.
      2) You check if (i==x) in the body of the loop, when this can only be true on the last iteration. Better to have your loop execute one less time and just return true beyond the body of the loop.
      3) The check || (x <= 1) will never be true because the loop doesn't execute when x is less than 2. Here's a riff on your solution:

      • Armando IG

        Thank you! Now I've learned that I've been using assert wrong, I need to check my conditionals better, and don't over complicate my code... Aaand that "mistake * mistake = working code" hahaha

  • William M.

    Is this an incorrect way of solving question #1? It certainly works and it works to extreme values, was just wondering if I'm incorrect in altering the code structure too much compared to how it was presented.

  • UnknownLearner

    My simple example for Quiz 2 here:

  • James C

    Here's my solution for the isPrime quiz:

  • James C

    Using direct initialization and copy initialization in the first quiz question.

  • Erg0Proxy

    The only change I made to the given code file in Question 1.
    I didn't think to change the other program to a bool so I came up with this.
    It feels stupid since the height is basically calculated twice every iteration.
    Any input on this ?

    • Erg0Proxy

      actually a litte shorter after looking at the time variable again

      • nascardriver

        When you don't need a part of an if-statement, you can leave it empty

        You could have turned `calculateAndPrintHeight()` into `printHeight()` and call that in the loop to prevent the duplicate calculation.

  • Hi

    My solution to 1:

  • jawN

    I think you could make 2nd quiz more optimized by changing test <= x to test <= x/2
    there is no way you can divide a number by something bigger than its half

  • ChebCheb

    Just a small thing, but since you always show that you are happy fixing even individual misspellings, this should be ok too.

    At the "Halts"-section, you wrote "std::exit() is called at the end of main". This can be confusing to some, since they never saw it coded there in any lesson. So maybe better write implicitly explicitly (lol), like "std::exit() is called IMPLICITLY at the end of main".

  • Deva_B.D.M.

    my solution for Q#2

  • dodo

    Using a piece of paper and a pen helped a lot for the second quiz.

  • Spectrillius

    Pretty neat seeing Question #1, as that was actually how I solved the problem initially.  
    Ahhh, the little satisfactions huh?

  • Mateusz Kacperski

  • Andrew

    Hi, new programmer here. Is there any reason why I should not solve Question #1 like this:

    I feel like I may be missing the point of what's being taught here.

  • Jay R

    Hey nascar. My solution seems to be more complicated, I think. I know there are many ways to solve the same problem, but I find myself having trouble with finding the most direct path for a solution. Can you offer any suggestions?

    Thank you for your time!

    • nascardriver

      Hey Jay,

      don't worry about not finding a short or pretty solution, that will come with experience. Be proud that you made it work ;)

  • Cesar

    Ok this quiz where super hard. I'm still scratching my head. what you guys recommend me to do? keep going write it as (Come back to chapter 7) when i finish the whole thing. or should i start chapter 7 again? whats the better way? cuz sometimes you learn things on other chapters that you be like ooohhhhh ok. I just want to know your opinion and your ways to learn it better.

    • Cesar Calderon

      NVM i got it. i to took my time. I'm use to seeing the parameters with X and y that when you added names to it it thru me off.

  • John

  • John

  • Vaklin Donchev

    Hello,there.Since  my solution turned out to be different and i lack confedence and knowledge yet,to know what is good and what is not i have to ask. Is my solution  lacking some knowledge  i should know  and was supposed to imply here,after all its not compettition and the purpose is to learn.

    TIPP: just created for loop in calculate and print.

    • nascardriver

      - Initialize variables with list-initialization for higher type-safety
      - Use double literals to avoid accidental integer arithmetic (2.0 instead of 2)
      - Use ++prefix unless you need the return value of postfix++
      - `size_t` is C, `std::size_t` (From the <cstddef> header) is C++
      - Use single quotation marks for characters. Full quotation marks create strings, which are more expensive

      Logic and separation into functions is good :)

  • rony53m

    how this is?

    main(with proper constants header file)

    #include<iostream>
    #include "constants.h"

    void calculation(double x)
    {
        double cheight{ x };
        for (int sec{ 0 }; cheight >= 0; sec++)
        {
            cheight = x - (myconstants::gravity * sec * sec / 2);

            if (cheight < 0)
            {
                std::cout << "current height is 0 meter in " << sec << "seconds \n";
            }
            else
                std::cout << "current height is " << cheight << " meter in " << sec << "seconds\n";

        }
    }

    int main()
    {
        std::cout << "enter your height: ";
        double height{};

        std::cin >> height;

        calculation(height);

        return 0;
    }

  • rs

    #include <iostream>
    #include <cstdlib>
    #include "constant.h"

    /*
    In the chapter 4 comprehensive quiz, we wrote a program to simulate a ball falling off of a tower. Because we didn’t have loops yet, the ball could only fall for 5 seconds.
    Take the program below and modify it so that the ball falls for as many seconds as needed until it reaches the ground.

    */

    double calculateHeight(double initialHeight, int seconds)
    {
        double distanceFallen = myConstants::gravity * seconds * seconds / 2;
        double heightNow = initialHeight - distanceFallen;

        // Check whether we've gone under the ground
        // If so, set the height to ground-level
        if (heightNow < 0.0) {
            std::cout << "0.0";
            std::exit(0);
        }
        else
            return heightNow;
    }

    void calculateAndPrintHeight(double initialHeight, int time)
    {
        std::cout << "At " << time << " seconds, the ball is at height: " << calculateHeight(initialHeight, time) << "\n";
    }

    int main()
    {
        using namespace std;
        cout << "Enter the initial height of the tower in meters: ";
        double initialHeight{};
        cin >> initialHeight;

        while ( initialHeight > 0) {

            static int time{0};
            calculateAndPrintHeight(initialHeight, time);
            ++time;
        
        }
          
          

        return 0;
    }

    is this acceptable?

  • Cascavel

    This one took a while. Had to stop myself from checking the solution. It's a much easier implementation what you guys did! Thanks for the awesome learning resource.

  • ItsPhil

    Hello, so I finding my self often in the problem not knowing what kind of loop I should use. I know that there are many possible ways to create a solution e.g Quiz Question #1. My solution was/is: Transforming the calculationAndPrintHeight function to a double and a for loop in the main function.
    Like so:

    Are there any factors beside readability, that I can use as a guideline?
    Maybe something like, try passing not more Informations that are needed to get a loop to work ?
    Or : for example the solution from Q1, you used just bool instead of the double, should I use a do while loop when I have 2 possible states ?)

  • nuth vireak

    Q1
    To be honest, it took me 2 days to finish it. I don't know.. but  this one is really hard.

    constants.h

    main

Leave a Comment

Put all code inside code tags: [code]your code here[/code]