Search

2.x — Chapter 2 summary and quiz

Quick Summary

A function is a reusable sequence of statements designed to do a particular job. Functions you write yourself are called user-defined functions.

A function call is an expression that tells the CPU to execute a function. The function initiating the function call is the caller, and the function being called is the callee or called function. Do not forget to include parenthesis when making a function call.

The curly braces and statements in a function definition are called the function body.

The return type of a function indicates the type of value that the function will return. The return statement determines the specific return value that is returned to the caller. This process is called return by value. Functions can have a return type of void if they do not return a value to the caller. Failure to return a value from a non-void function will result in undefined behavior.

The return value from function main is called a status code, and it tells the operating system (and any other programs that called yours) whether your program executed successfully or not. By consensus a return value of 0 means success, and a positive return value means failure.

A function parameter is a variable used in a function where the value is provided by the caller of the function. An argument is the specific value passed from the caller to the function. When an argument is copied into the parameter, this is called pass by value.

C++ does not define whether function calls evaluate arguments left to right or vice-versa.

Function parameters and variables defined inside the function body are called local variables. The time in which a variable exists is called its lifetime. Variables are created and destroyed at runtime, which is when the program is running. A variables scope determines where it can be accessed. When a variable can be accessed, we say it is in scope. When it can not be accessed, we say it is out of scope. Scope is a compile-time property, meaning it is enforced at compile time.

Refactoring is the process of breaking down a larger function into many smaller, simpler functions.

Whitespace refers to characters used for formatting purposes. In C++, this includes spaces, tabs, and newlines.

A forward declaration allows us to tell the compiler about the existence of an identifier before actually defining the identifier. To write a forward declaration for a function, we use a function prototype, which includes the function’s return type, name, and parameters, but no function body.

A definition actually implements the (for functions and types) or instantiates (for variables) an identifier. A declaration is a statement that tells the compiler about the existence of the identifier. In C++, all definitions serve as declarations. Pure declarations are declarations that are not also definitions (such as function prototypes).

Most non-trivial programs contain multiple files.

When two identifiers are introduced into the same program in a way that the compiler can’t tell them apart, the compiler or linker will produce a naming collision. A namespace guarantees that all identifiers within the namespace are unique. The std namespace is one such namespace.

The preprocessor is a process that runs on the code before it is compiled. Directives are special instructions to the preprocessor. Directives start with a # symbol and end with a newline. A macro is a rule that defines how input text is converted to a replacement output text.

Header files are files designed to propagate declarations to code files. When using the #include directive, the #include directive is replaced by the contents of the included file. When including headers, use angled brackets when including system headers (e.g. those in the C++ standard library), and use double quotes when including user-defined headers (the ones you write). When including system headers, include the versions with no .h extension if they exist.

Header guards prevent the contents of a header from being included more than once into a given code file. They do not prevent the contents of a header from being included into multiple different code files.

Quiz time

Question #1

Write a single-file program (named main.cpp) that reads two separate integers from the user, adds them together, and then outputs the answer. The program should use three functions:

  • A function named “readNumber” should be used to get (and return) a single integer from the user.
  • A function named “writeAnswer” should be used to output the answer. This function should take a single parameter and have no return value.
  • A main() function should be used to glue the above functions together.

Show Hint

Show Hint

Show Solution

Question #2

Modify the program you wrote in exercise #1 so that readNumber() and writeAnswer() live in a separate file called “io.cpp”. Use a forward declaration to access them from main().

If you’re having problems, make sure “io.cpp” is properly added to your project so it gets compiled.

Show Solution

Question #3

Modify the program you wrote in #2 so that it uses a header file (named io.h) to access the functions instead of using forward declarations directly in your code (.cpp) files. Make sure your header file uses header guards.

Show Solution


3.1 -- Syntax and semantic errors
Index
2.13 -- How to design your first programs

70 comments to 2.x — Chapter 2 summary and quiz

  • Gustav

    Hi Alex, great tutorial, learning a lot!
    I just want you to comment on my code

    Is there a better way of writing this?

    • nascardriver

      Hey Gustav!

      In your current code, this doesn't matter, but you might want to move the calls to `readNumber` out of the call to `writeAnswer`. It's unspecified if the left or right `readNumber` is called first. As I said, irrelevant now, but if one `readNumber` affects the other, this will cause trouble that you might not spot.
      Otherwise your code looks good, you could look into an auto-formatter to format your code consistently.

      • Gustav

        Thanks for your feedback, I just realized that I gave you the first draft of my code
        Anyways, here's the final iteration.

        Onto the next chapters.

        ~Cheers!

  • Thevnort

    For question 3, as part of the quiz, why did you add '#include "io.h"' to io.cpp when the IDE (Visual Studio 2019) knows to reference the .cpp files?

    • See here
      https://www.learncpp.com/cpp-tutorial/header-files/comment-page-8/#comment-398571
      or here
      https://www.learncpp.com/cpp-tutorial/header-files/comment-page-8/#comment-413858

      This question has been asked several times, you might get more information from reading the comments of lesson 2.11 https://www.learncpp.com/cpp-tutorial/header-files/comment-page-8/#comments

  • Ayberk

    If main function returns negative number then what happens ?

  • Marie Bethell

    Does the order of #includes matter? As in, should #include <iostream> come first or #include "io.h". Thanks!

  • Nikolas

    Is it bad practice to have your print/cout statements inside functions? I started learning to program with Python and was told it was bad practice to have my user interaction code inside functions

    • You can't have code outside of functions in cpp, so no, it's not bad practice.
      You should separate logic and io.

      • John

        nascardriver, I want to start by saying thank you so much for your work here. The way things are worded and broken down has made it really easy to learn the concepts so far. I have a similar question as Nikolas:

        2.5 — Why functions are useful, and how to use them effectively

        New programmers often combine calculating a value and printing the calculated value into a single function. However, this violates the “one task” rule of thumb for functions. A function that calculates a value should return the value to the caller and let the caller decide what to do with the calculated value (such as call another function to print the value).

        Just going off of the above, wouldn't you say that it is more appropriate to have the the cout statement in the main function? Although you are not really doing anything with the input from the user in readNumber() except for returning it, one can argue that communicating with the user for an input and getting(and returning) the input with the same function are two separate tasks.

  • Jake

    How come for the second quiz, in the main.cpp file you did not use #include <iostream>.

  • Bharat

    Hi,
    just wondering why you did not use int x{0}. Instead you just did int x. Are they both the same?
    Edit: Also, I copied and pasted excersise 1 into visual studio and there seems to be a build error. Any ideas?
    Error:    LNK2019    unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)Line 1

    • They're not the same, use

      Without the curly brackets, the value of `x` is undefined and reading from `x` produces undefined behavior.

      There's nothing wrong with the code. Make sure you saved the file before compiling it.

      • Bharat

        I still have the error in line 1, these are the errors. I saved it too.
        1)
        https://docs.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-error-lnk2019?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DEN-US%26k%3Dk(LNK2019)%26rd%3Dtrue&view=vs-2019

        2)
        https://docs.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-error-lnk1120?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DEN-US%26k%3Dk(LNK1120)%26rd%3Dtrue&view=vs-2019

    • Alex

      I updated the answers to use x {} (as per the best practice to initialize all variables). Thanks for pointing out the omission.

  • Nirbhay

    Hello!

    Is #include "blabla.h" in the first line of blabla.cpp redundant?
    As blabla.cpp already defines(so automatically declares) some functions in it. So it doesn't need to include the declarations and therefore the header file.

    Am I correct?

    Thanks :)

    • Hello!

      It can help you detecting errors early. See my comments here
      If you like foxes
      https://www.learncpp.com/cpp-tutorial/header-files/comment-page-8/#comment-413858
      If you like cats
      https://www.learncpp.com/cpp-tutorial/header-files/comment-page-8/#comment-398571

  • Samovar

    I run the following:

    [code]
    #include<iostream>

    int readNumber()
    {
        std::cout << "Enter a number: ";
        int x;
        std::cin >> x;
        return x;
    }

    void writeAnswer(int x)
    {
        std::cout << "The answer is " << x << '\n';
    }

    int main()
    {
        int x { readNumber() };
        int y { readNumber() };
        writeAnswer(x + y); // using operator+ to pass the sum of x and y to writeAnswer()
        return 0;
    }
    [\code]

    I run the code on Code::Blocks 13.12 on a MacBook Pro. The code did not compile. I receive
    "line 18 error:expected ' ; ' at end of declaration."

    as well as

    "line 18 error:expected ' ; ' at end of declaration."

    Please advise.

    • It appears you didn't enable C++11 or later. Make sure you followed lesson 0.10 and 0.11.
      Closing code tags use a forward slash (/).

      • Samovar

        I followed lesson 0.10 and 0.11.
        4 warnings are enabled in the compiler flags.
        1 phrase typed "-Wsign-conversion -Werror" in the other options.

        Still, the same 2 errors persist:

        "line 18 error:expected ' ; ' at end of declaration."
        "line 19 error:expected ' ; ' at end of declaration."

        The entire code is reproduced below:

        Please advise.

  • PRANAV AGARWAL

    Thanks a lot, Sir.

  • Lawrence

    Thanks alot for all your hard work! Words can't explain how thankful we are!

  • alfonso

    "Scope is a compile-time property, meaning it is enforced at compile time."

    I need more help with this. I "know" the scope is created (and destroyed) at runtime. No function call then no scope at all. So what does it mean "enforced"?

    Like that?
    Lifetime of the scope -> runtime.
    Scope (as access meaning) -> (is determined at) compile-time.

    • Alex

      Scope isn't created and destroyed at runtime. Scope is a compile-time property, meaning the compiler enforces the scope of an object. Enforces in this context means the compiler will give you an error if you try to access an object that is not in scope.

      There's no such thing as "lifetime of the scope". Lifetime is a property of objects. Since objects are only created/destroyed at runtime, this is a runtime property.

      For local objects, scope and lifetime are intertwined, in that the lifetime of local objects is defined by their scope -- that is, they are created at the point where they come into scope, and destroyed at the point where they go out of scope.

  • Paveun

    Is it required to include the header in the io.cpp file being referenced by said header?

    Also in main(), is there a reason not to simply put

    Thanks!

    • > Is it required to include the header in the io.cpp file
      No, but it can be helpful.
      See my comment in lesson 2.11 (mew.hpp and mew.cpp should be cat.hpp and cat.cpp)
      https://www.learncpp.com/cpp-tutorial/header-files/comment-page-8/#comment-398571

      > is there a reason not to simply put
      It's unspecified whether the left or right @readNumber will be called first. Since they're the same, it should be a problem. If you require a specific order, you should use temporary variables.

  • Fisticuffs

    The solution for question 3 includes io.cpp which is copied below. Although there is an io.h file as part of the solution, it isn't #included in io.cpp. However, there is a best practice note from section 2.11 that states that, "A code file should #include its paired header file (if it exists). If you’re curious as to why, see nascardriver’s comment here."

    So, although not necessary to make this work correctly, should there be a '#include "io.h"' line in the io.cpp file?

  • Dave Sosa

    Hello just wondering why you need to put int "int x" in "voide writeAnswer(int x). Why is the "int x" necessary.

    • Alex

      The writeAnswer is expecting the caller to pass in a value to print -- therefore, it needs to take a parameter, so that the caller can pass in a numeric argument to print.

  • Hi Alex!

    There's a trend to omit the trailing printed line feed lately. You talked about this in lesson 1.5 and I don't think it could be explained a lot better than you did. Maybe a spot-the-problem quiz helps.

    • Alex

      Just to be clear, are you saying the trend is to move from this:

      To this?

      Or are you saying it's to move from this:

      To this?

      Please clarify and then I can try to address. :)

      • This, where "Line 2" is the last thing printed by the program. Your first example has the same problem.
        Not printing a line feed at the end of the program will cause the prompt printed by the terminal to be printed on the same line as "Line 2".

  • phoenix blue

    excuse me, First thanks for the tutorial. In earlier chapter you said that it's better to use uniform intialization. But now why are you using direct intialization? (Quiz #1)

    so uh.. which one should be prefered?
    For now I will proceed to use uniform intialization following earlier chapter, I would like to know if there is reasoning behind the use of copy intialization or if I got it wrong.

  • Kushahl

    In question #2

    My source files are:

    First program:

    #include <iostream>                //This includes IOStream header file bot basic input and output
        int main()
        {
            int readnumber();
            void writeanswer(int x);
            int x,y;
            std::cout<<"Enter 2 numbers to add"<<'\n';
            y=readnumber();
            x=readnumber();
            writeanswer(x+y);
        return 0;
    }    

    io.cpp

    int readnumber()            //This function reads a function
        {
            int x;
            std::cin>>x;
            return x;
        }
        void writeanswer(int x)
        {
            std::cout<<" Your answer is : "<<x;
        }

    stdafx.cpp

    // stdafx.cpp : source file that includes just the standard includes
    // Firstprogram.pch will be the pre-compiled header
    // stdafx.obj will contain the pre-compiled type information

    #include "stdafx.h"

    // TODO: reference any additional headers you need in STDAFX.H
    // and not in this file

    I get below error

    :1>------ Build started: Project: Firstprogram, Configuration: Debug Win32 ------
    1>  io.cpp
    1>c:\users\kusingh\documents\visual studio 2012\projects\firstprogram\firstprogram\io.cpp(4): error C2039: 'cin' : is not a member of 'std'
    1>c:\users\kusingh\documents\visual studio 2012\projects\firstprogram\firstprogram\io.cpp(4): error C2065: 'cin' : undeclared identifier
    1>c:\users\kusingh\documents\visual studio 2012\projects\firstprogram\firstprogram\io.cpp(9): error C2039: 'cout' : is not a member of 'std'
    1>c:\users\kusingh\documents\visual studio 2012\projects\firstprogram\firstprogram\io.cpp(9): error C2065: 'cout' : undeclared identifier
    1>  Firstprogram.cpp
    1>  Generating Code...
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    I do not get any compile error when I add include<iostream> in the file io.cpp, but I do get below warning after program is successfully executed.

    'Firstprogram.exe' (Win32): Loaded 'C:\Users\kusingh\Documents\Visual Studio 2012\Projects\Firstprogram\Debug\Firstprogram.exe'. Symbols loaded.
    'Firstprogram.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ntdll.dll'. Cannot find or open the PDB file.
    'Firstprogram.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel32.dll'. Cannot find or open the PDB file.
    'Firstprogram.exe' (Win32): Loaded 'C:\Windows\SysWOW64\KernelBase.dll'. Cannot find or open the PDB file.
    'Firstprogram.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcp110d.dll'. Symbols loaded.
    'Firstprogram.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcr110d.dll'. Symbols loaded.
    The program '[8976] Firstprogram.exe' has exited with code 0 (0x0).

    My questions:

    Should we not include same header files in multiple files ?
    What does these warning signify even though program executed successfully ? I also noted that execcution window did not wait for me to press enter to exit unlike everytime. It did ask me in my successful program in previous question number 1.

    Thankyou so much for these tutorials.

    Regards
    K

  • Arthur

    hi, I have no experience with code and just started this tut. yesterday , I do not have an IDE yet (space problems on solid-state c drive) so am using notepad++ to write out answers for now. had to cheat a bit on answer 1 but was pretty close. as this tutorial is being updated I am unsure if I have used recommended brackets appropriately, and am wondering if I am understanding what the code is doing. I am assuming this program will work , will print to the console "basic addition:", "enter number  :", "enter number  :", "answer equals :" and the numbers will all be in a vertical line in the console. criticism is welcome. (hope I get the code tags right)

    thanks for any feedback

    • Arthur

      or it might work if I fixed line 2

      2 #include<iostream>

      :-\ lol

    • Hi Arthur!

      If you don't have access to a normal compiler, you can use an online compiler (eg. https://www.onlinegdb.com/online_c++_compiler ).

      Apart from the include,
      * Line 9, 13: You don't need to use << to concatenate strings. Use

      * Line 38: 'B' should be 'b'.

      Your initializations are correct.

      • Arthur

        thank you for the feedback , I am thinking on Code::Blocks but would rather decide if I have aptitude before installing software. I went and looked at some other basic beginners material to see if I could apply things from this tutorial in to my own idea. I needed random numbers for the idea, not  sure on that part, perhaps you could have a look and tell me if this is about where a noob should be this far in the tutorial? I didn't comment a lot but it is likely obvious to you...

        • There are multiple errors in your code. Try to compile it (You don't need to download anything, you can do it online), fix the errors and auto-format your code.
          For being written without tests, the code looks good for a beginner.

          • Arthur

            thanks again, I tried that online compiler you pointed me to, it helped , I got it to run but will need to review material and read some more on formatting the auto function on that site just moved all of the curly brackets. I would probably get more random questions having the child enter one of the numbers.

            • Formatted code for line references:

              * Line 9: Use braced initializer lists.
              * Line 9: Unnecessary call to @std::rand.
              * Missing call to @std::srand.
              * Line 10: Signed/unsigned conversion
              * Line 18: Should be a for-loop.
              * Use '\n' instead of @std::endl, unless you have a reason to use @std::endl.
              * Line 20-23: Favor initialization over assignment.
              * @test should be a bool.
              * Use ++prefix unless you need postfix++.
              * Line 58 doesn't do anything.
              * Missing printed trailing line feed.

              • Arthur

                ok I think I covered all of the issues , you suggested. I simplified 'randomNum' , tried to get rid of unnecessary things and gave more specific variable names. to learn the idea of this chapter test would at the end of line 33 I be looking to pass 'answer' to a third function and return a bool true/false to line 42?

                • Arthur

                  here is what I got for putting this into the files in question 3.

                  io.cpp

                  io.h

                  main.cpp

                  • Arthur

                    thanks @nascardriver the online compiler worked good, and I appreciate the feedback. I think this one is what the tutorial is teaching. thanks @ Alex for the tutorial.
                    io.cpp

                    io.h

                    main.cpp

                • * Line 17: Initialize your variables with brace initializers. You used copy initialization.
                  * Line 14: Use std::rand instead of it's global-namespaced counterpart.
                  * Line 14: Use std::time instead of it's global-namespaced counterpart.
                  * Line 9: Signed/unsigned conversion. Let's ignore this until casts have been covered.
                  * Line 14: Use @nullptr instead of @NULL.
                  * The while-loop was better. Sorry, I didn't go through your logic before.
                  * Still poor formatting. I hope this gets better once you use a code editor if you decide to keep going.
                  * @test is unnecessary. You can replace line 42 with line 38.
                  * Use '\n' unless you have a reason to use @std::endl.
                  * Unnecessary spaces before printed line breaks.

                  File separation for quiz 3 looks good. "io" doesn't fit the file's contents.

  • WSLaFleur

    So, here's my code for Quiz time, Question #1:

    When I spoiled the answer, I was surprised that you weren't using the initialization method you described for the variables (i.e. {}). Is this just something that wasn't updated to reflect changes to the core material?

    Also, I don't really understand what I'm doing with std::cin.ignore(2) - the program is running as intended, but unless I feed the cin.ignore function a value greater than 1, it fails to pause. If you're not too busy to explain, then do you know why this is happening?

    • Hi!

      > I was surprised that you weren't using the initialization method you described for the variables
      Alex didn't update most of the lessons yet. Chapter D and onward use copy- and direct initialization.

      * Line 8: Limit your lines to 80 characters in length for better readability on small displays.
      * Line 22: Don't compare booleans to false/true.
      * Use the auto-formatting feature of your editor.
      * Line 25: Declare one variable per line.
      * Don't use @system.
      * Line 13: Initialize to a specific value (0).

      @std::cin.ignore(count, delim) ignores all characters until delim is found or count characters have been ignored.
      By passing 1 you're ignoring at most 1 character. Since the only character left by @readNumber is a line feed (Because you press enter and @std::cin::operator>> doesn't remove the line feed), this line feed is removed and execution continues.
      If you pass 2 and the only character is a line feed, @std::cin.ignore will halt until a second character has been entered.
      Pass @std::numeric_limits<std::streamsize>::max() and '\n':

      If you don't understand a standard function, you can look them up in a documentation: https://en.cppreference.com/w/cpp/io/basic_istream/ignore
      These might be hard to understand just yet, but once you know C++, a good documentation is priceless.

      • WSLaFleur

        Thanks for the reply, I've been using cppreference to dig into any syntax I'm unclear or just curious about, but I'm unfamiliar with concepts like 'delim', which makes understanding the full context difficult sometimes.

        So I tend to squirrel down a rabbit hole of syntax links for a while and then return to writing my code after a bit. I realize we haven't hit booleans yet, I'll definitely adopt best practices for them whenever we arrive.

        Thanks again!

  • Suyash

    #include <iostream>

    using namespace std;

    int readNumber();
    int writeAnswer();

    int main()
    {
        cout<<"Welcome "<<endl;
        cout<<"Enter your number "<<endl;
        int a=readNumber();//Unused variable
        cout<<"Enter the other number "<<endl;
        int b=readNumber();//Unused variable
        cout<<"The total is "<<writeAnswer();
        return 0;
    }
    int readNumber()
    {
        int x;
        cin>>x;
        return x;
    }
    int writeAnswer()
    {
        int a,b;//uninitialized variable
        return a+b;
    }

    /*
    Hello Alex,
    I wrote this after reading all three of the quiz questions, therefore I used declarations so as to make it easy for me for the next two. It compiles, but shows four  warnings, stating 1. Unused variables, 2.Uninitialized variable for each a&b. I modified writeAnswer (And its declaration) to:
    void writeAnswer();
    void writeAnswer()
    {
        int a;//uninitialized variable
        cout<<a;
    }
    but then it shows an error saying:
    too many arguments to function 'void writeAnswer()'
    but then I initialised it in my declaration. so the other two errors are left
    no match for 'operator<<'
    and whole lot of ostream errors.

    Thank you! for the tutorials
    */

    • Hi!

      Functions cannot see variables declared inside other functions. @writeAnswer doesn't know about @a and @b in @main. You have to pass them as arguments.
      @a and @b in @main get assigned a value, but after that, they're never used.
      If @writeAnswer is declared

      the "void" means that it doesn't return a value. But in @main you're trying to print the value returned by @writeAnswer. This value doesn't exist, so you get an error.
      Please use code tags (Yellow box below the comment text field) and exact error messages.

Leave a Comment

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