Search

4.x — Chapter 4 summary and quiz

Quick Review

The smallest unit of memory is a binary digit, also called a bit. The smallest unit amount of memory that can be addressed directly is a byte. The modern standard is that a byte equals 8 bits.

A data type tells the compiler how to interpret the contents of memory in some meaningful way.

C++ comes with support for many fundamental data types, including floating point numbers, integers, boolean, chars, null pointers, and void.

Void is used to indicate no type. It is primarily used to indicate that a function does not return a value.

Different types take different amounts of memory, and the amount of memory used may vary by machine. See 4.3 -- Object sizes and the sizeof operator for a table indicating the minimum size for each fundamental type.

The sizeof operator can be used to return the size of a type in bytes.

Signed integers are used for holding positive and negative whole numbers, including 0. The set of values that a specific data type can hold is called its range. When using integers, keep an eye out for overflow and integer division problems.

Unsigned integers only hold positive numbers, and should generally be avoided unless you’re doing bit-level manipulation.

Fixed-width integers exist to define integer types with guaranteed sizes. Favor the std::int_fast#_t and std::int_least#_t integers when you need a fixed size guaranteed to be at least a certain size. std::int8_t and std::uint8_t should generally be avoided, as they tend to behave like chars instead of integers.

size_t is an unsigned integral type that is used to represent the size or length of objects.

Scientific notation is a shorthand way of writing lengthy numbers. C++ supports scientific notation in conjunction with floating point numbers. The digits in the significand (the part before the e) are called the significant digits.

Floating point is a set of types designed to hold real numbers (including those with a fractional component). The precision of a number defines how many significant digits it can represent without information loss. A rounding error can occur when too many significant digits are stored in a floating point number that can’t hold that much precision. Rounding errors happen all the time, even with simple numbers such as 0.1. Because of this, you shouldn’t compare floating point numbers directly.

The boolean type is used to store a true or false value.

If statements allow us to execute one or more lines of code if some condition is true. Multiple statements can be executed if they are put inside a block (inside curly braces). The conditional expression of an if statement is interpreted as a boolean value.

Char is used to store values that are interpreted as an ASCII character. When using chars, be careful not to mix up ASCII code values and numbers. Printing a char as an integer value requires use of static_cast.

Angled brackets are typically used in C++ to represent something that needs a parameterizable type. This is used with static_cast to determine what data type the argument should be converted to (e.g. static_cast<int>(x) will convert x to an int).

std::string offers an easy and safe way to deal with text strings. String literals are always placed between double quotes. std::string lives in the <string> header.

A constant is a fixed value that may not be changed. C++ supports two types of constants: literal constants, and symbolic constants.

Literals are values inserted directly into the code. Literals have types, and literal suffixes can be used to change the type of a literal from default.

Const variables are variables that can’t be changed after being initialized. Const variables can be either runtime or compile-time constants. constexpr variables must be compile-time constants.

Don’t use magic numbers in your code. Instead, use symbolic constants.

Quiz time

Question #1

Why are symbolic constants usually a better choice than literal constants? Why are const/constexpr symbolic constants usually a better choice than #defined symbolic constants?

Show Solution

Question #2

Pick the appropriate data type for a variable in each of the following situations. Be as specific as possible. If the answer is an integer, pick int (if size isn’t important), or a specific fixed-width integer type (e.g. std::int_least16_t) based on range. If the variable should be const, say so.

a) The age of the user (in years) (assume the size of the type isn’t important)

Show Solution

b) Whether the user wants color or not

Show Solution

c) pi (3.14159265)

Show Solution

d) The number of pages in a textbook (assume size is important)

Show Solution

e) The length of a couch in feet, to 2 decimal places

Show Solution

f) How many times you’ve blinked since you were born (note: answer is in the millions)

Show Solution

g) A user selecting an option from a menu by letter

Show Solution

h) The year someone was born (assuming size is important)

Show Solution

Question #3

Author's note

The quizzes get more challenging starting here. These quizzes that ask you to write a program are designed to ensure you can integrate multiple concepts that have been presented throughout the lessons. You should be prepared to spend some time with these problems. If you’re new to programming, you shouldn’t expect to be able to answer these immediately.

Remember, the goal here is to help you pinpoint what you know, and which concepts you may need to spend additional time on. If you find yourself struggling a bit, that’s okay.

Here are some tips:

  • Don’t try to write the whole solution at once. Write one function, then test it to make sure it works as expected. Then proceed.
  • Use your debugger to help figure out where things are going wrong.
  • Go back and review the answers to quizzes from prior lessons in the chapter, as they’ll often contain similar concepts

If you are truly stuck, feel free to look at the solution, but take the time to make sure you understand what each line does before proceeding. As long as you leave understanding the concepts, it doesn’t matter so much whether you were able to get it yourself, or had to look at the solution before proceeding.

Write the following program: The user is asked to enter 2 floating point numbers (use doubles). The user is then asked to enter one of the following mathematical symbols: +, -, *, or /. The program computes the answer on the two numbers the user entered and prints the results. If the user enters an invalid symbol, the program should print nothing.

Example of program:

Enter a double value: 6.2
Enter a double value: 5
Enter one of the following: +, -, *, or /: *
6.2 * 5 is 31

Show Hint

Show Hint

Show Solution

Question #4

Extra credit: This one is a little more challenging.

Write a short program to simulate a ball being dropped off of a tower. To start, the user should be asked for the height of the tower in meters. Assume normal gravity (9.8 m/s2), and that the ball has no initial velocity (the ball is not moving to start). Have the program output the height of the ball above the ground after 0, 1, 2, 3, 4, and 5 seconds. The ball should not go underneath the ground (height 0).

Use a function to calculate the height of the ball after x seconds. The function can calculate how far the ball has fallen after x seconds using the following formula: distance fallen = gravity_constant * x_seconds2 / 2

Sample output:

Enter the height of the tower in meters: 100
At 0 seconds, the ball is at height: 100 meters
At 1 seconds, the ball is at height: 95.1 meters
At 2 seconds, the ball is at height: 80.4 meters
At 3 seconds, the ball is at height: 55.9 meters
At 4 seconds, the ball is at height: 21.6 meters
At 5 seconds, the ball is on the ground.

Note: Depending on the height of the tower, the ball may not reach the ground in 5 seconds -- that’s okay. We’ll improve this program once we’ve covered loops.
Note: The ^ symbol isn’t an exponent in C++. Implement the formula using multiplication instead of exponentiation.
Note: Remember to use double literals for doubles, eg. 2.0 rather than 2.

Show Solution

Question #5


Find 3 issues (affecting 4 lines) in the following code.

Sample output

How old are you?
6
Allowed to drive a car in Texas [ ]
How old are you?
19
Allowed to drive a car in Texas [x]

Show Solution


5.1 -- Operator precedence and associativity
Index
4.14 -- Const, constexpr, and symbolic constants

1,095 comments to 4.x — Chapter 4 summary and quiz

  • Bouncy Disaster

    Small inconsistency:
    "If statements allow us to execute one or more lines of code if some condition is true. Multiple statements can be executed if they are put inside a BLOCK (inside curly braces). The conditional expression of an if statement is interpreted as a boolean value."

    If statement with multiple statements inside block/curly braces aren't introduced until "7.2 — If statements and blocks" (in "4.10 — Introduction to if statements" there is only mention of 7.2 lesson where they are explained, but no use is shown).

    (as a side note, I'm curious why if statements with blocks/curly braces are delayed by so many chapters. They don't seem hard or problematic, and are very useful early on)

  • J

    Had a lot of fun with this. Would love some feedback.

    Initially had all the distance travelled func in main, but didn't look very elegant with that much text repeating. Think it's looking fairly readable now. Keen to learn how loops work down the track. I also added a conditional check to end the program early once the ball hit's the ground.

    Let me know how I went. Thanks!

    • J

      Post submitting the above, I re-evaluated my function names to make more sense.

      Velocity -> distanceFromGround

      DistanceTravelled -> printBallPosition

  • letsgetit

    A joy to work through this one.  Really tested most of the major topics that have been covered so far.  My main goal here with this program, apart from learning C++ of course, was to separate the program into as many short functions as generally reasonable, per best practices.  Hopefully the rest abides by best practices more or less as well.  Sharing my solution for quiz question #4:

  • Sankalp Gupta

    Hi, could you please review my code

  • letsgetit

    Sharing my solution for quiz question #3.  Glad to see the program I came up with was fairly similar to the author's program more or less.  On the right track!

  • Waldo Lemmer

    In the previous lesson, you said:
    > In C++17, prefer “inline constexpr” instead

    But in Question #4's solution, you have:
    >

    You also didn't put it in a namespace.

    • Alex

      Upon reflection, I reverted the answer -- it's weird to talk about user-defined namespaces and inline variables when we haven't covered those topics yet. For this program, since gravity is only needed in one place, a local constexpr variable is fine.

  • MidZ

    I AM SO PROUD OF THIS , IT TOOK ME A WHILE TO THINK THOUGH

  • Aza

    When I try to compile this code, it gets an error at the else statement, where it says "expected a statement". What does it mean and what prompted it? Thank you!!

  • Ouro

    My code gives the same output as the solution that's given. I wonder if my code is considered 'best-practice' seeing that my code differs from the code provided in the solution? Thanks in advance!

  • Arsen

    Hello, I have a question regarding the solution for your Question 3. I would appreciate if you help me to clarify some things.

    When I wrote my code, firstly it was all in

    function. Then, I realized it was not that well structured, so I made three separate functions as in your answer. However, I initially had a separate function for character input ('+', '-', '*' and '/') as you have in the solution , but then I put this whole function in a new function in an IF statement.
    You have :

    While I instead of having char operation in IF statements , insert the whole FUNCTION, in your case it is function

    My way didn't work, I wonder why?

    Many thanks :)
    Btw, I have been learning C++ from ZERO on this website and so far it is amazing) Thanks for this amazing learning source.

    • nascardriver

      Hi Arsen, can you post the code that didn't work?

      • Arsen

        Hi. I didn't save at that time, however, I built a new one in the way I did last time. Here it is:

        So, it can calculate only " + " operator.

  • Mal

    I find it quite alarming that when you give a constant an value, eg, 'constexpr double gravity { 9.8 }; when you examine its value when debugging you discover that you find out that instead of      
    9.800'000'000'000'000'000 you've got the number 9.800'000'000'000'000'711

    If you actually want to undertake math with a high level of precision do you have to make use functions within "3rd party" libraries?

    • Alex

      Yes. See https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic

      There's nothing to be alarmed about here. In the vast majority of cases, we don't need more than 15 significant digits of precision.

  • Mal

    Question 4 - When I pasted your solution into VS2019 it threw up an error and a warning.  The error was at line 18 where you used gravity instead of constants::gravity

    The warning was Warning    C26451    Arithmetic overflow: Using operator '*' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator '*' to avoid overflow (io.2).

    Changing int seconds to double seconds gets around the problem and I see that you are covering casting in chapter 6.    

    Loving the course.

    • Mal

      Have just spotted what was causing the error - In my header, I had followed the guidance at 4.14 and put my inline constexpr in a namespace, whereas you have not :)

  • Manish

    Is this approach correct?

    #include "Constants.h"
    #include <iostream>
    #include <math.h>

    double heightOftower()
    {
        double height{};
        std::cout << "Enter the height of the tower in meters: ";
        std::cin >> height;

        return height;
    }

    double timeToHitGround(double height)
    {
        double time{ pow(((2 * height) / gravity_constant),0.5) };

        return time;
    }
    double getHeight(int time,double towHeight)
    {
        double height{ (towHeight - (gravity_constant * pow(time,2) / 2)) };

        return height;
    }
    int main()
    {    
        double towerHeight{ heightOftower() };
        double time{ timeToHitGround(towerHeight) };
        std::cout << time << std::endl;
        
        for (int i = 0; i <= ((int)time+1); i++)
        {
            if (((int)getHeight(i,towerHeight) + 1) < 0)
            {
                std::cout << "At " << i << " seconds, the ball is on ground." << std::endl;
            }
            else
            {
                std::cout << "At " << i << " seconds, the ball is at height: " << getHeight(i,towerHeight) << " meters." << std::endl;
            }
        }
        
        system("pause 0");
        return 0;
    }

  • Armando IG

    Hello, I apologize for the terrible formatting on my question 4, but I had a problem with the answers it gave, your sample output described

    At 0 seconds, the ball is at height: 100 meters
    At 1 seconds, the ball is at height: 95.1 meters
    At 2 seconds, the ball is at height: 80.4 meters
    At 3 seconds, the ball is at height: 55.9 meters
    At 4 seconds, the ball is at height: 21.6 meter
    At 5 seconds, the ball is on the ground.

    Mine instead gives:
    At 0 seconds, the ball is at height: 100 meters
    At 1 seconds, the ball is at height: 95.1 meters
    At 2 seconds, the ball is at height: 75.5 meters
    At 3 seconds, the ball is at height: 31.4 meters
    At 4 seconds, the ball is on the ground.
    At 5 seconds, the ball is on the ground.

    Did my terrible formatting affected calculations?

    PD. I compared it to the Answer but the formula seems to be the same, my gravity is set to 9.8 inside the header

    • Seth

      Each time you calculate

      you are using the new value of h. You should be subtracting from the original height (100 in this case) each time, and not from the new value. I would instead pass height as a constant, and then always calculate h as

  • Jordan

    I finally did it, the output is 100% the same but I didn't use the calculateAndPrint() function which make me feel less confident tbh. I don't know if the code below will run in error in the future if there is number changes such as towerHeight. Suggestions would be a great help!

    • nascardriver

      hi!

      Either `distanceFallen` should be called `height` or `calculateHeight` should be called `calculateDistanceFallen`. The way it is, it can't be right, because "distance fallen" does not have the same meaning as "height".

      The same story inside of `calculateHeight()`.

      Using `const` would have prevented you from repurposing the variable and breaking its meaning.

      Creating a separate variable comes at no extra cost. The compiler is smart enough to reuse the memory of the first variable.

  • Jacob

    Why is Q2A not short?

    • Alex

      Short isn't typically used these days. If space isn't important (e.g. you only need one variable), int tends to perform better. If space is important, using one of the fixed-width integer types is a better choice.

  • Ahmed

    i did some mistakes at first, and after seeing your code I rewrote mine again and made it look cleaner! thank you.

  • Jeff

  • Jonathan Chung

    Is there a problem with this solution?

    • nascardriver

      Use double literals to avoid accidental integer arithmetic, `2` should be `2.0`.

      You have redundant values in line 30-34, there's nothing stopping you from doing a typo

      You can wrap `currentHeight()` and `distanceFallen()` in a function. See for example Win Tan's solution https://www.learncpp.com/cpp-tutorial/chapter-4-summary-and-quiz/comment-page-14/#comment-494325 (His parameters are named poorly, please don't copy them)

  • Daniel

Leave a Comment

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