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

  • John

    what is that /2 in the equation?

  • Miquel

    Hey! Since i had looked up the basics in looping already i did the second problem a bit different, but I'd still love to have some feedback to my coding!
    Thanks Alex and nascardriver in advance thought, I love the work you both do!

    towerfall.cpp:

    constants.h:

    • Hi Miquel!

      * @ballHeight should be declared inside the loop.
      * Line 36 should be a break, because there could be code after the loop.
      * You're using the same name style for variables and functions, this can lead to confusion.
      * Line 28 should not be true if @ballHeight is 0.0, 0.0 is ground.

      Your code looks good overall, keep it up!

  • Sam

    Hey! I was wondering if you could possibly check over my solution for the second problem. It work's perfectly but I am wondering if there's anything I could have done better?

    main.cpp:

    constants.h:

    • main.cpp
      * Line 8: Initialize your variables with brace initializers.
      * Line 6, 16: Use double literals when calculating with doubles (2.0 instead of 2).
      * Line 21, 23, 25, 27, 29, 34: Limit your lines to 80 characters in length for better readability on small displays.
      * Use ++prefix unless you need postfix++.
      * You're using the same name style for variables, functions and namespaces. This can lead to confusion.
      * Line 21+: Don't repeat code.
      * @distanceFallen: Poor name. It calculates the new height.

      What if the ball is already on the ground before line 32?

  • Heisenberg

    Hey alex, This is the program I wrote for the problem given in quiz. it is giving satisfactory output. I just want to make sure whether this follows criterion of good programming practice.
    #include <iostream>
    double get_number()
    {
        double num{ 0 };
        std::cout << "enter the double value :";
        std::cin >> num;
        std::cout << std::endl;
        return num;
    }
    char get_char()
    {
        char ch{};
        std::cout << "Enter one of following: +, -, *, / :";
        std::cin >> ch;
        return ch;
    }
    void calculate()
    {
        double ans{ 0 };
        double x = get_number();
        double y = get_number();
        char c = get_char();
        if (c == '+')
            ans = x + y;
        if (c == '-')
            ans = x - y;
        if (c == '*')
            ans = x * y;
        if (c == '/')
            ans = x / y;
        std::cout << x << " " << c << " " << y << " is " << ans;
    }
    int main()
    {
        calculate();
    }

    • Please use code tags when posting code (Yellow box below the reply textbox)

      * Use '\n' unless you have a reason to use @std::endl.
      * Use descriptive variable names.
      * Use else-if.
      * Print a line feed at the end of your program.
      * Initialize your variables with brace initializers.
      * Use double literals when calculating with doubles (0.0 instead of 0).
      * @main: Missing return statement.

      • Heisenberg

        >Print a line feed at the end of your program.
           I didn't understood it.
        >Initialize your variables with brace initializers.
           What value should be used to initialize variable with char data type?(like we use 0 in case of int or 0.0 in case of double)

        • > Print a line feed at the end of your program

          When you don't print a line feed at the end of your program, the next line in the terminal will be appended to your program's last line.

          > What value should be used to initialize variable with char data type?
          You can use an empty list. I was referring to your variables in @calculate (@x, @y, @c). You initialized those using copy initialization.

  • Dimbo1911

    Any advices or remarks on the following?
    constants.h

    main.cpp

    • main.cpp
      * Line 11: Initialize your variables with brace initializers. You used copy initialization.
      * Unnecessary forward declarations. Move @main below the other functions.
      * Line 39, 47: Use double literals when calculating with doubles (0.0 instead of 0, 2.0 instead of 2).
      * Line 38-39: Initialize.

      • Dimbo1911

        Damn, you have a great eye for this, thx a lot. Btw is using the forward declarations by any means detrimental to the code (comparing it to writing code without them)? I use them for the sole reason of having a bit tidier code, I like having the main function first, but that might just be me.

        • Forward declarations add extra work when you update a function's signature (return type, name, parameter types, constness), because you'll have to do everything twice. Other than that they don't do any harm.

  • Rokki

    holy shit  it was so hard            

    constants.h:

    main.cpp:

    • Rokki

      here's a improved version

      main.cpp

      constants.h:

      it's much better and more practical than the solution i guess :D hehe

      • main.cpp
        * Line 22, 28: Initialize your variables with brace initializers. You used copy initialization.
        * 6, 11, 28, 31: Use double literals when calculating with doubles (1.0 instead of 1, 2.0 instead of 2, etc.).
        * Line 28, 33, 34, 38, 47: Limit your lines to 80 characters in length for better readability on small displays.
        * Line 14: Don't use @std::exit.
        * Line 22: Avoid abbreviations unless they're obvious.
        * Line 25: while (true)
        * @calculation_And_Print doesn't return anything, it should be void.
        * Line 34: Use ++prefix unless you need postfix++.

        constants.h
        * Line 5: 9.8 is a double, not a float. Enable compiler warnings.

  • Mitchell Zakocs

    This is my code I did for the extra credit question. Any suggestions or criticisms?
    Thanks!
    ~Mitch

    main.cpp

    constants.h

    I used the twoEq as the multiplier in the gravity equation. May have not been the best option, I decided to use It because of the suggestion of not using "magic numbers" in the lesson on Literals (D.2.8). I don't know if this is what you meant when you wrote the article, but I did it anyways :) Let me know if its wrong haha.

    • Hi Mitchell!

      main.cpp
      * Line 11, 16, 18, 21, 25: Limit your lines to 80 characters in length for better readability on small displays.
      * You're mixing int, float and double. double suits all of your uses.
      * Line 17: Use double literals when calculating with doubles (0.0 instead of 0)
      * Line 17, 21: Duplicate calculation of current height.

      constants.h
      * Line 4: Use float literals when calculating with float (2.0f (or 2f) instead of 2)

      > I used the twoEq as the multiplier in the gravity equation
      2 isn't use in place of value that represents anything. It's part of a mathematical formula and thus should not be replaced by a constant.

      • Mitchell Zakocs

        Thank you for the review! It really helps out a new coder :D

        For lines 17 and 21, the first calculation was for the if statement, but it would definitely be a better idea to put the calculation into a variable. Great suggestion!

  • Lorenz

    In previous lessons you suggest to use uniform initialization, and I did it

    now in your example you use the more common copy initialization

    now, coming from C and arduino the second one is the "standard", which one shall I use? what are the main benefits of using the uniform initialization over others? performance or just uniform "better" code?

    Thanks

  • Anonymous

    Hello! Site looks kind of alien now :P

    https://repl.it/@Cprogrammer/Calculator

    Here is my beaten-to-death calculator program. To handle errors when entering invalid operators I made 'getOperator()' return the garbage value 'f'. My question is should 'calculateAndPrintResult()' check for 'f' or for 'any value other than the operators' when displaying the error message? Would one be better or more efficient?

    Also I tried out some other programs on my own, let me know what you think about it:

    1. https://repl.it/@Cprogrammer/Shreedharacharya-Formula (Quadratic Formula)

    2. https://repl.it/@Cprogrammer/Factorial-Function (Factorial, upto 23 if I remember correctly)

    • General
      * Use the auto-formatting feature of your editor.

      Calculator
      * header.h: Poor name
      functions.cpp
      * Line 6, 14: Initialize your variables with brace initializers.
      * Q: Less efficient
      * Missing printed trailing line feed at the end of your program.

      Quadratic
      functions.cpp
      * Line 6: Initialize your variables with brace initializers.
      * Inconsistent naming.
      * Don't use abbreviations. Variable names should be descriptive.
      * Use long double literals when calculating with long doubles ('l' postfix).

      Factorial
      main.cpp
      * Missing printed trailing line feed.
      functions.cpp
      * Line 6: Initialize your variables with brace initializers.

      • Anonymous

        > Less efficient

        Checking for 'f' or not? And why?

        > Missing printed trailing line feed

        What is that?

        Also, anyway to make factorial program more efficient or able to accept input >20?

        • > Checking for 'f' or not?
          Checking for 'f' is less efficient. The more you do, the longer it takes.

          > What is that?

          The next thing that's printed will be on the same line as "Hello World".

          Do this instead

          • Anonymous

            > Checking for 'f' is less efficient.

            Is the difference significant?

            > Trailing line feed

            Why would it be required at the end of the program? Isn't the program going to terminate anyway?

            For the rest of the printed lines in all programs std::cin is being used so it automatically creates a new line after you enter input (I think) so it won't be required there.

            Also, anyway to make factorial program more efficient or able to accept input >20?

            • > Is the difference significant?
              Depends on your definition of "significant". You won't notice it. But if it's unnecessary, you shouldn't do it.

              > Why would it be required at the end of the program?
              If you're running the program from a console/terminal, whatever is printed after your program terminates will be on the same line.

              > anyway to make factorial program more efficient
              Don't use recursion (Don't let the function call itself).

              • Anonymous

                Thanks! I think all of this (ie trailing line feed, l suffix, empty initialization) etc should be included in the lessons. I don't think it is part of the lessons if I remember correctly.

                > Don't use recursion (Don't let the function call itself).

                Is there a better template for the factorial program? This one was from my textbook.

                Also is the input size capped at 20?

  • Gejsi

    This is my interpretation of exercise 3. I also used constants to represent the symbols. I know maybe constants might be unnecessary in this case, but I did it more to reinforce the past lesson and for muscle memory so I make it a habit instead of dropping magic numbers.

    • Hi!

      * Line 48: Limit your lines to 80 characters in length for better readability on small displays.
      * Line 30-36 should use your constants
      * @isSymbol: Missing return statement. Make sure you followed lesson 0.10 and 0.11.
      * Line 52: Unnecessary. All the checks are done again in the following lines.
      * Missing printed line feed at the end of your program.

  • Arthur

    not sure if I came up with something wrong because I missed a point? or just different because I read ahead at some of the loops?

    my constants.h

    io.cpp

    main.cpp

    • Arthur

      this one is probably better ?

      my constraints.h

      io.cpp

      main.cpp

      • * Use your editor's auto-formatting feature.

        my constants.h
        * Line 6: Initialize your variables with brace initializers. You used direct initialization.

        io.cpp
        * Line 6, 14, 21: Use double literals when calculating with doubles.
        * Line 14-15, 21-22: Initialize your variables instead of assigning.
        * You don't need to return from voids.
        *

        main.cpp
        * Line 5: Initialize your variables with brace initializers. You used copy initialization.
        * Line 7, 8, 9, 14: Use double literals when calculating with doubles.
        * @distance should be declared inside the loop.
        * Line 9, 14: Double comparison of @floor.

  • Smidge

    After hours of tinkering with my code I finally got it right. But I think that my code is a mess. If anyone can help me improve my code so I can spot the things I've done wrong.

    constants.h file

    main.cpp

    I used a loop on my first one but realized that I was cheating so I tried to do this again without using loops so I can improve my foundation.

    • Hi Smidge!

      * Use the auto-formatting feature of your editor
      * Use double literals when calculating with doubles (2.0 instead of 2, 0.0 instead of 0).
      * Line 25: Unnecessary comparison.
      * Line 7: Initialize to 0.
      * Line 23, 27: Limit your lines to 80 characters in length for better readability on small displays.
      * You're using the same name style for variable, functions, and namespaces. This can lead to confusion.

      • Smidge

        Wow! Thank you for your feedback! You're such a great help. Btw, I have a few questions still, they may seem stupid but I hope you can bear with me.

        * About auto-formatting feature.
        I'm currently using code::blocks and what could that feature be? is it when it auto tab a line when it is inside the curly braces?
        * Line 25: Unnecessary comparison
        I should use else here instead of else if right? since if(var <= 0) is false that means var is always greater that 0.
        I also realized here that I used the function's name as the condition instead of using variable.
        * Line 7: Initialize to 0
        Doesn't using uniform initialization automatically initialize the variable to 0 or is it just good programming practice to always initialize to 0?
        * Line 23, 27: Limit your lines to 80 characters in length for better readability on small displays.

        * Name style
        I can't for the life of me know how to name them properly. English being not my first language contributes to this I guess? It's just that I can't find a good descriptive name without ending up using the same name style. This really leads to confusion as what happened to me on line 20. Btw, can you give me some examples or tips on how to use a good name style? What are your suggestions on the names that I used on my code?
        Again thank you so much for reviewing my code.

        • > auto-formatting
          I don't have code::blocks, I hope these are still up-to-date
          http://forums.codeblocks.org/index.php?topic=12871.0
          https://stackoverflow.com/questions/26278082/is-there-any-shortcut-for-codeblocks-to-format-the-code
          I said this, because line 21 is missing 2 spaces (compared to line 25). The auto-formatter will make your code have the same spacing, indention, empty lines, etc. everywhere. It might also wrap lines, depending on how you configure it.

          > I should use else here instead of else if right?
          right

          > I used the function's name as the condition instead of using variable
          Your compiler should've warned you about this. Make sure you followed lessons 0.10 and 0.11.

          > Doesn't using uniform initialization automatically initialize the variable to 0
          It does. The 0 just makes it more obvious that the variable is zero-initialized. That way, someone who doesn't know C++ has a chance to understand what's happening.

          > Name style
          It's not about the meaning of names, but the capitalization of their names.
          You use camel case (Beginning of a word is capitalized) with a lower case first letter.
          By using different styles for different types, it's easier to tell them apart without looking at their declaration.
          Here's a part of my naming convention, I never finished it
          https://gitlab.com/Cre3per/conventions/blob/master/cpp.md#names

          • Smidge

            I actually followed both lessons 0.10 and 0.11 but I don't know how it happened but -Wsign-conversion -Werror is missing. on my settings. Thanks for that!
            btw the link says 404 page not found?

            • It's 2 links, here again, separated

              @Alex How about a whitelist for links?

  • Paulo Filipe

    Could any pro guy review my code for the question 4?

    I am reading these lessons for about a week and I am in love with programming!! Thanks to the authors for the effort put into these.
    Very comprehensive text!!

    I wanted to add an extra feature to the program to calculate the exact moment in seconds of when the ball hits the ground, so I did some Google searches and this is my program:

    const.h

    main.cpp

    I confess that I took a peak at how the main function was structured in the solution (I was stuck cuz I'm still a noob) but after that, never had to look into the solution anymore!

    • Hi Paulo!

      main.cpp
      * Line 18: Initialize your variables with brace initializers. You used copy initialization.
      * Line 18, 35: Use double literal when calculating with doubles (2.0 instead of 2)
      * Line 10, 26: Initialize your variables with brace initializers.
      * Line 31, 36, 38, 53: Limit your lines to 80 characters in length for better readability on small displays.
      * Line 25: Misleading reassignment. The new value is no longer a height

      • Paulo Filipe

        Thanks for the review, but I have one question:

        * Line 10, 26: Initialize your variables with brace initializers.
        Am I supposed to initialize  a variable that is going to be assigned a value in the next line inputted by the user?

        The rest was clear enough and I get it. =)

        • Yep, initializing everything prevents forgetting an initialization where you would have needed it.
          Prior to C++11, @std::cin::operator>> didn't override the value of the variable if extraction failed. Unless you read the documentation, don't assume a function is able to handle uninitialized variables.

  • Paulo Filipe

    How do I leave a comment with code? Sorry about the noob question.

  • Alireza

    What about this solution, I think it's shorter than others. X-D

    • * Line 12, 29: Initialize your variables with uniform initialization. You used copy initialization.
      * Line 18, 26, 27: Initialize your variables with uniform initialization.
      * Line 24, 31, 32, 37: Limit your lines to 80 characters in length for better readability on small displays.
      * Line 29: Use ++prefix unless you need postfix++
      * @main: Missing return statement
      * Line 37-42: Should use the conditional operator
      * Use double literals when calculating with doubles (2.0 instead of 2)

  • RVJonah

    I am really enjoying these tutorials and I learning a lot and fast. Can I make a suggestion that you change to the statement in the formula in part 4. It currently reads:
    "distance fallen = gravity_constant * x_seconds2 / 2"
    and to make it clear should read:
    distance fallen = (gravity_constant * x_seconds2) / 2
    as it is very easy to miss read this as
    distance fallen = gravity_constant * (x_seconds2 / 2)
    which gives completely different results.

  • Paul

    When attempting to debug how do you enter the value of variables such as the initial height used in question four?

    • Alex

      Once you debug past the line that accepts input, your program will wait for you to enter input before proceeding in the debugger. You should be able to enter input in the normal way, via the console window your program opens when it is launched.

  • FoxKid777

    • Hi!

      * Line 19, 21, 38, 39, 54: Initialize your variables with uniform initialization. You used copy initialization.
      * Line 31: Initialize your variables with uniform initialization.
      * Line 22, 37, 47, 49: Limit your lines to 80 characters in length for better readability on small displays.
      * Don't use "using namespace"
      * Use ++prefix unless you need postfix++
      * Use double literals when calculating with doubles (2.0 instead of 2)
      * Unnecessary forward declarations. Move @main below the other functions.
      * Line 49: height-height is 0.0

  • n1fty

    • constants.h
      * Line 5: Initialize your variables with uniform initialization. You used direct initialization.

      main.cpp
      * Line 8, 17, 18, 23, 24: Initialize your variables with uniform initialization. You used copy initialization.
      * Line 9, 40: Initialize your variables with uniform initialization.
      * Line 17, 26, 37: Limit your lines to 80 characters in length for better readability on small displays.
      * @main: Missing return-statement.
      * Line 8: 1 is an int. Use 1.0
      * Line 9, 10: @i should be declared in the for-loop's init block
      * Use ++prefix unless you need postfix++
      * Line 11: You can use the *= operator.
      * Line 17: 2 is an int, use 2.0
      * Line 28: +=
      * Line 25: 0.0
      * Line 43: Initialize to 0.0
      * Don't use "using namespace", it can lead to name collisions
      * You're using the same name style for variables, constants and functions. This can lead to confusion.

      • n1fty

        Very eye opening to have someone pick apart your code I love it man. I know better from reading on this awesome site. I did miss one thing.. Name styles. I'll shoot back and read again! And then I'll fix the issues for the sake of learning.

  • n1fty

    Is this how its done? I LOVE homework!

    • Hi!

      * Line 22, 48, 55, 67, 68, 70: Initialize your variables with uniform initialization. You used copy initialization.
      * Line 18, 43: Initialize your variables with uniform initialization.
      * Line 20, 24, 26, 52: Limit your lines to 80 characters in length for better readability on small displays.
      * Variable names should be descriptive.
      * @eCheck should be a boolean
      * Line 55: You're declaring a new variable called "eCheck", which is unrelated to @eCheck in line 48.
      * @std::cin.ignore ignores only 1 character unless you tell it do ignore more.
      * Line 37, 40: Can be replaced with

      * Line 26: | is a bitwise or, you want ||
      * Line 20, 26: Duplicate code
      * @errCheck should be a boolean

  • Nathan

    For some reason, this won’t work.  Can you help?

    If (seconds == 1 && height >= 0)
    ...

    It might be something else in the program, but everything else seems to run fine.  It won’t end up checking for the height.

  • Haydo

    Howdy, just wanted to see how I went for question 3, I realise that the solution written combines calculation and print. I wasn't sure if it was worth making another function just for print, but with the way I've determined operators it feels like that would add a bunch of useless lines to the code. Not sure if the 'do while' loops are up to standard either, I just wanted to do them so had a quick google.

    Thanks for the awesome lessons so far.

    • Hi!

      * Line 51, 53, 56, 58: Initialize your variables with uniform initialization. You used direct initialization.
      * Line 5, 12, 15, 47: Initialize your variables with uniform initialization.
      * Line 14, 42, 59: Limit your lines to 80 characters in length for better readability on small displays.
      * Line 17-23: Use the or-operator (||)
      * Line 26: You're setting @validResponse to true even if it's true already. A while(true) loop would've been more appropriate, since you're not using the condition.
      * @calculateResult: Missing return-statement. If a function has a non-void return type, it has to return.

      Splitting functions is usually a good thing to do.

      • Haydo

        Thanks for the comments, really appreciate the help. Just wanted to get some clarification as I go back and try to improve.

        I read in an earlier chapter that using direct initialization if a variable is going to be instantly assigned is fine. I can see why you would use uniform though, is this a best practice sort of thing?

        To split the lines that are over 80 characters should I just literally split them and use another std::cout to print again (e.g line 14)? I only ask if there is a way to improve readability whilst not adding an extra command.

        Using || was something I didn't think of that makes it much more concise.

        What I can't get my head around is making a concise while(true) loop. It seems super obvious but I cant think of it. I tried this:

        Which I thought would just check if it was a valid operator and print the message and repeat if it wasn't. It seems to just accept any input which will then cause an error when looked up later.

        I know this is probably super obvious but I can't think at the moment.

        Thanks again for all the help.

        • > I read in an earlier chapter that using direct initialization if a variable is going to be instantly assigned is fine
          That doesn't make a whole lot of sense. I could understand that not initializing a variable at all is fine if it's being assigned a value right after. But there's no point in saying initialization X is fine if a value is assigned right after. Could you try to find the lesson stating this?
          Assuming my guess is correct: Yes, you can omit initializations. But doing so could lead to forgetting an initialization where it's necessary, or removing the assignment later and forgetting to initialize the variable. I'm suggesting to initialize all variables, because it prevents you from doing hard-to-debug mistakes.

          > To split the lines that are over 80 characters [...]
          Line 14 could be split into 2 lines by splitting the output

          This adds another call to @operator<<, which slows down your program (minimally). Since this isn't sensitive code (ie. it doesn't require high efficiency), the reduced efficiency can be neglected.
          If efficiency was important (eg. if the code was in a rendering loop, which doesn't make sense, but let's say it was), you could split the string in 2 lines:

          Note that the second line cannot be indented, as the space would be part of the string.
          The messed up indentation is worse than exceeding 80 characters, so either keep the line as it is or split the output. The 80 character limit isn't a rule, it's a just a guideline.

          > enterOperator
          Line 8: You can't compare values like that.
          You first compare @userOperator to '+', this will evaluate to true if @userOperator is '+', as expected. The next expression is independent of the previous. '-' will be converted to a bool. Every non-zero value is true, so '-' is true and the if's condition is fulfilled.

          • Haydo

            That's what I meant just used wrong terms. Understood now though.

            All makes sense now though, as I thought I was just being an idiot.

            Thanks for that.

  • Anonymous

    Here is my gravity program: https://repl.it/@Cprogrammer/Gravity

    Any suggestions? I did it a little differently and a little clunkily too. I mainly wanted to not take up space by having lots of intermediate variables.

    • Hi!

      > I mainly wanted to not take up space by having lots of intermediate variables.
      You're using just as much memory as you'd do if your code was readable.

      main.cpp
      * The return value of @calculateAndPrintHeight is always the same as the value returned by @getHeight. Remove @calculateAndPrintHeight's return and store @getHeight's return value in a variable.

      constants.h
      * Use constexpr for compile-time constants

      functions.cpp
      * Line 6: Initialize your variables
      * Line 12: Variable names should be descriptive. Use single-letter names for iterators only.

      • Anonymous

        Updated based on your reccomendations: https://repl.it/@Cprogrammer/Gravity

        > * Line 6: Initialize your variables

        I didn't understand this. Elaborate? Do I have to initialize with blank values?

        > You're using just as much memory as you'd do if your code was readable.

        Why is that? I thought that having intermidiate variables would use up more memory as we now have to set aside memory for them.

        • > Elaborate

          This is the same as what you currently have, but this way even a non-cpp reader can know what the initial value of @height is. Initializing variables, even if they get overridden, places your program in a predictable state between declaration and assignment, which is good for debugging. It also prevents accidental use of uninitialized variables.

          > Why is that?
          When you're using the return value of a function without storing it, a temporary variable is created to store the return value.

          EDIT:
          * You're using the same name style for variables and functions. This can lead to confusion.
          * 0.5*constants::gravity could be stored in a constant so you don't have to recalculate it all the time

  • Anonymous

    Hey Alex! Nice to see the updated site.

    When I compile this(https://repl.it/@Cprogrammer/Calculator) or rather the part that has been commented out in main.cpp, it causes problems. More specifically the order of inputs is inverted. What could be the reason?

    • Hi!

      The evaluation order of function arguments is undefined. If you need your arguments to be evaluated in a specific order, do as you did in the code that works fine.

      • Anonymous

        Thanks! I have one question though. Why does it invert the order of the inputs specifically instead of doing something random everytime?

        • > instead of doing something random everytime?
          It is well defined what your compiler does, ie. the same will happen every time. But if you switch compilers, something else might happen. The behavior isn't standardized, so every compiler developer can make up something on their own.

          > Why does it invert the order of the inputs specifically
          I have to guess, because I'm not your compiler developer.
          I'm assuming you're compiling your program in 32bit x86. Most 32bit x86 calling conventions (if not all) pass arguments by pushing them onto the stack. They do so right-to-left. If you're calling a function and passing it's return value as an argument, the function call is only performed when the value is needed. Calling it earlier would be a waste of memory. Since arguments are pushed right-to-left, the second @getValue is called first, then @getOperator, followed by the first @getValue.

  • Hey, I finally got mine working but I noticed it's a bit different than the answer.  Also, I noticed that in the example answer they said the ball would have fallen 5 meters, and it's been 7 years since I've taken physics, but after one second shouldn't it have fallen 9.8 meters, then after two seconds 9.8 meters + (9.8 * 2)?  Anyways, I'll post my code, I appreciate any feedback.

    equations.h

    equations.cpp

    main.cpp

    • Note: I realize I used double for everything, I did this super late at night and was just trying to get it to work.

    • Hi Chris!

      > but after one second shouldn't it have fallen 9.8 meters
      Nope. After 1 second, your velocity is 9,8m/s. You fell 4,9m in that second. After 2 seconds you fell 19,6m. Wikipedia has all the handy formulas https://en.wikipedia.org/wiki/Equations_for_a_falling_body#Equations

      equations.cpp
      * Line 4: Initialize your variables with uniform initialization.
      * Line 5: Initialize your variables with uniform initialization. You used direct initialization.
      * @height should not be a global variable. Pass it around as an argument and return value.
      * Line 16, 22 and main.cpp line 8-13: Use double literals when calculating with doubles. (2.0 instead of 2, 0.0 instead of 0, etc.).
      * Line 23, 25: Duplicate code and strings. Use a conditional statement

      > I used double for everything
      double is the correct choice.

  • Oscar R.

    Hey Alex, I think the process you showed for Q3 is not a good practice because it disobeys the "One Function, One Purpose" rule that you talked about. In yours, printResult does two things - calculate the answer and print the result. Shouldn't those be two separate functions? Heres what I did.

    • Alex

      Your answer doesn't comply with the expected output of the program. It should print: 6.2 * 5 is 31, not "Your answer is: 31".

      For how you wrote your program, I think your answer makes sense. With my answer, both the text and the answer are conditional based on operator. I thought it was more comprehensible to combine them than have that conditional logic split out over two functions.

  • Oscar R.

    Shouldn't the answer for Q2A be const instead of int because the user's age does not change?

  • Sascha

    Hi my new compact code;

  • Sascha

    Hi, thats my solution of question nr.3

    • Hi Sascha!

      * Don't repeat code. It increases the binary's size and harder to update, often leading to undesired behavior.
      * Variable names should be descriptive
      * The first argument to @calc is unused
      * Initialize your variables with uniform initialization
      * Misleading formatting. Use the auto-formatting feature of your editor
      * Use double literals when calculating with doubles (2.0 instead of 2)

      Take a look at Alex' solution if you haven't already.

  • Oscar R.

    Hi, I'm getting an error when trying to compile a program i'm making and I do not understand the cause. Can you please help me?

    Error :

    ||=== Build: Debug in Area of Circle Calculator (compiler: GNU GCC Compiler) ===|
    D:\My Stuff\Projects\Learning C++\CBProjects\Area of Circle Calculator\main.cpp||In function 'int main()':|
    D:\My Stuff\Projects\Learning C++\CBProjects\Area of Circle Calculator\main.cpp|7|error: cannot convert 'float (*)()' to 'float' in initialization|
    ||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

    main.cpp:

    io.cpp:

    io.h:

Leave a Comment

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