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 represent the size of 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 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. int16_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 includes a namespace called myConstants. In the myConstants namespace, define 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.

Show Solution


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

784 comments to 4.x — Chapter 4 summary and quiz

  • Matt

    VS 2019 throws a warning on /W4 regarding (seconds * seconds), C26451 Arithmetic Overflow - "Using operator '*' on a 4 byte value then casting to the result to an 8 byte value. Cast the value to a wider type before calling '*' to avoid overflow." (but shows up ONLY after I compile to debug).

    I was forced to cast the int to double for the acceleration formula to clear the warning, at that rate would it not be easier overall to identify seconds as double?

    If an int * int has a chance to overflow a double, does not a double * double afford the same if not higher likelihood to overflow a double? Not sure if VS 2019 is just being silly at this point.

    • Seems silly to me. There's no reason why a simple multiplication would overflow.
      It's right in that casting it first would be better, but still, this warning seems like it'd pop up very often although there's no danger.

  • Sam

    Question #1 has a typo.

    “Why are const symbolic constants usually a better choice than #defined symbolic constants?”

    “const” should be “constexpr”

    Regardless of the typo, this was a great lesson. Keep up the amazing work!

  • Sam

    Here is my solution for Question #4. I utilized an external library called <cmath>, hope that's not an issue!

    main.cpp

    constants.h

    I would appreciate any feedback as it will help me progress a lot!

    Thank you in advance and keep working hard on these amazing tutorials :)

    • Hi Sam!

      - Use double literals for doubles (2.0 instead of 2).
      - Line 8: Don't mix lines.
      - Initialize your variables with brace initializers.
      - Line 17: There's no reason to use `size_t` here. Use an `int`.
      - Avoid abbreviations, name your variables descriptively.
      - If your program prints anything, the last thing it prints should be a line feed ('\n', `std::endl`).
      - `main`: Missing return-statement.

      • Sam

        I see. Thank you for your feedback! :)

        Also, I didn't know you have to specifically specify a return 0; at the end of your main function since it does it automatically? If you could possibly clarify that, I would be appreciative!

  • Edgar J. Wurst

    Here's my answer to question 4.  I use two header files #included in two different .cpp files.  I also mix an int for the variable time and a double for the variable height.  The variable height is initialized as a double although the user likely enters an integer.  Any comments in general?

    ch4xq4.cpp

    ch4xq4funcs.cpp

    ch4xq4.h

    ch4xq4constants.h

    Here's my output for the gruesome possibility of a ball falling out of a transoceanic flight at 10 km above the water:

  • Edgar J. Wurst

    Here's my three-file solution to quiz 4, question 3.  Any suggestions for improvement?

    ch4xq3.cpp

    ch3xq3funcs.cpp

    ch4xq3.h

  • Nirbhay

    To make this almost perfect website perfect, here is my contribution:

    Typo:

    "Different types take different amounts of memory, and the amount of memory used **by(this by is redundant)** vary by machine."

    Thanks :)

  • Anonymous

    I have an error with the following code:

    The Error is:
    Error MSB6006 "CL.exe" exited with code 2

  • Owen

    I did Question 3 without looking at the solution and came up with a faster and easier solution, i think...

    Pretty simple. Takes in the sum by order, passes it all to doCalc(a, oper, b) and uses a switch to determine the operator and therefor the type of arithmetic needed by the user.

    • - Name your variables descriptively. Avoid abbreviations.
      - Use single quotation marks for characters.
      - Initialize your variables with brace initialization. Only initialize them to a specific value if you're using that value.
      - Use your editor's auto-formatting feature.
      - You don't have to break after returning. A return stops everything.

      > faster
      Hard to tell.

      > easier
      Given just `main`, it's easier to understand what Alex' code does. Performing the calculation without printing the result is definitely better.

      > uses a switch
      `switch` is the right choice for this task, but hasn't been covered yet and cannot be used in the official solution.

  • kanishkaditya shukla

    HEY ALEX AND NASCARDRIVER

    this is a small snippet from my program

    #ifndef HEADER_H_INCLUD
    #define HEADER_H_INCLUDED

    constexpr double gravity{9.8};
            OR
    namespace constant
    {
        constexpr double gravity{9.8};
    }

    #endif // HEADER_H_INCLUDED

    QUESTION ::I created a program for the second quiz using the above code as a header it worked both ways by simply defining the
               "constexpr double gravity" in the header file or by creating a namespace (CONSTANT) i am a bit confused about this , that
                which method should i use and why,please explain. Thanks in advance.

    SUGGESTION::ALEX,CAN YOU PLEASE ADD THE FULL FORM OF CONSTEXPR

  • Alexander S.

    I don't know if anyone will still reply, but I'm having an issue where constants::gravity is saying constants is not a recognized namespace, but here is the code

    • Compiles fine for me. Does it work when you replace `#include "constants.h"` with the contents of constants.h?
      What's the exact error message?

      • Alexander S.

        Yes, if I replace it, it works fine. I just loaded the program again today and it had no issues. Thank you though...

        Don't know what happened

      • Alexander S.

        Also, I know this is a long while later, are there any prominent or minor format issues with my code, Thanks!

        • Not formatting, but a bunch of other issues:
          - Don't use `system`, your code won't work as intended on other platforms.
          - Don't include <Windows.h>, your code won't compile on other platforms.
          - Initialize your variables with brace initializers.
          - Use double literals for doubles (0.0 instead of 0, etc.).
          - `main`: Missing return-statement.
          - Use short-hand operators += -= *= /=.
          - Limit your lines to 80 characters in length for better readability.
          - Line 26 is always true.
          - Line 28: `break`.
          - Print line breaks at the end of lines, not the beginning.

          • Alexander S.

            1. & 2. Didn't realize this, I only use it for Sleep, what should I do instead..

            I couldn't figure out what to do with Line 26 because I didn't want wrong inputs but I just couldn't get it to work lol

  • Arionne Coleman

    What statement makes the code not print anything if an invalid symbol is entered in.

    Edit: does it happen because in the solution it isn't coded to deal with and symbols accept the ones given for an output?

    • Alex

      I presume you're referring to quiz 3. If the user enters an invalid symbol, variable op will contain that invalid symbol. When function printResult() is called, none of the if statements will match, so nothing is printed.

      It would be a reasonable addition to the program to add to the end of printResult() the following:

      That way, rather than printing nothing, it would print an error message instead.

  • Grego

    Hello Alex, nascardriver,

    First of all, this is my first comment, so I am gonna take this occassion to thank you for the tutorial, it's great so far.
    I would appreciate if you could take a look at my Question #3 code for any possible improvements.
    I have commented in contents of my header for everything to be in one code block.

    I also kept my main function at the top and put forward declarations in my header - is it a bad practice overall?

    • Hi Grego!

      > I have commented in contents of my header for everything to be in one code block
      Thanks!

      > I also kept my main function at the top and put forward declarations in my header - is it a bad practice overall?
      You can do it, but it increases work if you decide to update a function's signature (You have to change it in 2 places). For this reason, I recommend moving `main` below the other functions.

      - `xyResult` should be inside the if-statement.
      - Line 28: '='
      - Inconsistent formatting. Use your editor's auto-format feature.
      - `validFlag` is not used after being set. You could return immediately, ie. replace `validFlag = b` with `return b`.

      • Grego

        Hey nascardriver,

        Appreciate the quick response. I have to admit your last point took me a minute to understand, as I was fixated on returning only at the end of the function for some reason.
        Sorry about the formatting, I will do better.

        I took your advice to heart and the Question 4 code is cleaner, I hope.

        • - Limit your lines to 80 characters in length for better readability on small displays.
          - Use double literals for doubles (2.0 instead of 2, same for 0).
          - Initialize `distanceFallen` and `ballPosition` to their desired values.
          - `main`: Missing return-statement.
          - Line 44+: Duplicate strings/code. Add a function that takes seconds and towerHeight as arguments and calculates and prints.

  • zim

    Hey, I'm slowly getting there, though it can get a little over overwhelming, trying to remember all the technical bits.
    It not covered yet, but I managed to loop the program instead of calling functions repeatably, would this be the correct way to do this ?

    • Hey!

      - Initialize your variables with brace initializers.
      - Limit your lines to 80 characters in length for better readability on small displays.
      - Don't mix `float` and `double` without a reason. If you're not coding for a system with highly limited resources, use `double`.
      - Use double literals for doubles (0.0 instead of 0, etc.).
      - Initialize `fallen` instead of assigning to it.
      - Use your editor's auto-formatting feature.
      - "value1" is a poor name. Names should be descriptive.
      - `loop` and `time` are identical, remove one or the other.

      Since you know how often your loop will run before you start it, a `for`-loop should be used. Assuming the use of a `while`-loop is deliberate, you used it correctly.

  • Daniel

    This is my solution using for statement:

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

    // if the ball is on the ground, the function returns 1
    bool printBallHeight(int seconds, int towerHeight)
    {
        double ballHeight{};
        ballHeight = towerHeight - constants::gravityConstant * seconds * seconds / 2;

        if(ballHeight >= 0)
            std::cout << "At " << seconds << " seconds, " << "the ball is at height: " << ballHeight << "meters \n";
        else
        {
            std::cout << "At " << seconds << " seconds, " << "the ball is on the ground. \n";
            return false;
        }

        return true;
    }

    int main()
    {
        std::cout << "Enter the height of the tower in meters: \n";
        int towerHeight;
        std::cin >> towerHeight;

        bool isBallOntheGround{true};

        for (int seconds = 0; isBallOntheGround; seconds++)
        {
            isBallOntheGround = printBallHeight(seconds, towerHeight);
        }

        return 0;
    }

    I want to know if it is a good practice the function printBallHeight returns true or false.
    Any more feedbacks would be great! :D

    • - Initialize `ballHeight` instead of assigning to it.
      - `ballHeight >= 0` should be `ballHeight > 0`. If it's equal to 0, the ball is on the ground.
      - Use double literals for doubles (0.0 instead of 0, 2.0 instead of 2).
      - Initialize `main::seconds` with a brace initializer.
      - Use ++prefix unless you need postfix++.

      > I want to know if it is a good practice the function printBallHeight returns true or false
      Yes, it allows you to terminate the loop early. Since you want to loop until the ball hits the ground, not for a certain number of steps, you should use a `while`-loop.

  • VerticalLimit

    //First Exercise

    #include <iostream>
    using namespace std; // yes this is intentional as I know for now
                         // this would be the only namespace for this exercise

    int exercise()
    {
        cout << "Float Exercise Quiz\n" << endl;
        cout << "Please enter two float numbers with any of these arithmetic symbol (+, -, *, or /) in between: ";
        double a{ 0.0 }, b{ 0.0 };
        char symbol{};
        cin >> a >> symbol >> b;

        if (symbol == '+')
        {
            cout << "Answer is: " << a + b <<'\n';
            return 0;
        }
        else if (symbol == '-')
        {
            cout << "Answer is: " << a - b << '\n';
            return 0;
        }
        else if (symbol == '*')
        {
            cout << "Answer is: " << a * b << '\n';
            return 0;
        }
        else if (symbol == '/')
        {
            cout << "Answer is: " << a / b << '\n';
            return 0;
        }
        else
        {
            cout << "Incorrect arithmetic symbol entry! Try again!\n";
            return 0;
        }

    }
    int main()
    {
        exercise(); // Calling the function

        system("pause"); //due to Visual Studio
        return 0;
    }

    • Please use code tags when posting code (Yellow box below to comment box).

      - Don't use `using namespace`. Even if there's only 1 namespace, names can still collide with names from the global namespace.

      Output: 3

      Output: 3.3
      - Don't use `system`, it won't work on other platform. VS can be configured to keep the console open after the program has finished.
      - Declare 1 variable per line.
      - You're using the same name style for variables and functions, this can lead to confusion.
      - `exercise` should be `void`. If it wasn't, you should move the `return 0` to the end of the function as it's independent of `symbol`.

      • VerticalLimit

        Thanks for the pointers will redo the task

        • You don't need to redo the task as long as you understood my pointers. There'll be more quizzes in which you can apply what I said. But if you want to, redo it.
          Also, this line

          There's no reason to use `std::endl` here, just add another `\n` to the end of the string.

  • Hai Linh

    In Question #3, what happens if the second double value is 0, and the operator is / (division) (division by 0)?
    I assume it'll print nothing

  • Samira Ferdi

    Hi Alex and Nascardriver!

    This is my code:

    Should I use switch-case instead of if because switch-case is more simple and readable?

  • alfonso

    I'm wondering if I violated some good practices calling functions like that on lines 26 - 31

    • - Use double literals for doubles (2.0 instead of 2).

      Line 26-31 should use a loop, but those haven't been covered yet, so your code is fine!

      • alfonso

        Ok. I know about loops. My concern was about calling too much functions in a row:

        Another concern was: display() and getBallHeight() must match their first parameter to work as desired ...

        • > calling too much functions in a row
          No problem.

          > display() and getBallHeight() must match their first parameter
          A loop would solve that.

          You could also add a function "calculateAndPrintHeight".

  • hwakeye's whole family dies in endgame : /

    Hey Nascardriver!
    I solved the 4th question.

    What can be some improvements here?

    • Hey spoiler!

      - Use double literals for doubles (2.0 instead of 2, etc.)
      - Limit your lines to 80 characters in length for better readability on small displays.
      - @main: Missing return-statement. (Should be added for consistency).
      - Use single quotation marks for characters ('\n').
      - Line 13 could be >= to save avoid subtraction in line 17 in the case of `ballDisplacement == towerHeight`.
      - You're using the same name style for variables, constants, and functions. This can lead to confusion.

      Well structured!

      • *insert marvel movie spoiler*

        Thanks nascardriver,
        Those tips really helped.
        I forgot to write return statement in main.
        Why did it not show error when there was no return statement.

  • BP

    Hi,
    I'm having a bit of a problem with question 4. Because for 100 meters I'm not getting the same results as the ones given. Could someone please point out what I'm doing wrong in the following code?

    I'm getting the following results:
    0 sec - 100 m
    1 sec - 95.1 m
    2 sec - 75.5 m
    3 sec - 31.4 m
    4 sec - ball on ground
    5 sec - ball on ground

  • Torraturd

    Is it okay if I answer the question like this?

    • * Initialize your variables with brace initializers.
      * Line 8, 28: Limit your lines to 80 characters in length for better readability on small displays.
      * Use double literals for doubles (0.0 instead of 0, 2.0 instead of 2, etc.).
      * Use @std::pow instead of @pow
      * Missing #include <cmath>
      * Line 22+: Should be a do-while-loop.
      * Name your variables descriptively.

  • Richard Flores

    For Q3 can I use a switch case instead?
    ...
       switch (opr) {
          case '+' :
             totalVal = val1 + val2;
             break;
          case '-' :
             totalVal = val1 - val2;
             break;
          case '*' :
             totalVal = val1 * val2;
             break;
          case '/' :
             totalVal = val1 / val2;
             break;
          default :
             isValid = 0;
             break;
    ....

    Are operator chars allowed in case inputs or must they be integers only?

  • Jonathan

    Maybe I will change the code to loops if I learn it. What can be improved in the code?

  • Cal

    You've got a typo "poitners" in the data types part of the quick review up top.

  • Napalm

    Question 4

    constants.h

    main.cpp

    I'm proud to have finally got this to work without cheating! It turned out different to the answer though. I think I may have broken the one job function rule though, it looks like I got the use of printResult() and distanceFallen a bit jumbled. The only other issue was that it keeps printing "the ball is on the ground" rather than stopping.

    Is it bad practice to put "using namespace" for this?

    Any more feedback would be great.

    • main.cpp
      * Line 20: Initialize your variables with brace initializers.
      * Line 20: Re-assigning to @t is unnecessary. Use a simple multiplication.
      * Line 26: Use double literals for doubles (0.0 instead of 0).
      * Line 29: Limit your lines to 80 characters in length for better readability on small displays.
      * "g", "h", "t" are useless names. Name variables descriptively, avoid abbreviations.
      * Line 40, 42, 44, 46, 48: Should be ++time to prevent human error.
      * @main: Missing return-statement.

      > Is it bad practice to put "using namespace" for this?
      It'd be better without it. That way it's obvious where @gravity is coming from and name collisions are prevented. As long as the using-statement is in a source file and you know the contents of the namespace, you _can_ use "using namespace", but you should do so with care.

  • p1n

    Hey can i get help with this program.When i enter integer numbers it works,but with float it doesn't. I tried answering the third question like this.
    main.cpp:

    functions.cpp:

    functions.h:

    Thanks in advance.
    ********EDIT***********
    I'm an idiot,I always typed comma instead of a dot while typing float numbers.
    I still wonder is this better than the solution showed.

  • Avijit Pandey

    I attempted question number 4, and here's my solution:

    So, i noticed that mine is considerably shorter than yours, what i want to know is if it is a good practice to keep your code as comapct as possible or not, additionally, if i made any novice mistakes that i am not noticing since its not causing any problems as of yet.

    • * Line 6: Use double literals when calculating with doubles (2.0 instead of 2).
      * Line 10, 13: Limit your lines to 80 characters in length for better readability on small displays.
      * Inconsistent formatting. Use your editor's auto-formatting feature.

      > is a good practice to keep your code as comapct as possible
      No. Compact code is often harder to read and less reusable. You cannot calculate the height at a given time without printing it. Alex can.

  • Hi Alex!

    Q2 encourages the use of of types (@std::int16_t) that were previously warned about (Lesson 4.6).

  • Louis Cloete

    Hint #2 at Q3: should be operator== (equality comparison, not assignment)?

  • Louis Cloete

    I don't understand Quiz Q2 e-g. What is the question asking?

Leave a Comment

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