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).

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 either int, long, or a specific fixed-width integer type (e.g. std::int_fast16_t) based on range. If the variable should be const, say so.

a) The age of the user (in years)

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).

Your program should include a header file named constants.h that contains a symbolic constant to hold the value of gravity (9.8).

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,058 comments to 4.x — Chapter 4 summary and quiz

  • ChebCheb

    Hi everybody, and BIG THANKS for this great tutorial!!!

    I just solved Question 4, and i can't help it, it just seems to me that my solution is a bit easier to read and understand and less error-prone. There are 20% less lines of code (30 to 38, excluding empty lines and comments). Also, there are basically no functions calling functions calling functions (in the official solution, main calls "calculate and print", which in turn calls "calculate", and then calls "print"). My code on the other hand basically only has two "layers": Main function who calls the other functios. To naive little me, this seems way less complicated.

    So please take a look at it and tell me where i'm taking things too easy and will run into problems when continuing this way when more complicated tasks occur ;-)

  • narf

    • ChebCheb

      Hi narf. Thats some compact code, but if i'm not mistaking here, it misses the topic a little.

      Aren't you using some methods that aren't covered by the tutorial yet? Like the "for"-thingy.
      Also, you didn't put the gravity const in a header, as was demanded, and you're not following the "best practice" of seperating things into different functions.

      What help can this be to new learners?

  • Guest

    I'm truly glad I came across this website, by far the best C++ course I found online! Thank you very much for your effort, will donate as soon as I can afford to :)

  • Mateusz Kacperski

  • mark brain

    Can someone please critique my code, thanks.

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

    double getTowerHeight()
    {
        double towerHeight{};
        std::cout << "Please enter the tower height: ";
        std::cin >> towerHeight;
        return towerHeight;
    }

    void printTowerHeight()
    {

    }

    void calculateAndPrintTowerHeight(double towerHeight)
    {
        double distanceFallen{};
        double updatedHeight{};

        for (int i = 0; i < 5; i++) //i is the seconds passed
        {
            distanceFallen = gravity * (i * i) / 2;
            updatedHeight = (towerHeight - distanceFallen);
            if (updatedHeight <= 0)
            {
                std::cout << "At " << i << " seconds the ball is on the ground";
                break;
            }
                
                else
                    std::cout << "At " << i << " seconds, the ball is at height " << updatedHeight << " metres." << '\n';
        }
    }

    int main()
    {
        double towerHeight{ getTowerHeight() };
        calculateAndPrintTowerHeight(towerHeight);

        return 0;
    }

  • mark brain

    Im new to programming. Can someone please critique my programming code to say whether it is good or bad. I know i did not use comments. My code differs a bit because i understood how for statements work. Naming of my header file is also not correct. Any comments would be appreciated, thanks, Mark

    #include <iostream>
    #include "TestProjecth.h"  //Contains header file with gravity constant in

    double getTowerHeight()
    {
        double height{};
        std::cout << "Please enter the height of the twer in metres: ";
        std::cin >> height;
        return height;
    }

    void calculateBallHeight(double towerHeight)
    {
        double distanceFallen{};
        double updatedHeight{};

        for (int i = 0; i < 5; i++)
        {
            distanceFallen = gravity * (i * i) / 2;
            updatedHeight = (towerHeight - distanceFallen);
            std::cout << "At " << i << " seconds, the ball is at height: " << updatedHeight << " metres." << '\n';
        }
        
    }

    int main()
    {
        const double towerHeight{ getTowerHeight() };
        calculateBallHeight(towerHeight);

        return 0;
    }

    • nascardriver

      Use list-initalization for higher type-safety.
      ++prefix is quicker than postfix++.
      Use double literals for doubles to prevent accidental integer arithmetic.

  • Anatole

  • dodo

    This was a lot of fun! And I'm proud that i managed to get close to the solution. Really fun quiz.

    • dodo

      Added some stuff, it works but not perfect.

  • Medhat Diab

    • nascardriver

      It doesn't matter which value `sec` has in `distanceFallen`, you're always doing the same. You don't need an `if`-statement in there.

  • Win Tan

    constant.h

    main.cpp

  • Darwin Karl Mercado Marvin Mercado

    problem number 4 using forloop
    constant.h
    #pragma once
    #ifndef CONSTANT_H
    #define CONSTANT_H

    namespace constant {
        constexpr double gravity{ 9.5 }; //meter in seconds square
    }

    #endif

    main.cpp

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

    double getValueHeight() {
        double x{};
        std::cout << "Enter the Height value in meter: ";
        std::cin >> x;
        return x;
    }

    double calculateDistanceFallen(double height, int seconds) {
        double fallen{ (constant::gravity * seconds * seconds) / 2.0 };
        double distanceFall{ height - fallen };
        return distanceFall;
    }

    void calculateHeight(double height, int seconds) {

        double droppingHeight{ calculateDistanceFallen(height, seconds) };
        std::cout << "At " << seconds << " seconds, the ball is at height: " << droppingHeight << "meters\n";
    }

    int main() {

        double inputHeight{ getValueHeight() };

        for (int i = 0; i <= 5; i++) {
           if (i == 0)
              std::cout << "At " << i << " seconds, the ball is at height: " << inputHeight << "meters\n";
           if (i == 1)
               calculateHeight(inputHeight, i);
           if (i == 2)
              calculateHeight(inputHeight, i);
           if (i == 3)
              calculateHeight(inputHeight, i);
           if (i == 4)
              calculateHeight(inputHeight, i);
           if (i == 5)
              std::cout << "At " << i << " the ball is on the ground." << '\n';
        }

    }

  • Husen Patel

    My answer to question #3, printAnswer() does not take any arguments.

  • SuperNoob

    Solution to Question #4. Any flaws?

    constants.h

    main.cpp

    • nascardriver

      Name variable descriptively, avoid abbreviations.
      Initialize variables with list-initialization for higher type-safety.
      Lin 10,12: Duplicate calculation. Store this value in a variable.

  • Frido Kurniawan

    hello everybody, especially Alex and Nascardriver.
    I'm complete noob in this programming world and I hope you can give me some clarification about this.

    I just wonder (about quiz question number 4) why we use double type for towerHeight variable, while we actually assign integer literal (100) into it? Also, we do calculation with a mix of integer and floating point variables there.  

    AFAIK, acourding to the warning section of chap. 4.8, this is your suggestion : "Make sure you don’t use integer literals where floating point literals should be used. This includes when initializing or assigning values to floating point objects, doing floating point arithmetic, and calling functions that expect floating point values."

    Thanks before....

    • nascardriver

      The user can enter floating point numbers. 100 is just an example.
      There's nothing wrong with making `seconds` a `double` too, I don't know why Alex chose to use an `int`. I'll leave the quiz as-is, because making `seconds` a `double` won't change anything.

  • tsoud

    My first post here, so I want to start off by mentioning how glad I am that I found learncpp.com! I really appreciate all your effort in maintaining and updating this terrific website.

    A couple of questions (my apologies in advance if they were asked before but I waded through 14 pages of comments and didn't see anyone else ask):

    - In the model answer to Question #4 (extra credit) you used

    to make towerHeight constant (line 41). In this particular case, does it make a difference if towerHeight is a constant or regular variable?

    - For both quizzes, my answers are similar but I broke out each function into a separate source file with its own header. Is this practice recommended? I know these are exercises but I'm asking more generally.

    Thanks!

    • nascardriver

      Adding `const` prevents you from accidentally modifying variables and it makes the code easier to understand because you know values won't change. It doesn't change the program's behavior.

      1 file per function seems overkill. Try to group similar functions in the same file. Generally it is good to separate code into different files. The examples don't do so for ease of reading/writing, but you can do it for practice.

  • A

    Why choose "if else" and not "switch" for question 3? Switch seems clearer, more readable to me in this case.

  • Dimachaerus

    For extra credit, thats my solution. I know it's not really good looking,especially if I need to change values I know I need to find and replace them one by one but it works like a charm :D"
    Constant File:

    Main file:

  • Dimachaerus

    Hello. At question 3, I do like this. It solves the problem and looked elegant to me but I would like to know if my version is not efficient as yours.
    (I'm learning all my c++ information with this site btw, thank you for your effort)

  • Cristopher Klingensmith

    So for question three, my code looks very different.

    #include <iostream>

    double numGetter()
    {
        std::cout << "Please enter a floting point number: ";
        double num0{};
        std::cin >> num0;
        std::cout << '\n';

        return num0;
    }

    char opGetter()
    {
        std::cout << "Please enter a mathmatical symbol: ";
        char mathSymbol{};
        std::cin >> mathSymbol;
        std::cout << '\n';
        
        if (mathSymbol == 42)
            return mathSymbol;
        else if (mathSymbol == 43)
            return mathSymbol;
        else if (mathSymbol == 47)
            return mathSymbol;
        else if (mathSymbol == 45)
            return mathSymbol;
        else
            std::cout << "restart and try again\n";
    }

    double expression(double x, double y, char z)
    {
        double answer1{};
        if (z == 42)
        {
            answer1 = x * y;
            return answer1;
        }
        else if (z == 43)
        {
            answer1 = x + y;
            return answer1;
        }
        else if (z == 47)
        {
            answer1 = x / y;
            return answer1;
        }
        else if (z == 45)
        {
            answer1 = x - y;
            return answer1;
        }
    }

    int main()
    {
        double num1{numGetter()};
        double num2{numGetter()};
        char symbol{ opGetter() };
        double answer{ expression(num1, num2, symbol)};
        std::cout << num1 << "   " << symbol << "   " << num2 << "   =   "<< answer;

        return 0;
    }

    It still works but I don't know if this would be harder to read and understand than yours, I understand the code, but then again I just wrote it lol.

    It took 66 lines of code which I noticed is a lot larger than your program.

    • Bill Gates

      There's definitely some superfluous code that could be cleaned up -
      1) there's no need to call for a new line after the inputs of num0 and math symbol, the cin will automatically move to the next line - unless you want the extra space.
      2) there's no need to check for mathsymbol in the OpGetter function - just return it.  Notice you're returning mathSymbol regardless of the input.  You're checking for the value of it in your expression function
      3) in the expression function, just return answer1 at the end outside of the if then else statements.

  • Jhon Ramos

    for practice purposes, without loop:

    constant.h

    main.cpp

  • asd

    Hi. May I have some feedback on my solution to Q4. Thank you!

    constants.h

    main

    • nascardriver

      Use double literals for doubles to avoid accidental integer arithmetic.

      You're calculating `x - distance_fallen(y)` twice. Calculate it once and store the result in a variable.

      Name things descriptively, `x`, `y`, and `result` don't have a meaning.

  • kio

    Hello once more, mine solution for Q4:

    const.h

    source.cpp

    • nascardriver

      - math.h is a C header, C++ has cmath which defines its contents in the `std` namespace. `pow` should be `std::pow`.
      - Initialize variables rather than assigning to them
      - Use `double` unless you have a reason to use `float`
      - Use an auto-formatter
      - Use floating point literals for floating point arithmetic to avoid accidental integer arithmetic. `2` should be `2.0`
      - You can avoid to duplicate numbers in `main` by writing a function that takes the time as a parameter and calls `printDistance` and `distanceFallen`.

      • kio

        Hi Nascar driver, thank you for your input.

        Use an auto-formatter?, can you please provide an example?

        You can avoid to duplicate numbers in `main` by writing a function that takes the time as a parameter and calls `printDistance` and `distanceFallen`. - Can you please provide a function definition for this? I'm trying to figure it out on my own, but without the success.

        • nascardriver

          An auto-formatter is a tool that formats your source code. Your IDE or editor probably has a built-in auto-formatter. Look up how to use it, you probably need to press a hotkey.

          • kio

            Hi nascardriver,

            Updated Q4 thanks to your suggestions:

            main.cpp

            const.h

  • kio

    Hello all, mine solution for Q3.

    • nascardriver

      " " is a string, ' ' is a character. Strings are expensive. Same for "\n".

      What if `printOutput` gets called with a `sign` that isn't +-*/ or ' '?

      • kio

        Hi nascardriver,
        Thank you once more for taking your time to review the code.

        Based on the program req, "If the user enters an invalid symbol, the program should print nothing.". The program will print ' ' empty space.

        • nascardriver

          `printOutput` will print a line feed if `sign` is a space, but nothing if `sign` is another invalid character. It should behave the same for all invalid signs.

          Also, if you want to create a `char` with a default value, you can use `{}` (Creates a `char` with value 0) as far all other types.

          • kio

            Hi nascar, thank's for you patience

            The updated code is added below:

  • lucky

    Enter a double value: lo
    Enter a double value: Enter one of the following: +, -, *, or /

    above is the program execution if we give "lo"  instead of double input,
    why then the program not letting us to enter second double and operator??
    (after giving "lo" as first input it exits printing above output.)

  • dwayne

    this is the best way ive found sofar, not polished bt works.
    you can replace 7 in the for statement with any other number.

  • Waldo Lemmer

    1. **Question #2**

    a) The age of the user (in years)

    > int

    Is short a valid answer? If not, why?

    2. My answer to Question #3 is EXACTLY the same as yours. I just used different identifiers, and my functions are below the main() function. I'm so proud :D

    3. My answer to Question #4:

    constants.h:

    learncpp-4.x-q4.cpp:

    3.1 If I put `seconds * seconds` at line 42 between parentheses, VS warns:
    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).

    3.2 Any suggestions for how my code can be improved?

    4. Your answer at Question #4:

    From lesson 2.11:

    > Order your #includes as follow: your own user-defined headers first, then 3rd party library headers, then standard library headers

    -

    By the way, the questions in this lesson are great! I hope future lessons contain similar questions :)

    • nascardriver

      1a
      I disagree with the answers in this quiz, maybe Alex will explain
      (x) doubt

      Unless you have a good reason to, don't diverge from the unmodified types `int`, `double`, `char`.
      Only if you're limited in memory or need extraordinarily large numbers, use guaranteed-width types.

      3.1
      VS is right, but can be ignored if you know the value of `seconds * seconds` doesn't overflow an `int`.

      3.2
      Not really :)

      4
      Thanks!

  • xixi

    hi, in question #4. i read from the comment, that 2.0 is to avoid accidental integer compute. but seconds are also integer, do i need to define the seconds as integer too.

  • yeokaiwei

  • xKaihatsu

    This is my code for calculating the ball’s height.

    • nascardriver

      - Initialize variables with list initialization for uniformity and higher type-safety.
      - Use double literals for floating point arithmetic to avoid accidental integer arithmetic.
      - Use ++prefix unless you need postfix++.
      - `calculateBallHeight` does more than calculating the ball height, which reduces its reusability.

  • xKaihatsu

    This is what I did for the mini calculator program.

Leave a Comment

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