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

Now that we’ve covered what functions are and some of their basic capabilities, let’s take a closer look at why they’re useful.

Why use functions?

New programmers often ask, “can’t the code we’re putting inside the function just be put directly inside main?” In many cases (particularly for simple examples), it can. However, functions provide a number of benefits that make them extremely useful in non-trivial programs.

  • Organization -- As programs grow in complexity, having all the code live inside the main() function becomes increasingly complicated. A function is almost like a mini-program that we can write separately from the main program, without having to think about the rest of the program while we write it. This allows us to divide complicated tasks into smaller, simpler ones, and drastically reduces the overall complexity of our program.
  • Reusability -- Once a function is written, it can be called multiple times from within the program. This avoids duplicated code and minimizes the probability of copy/paste errors. Functions can also be shared with other programs, reducing the amount of code that has to be written from scratch (and retested) each time.
  • Testing -- Because functions reduce code redundancy, there’s less code to test in the first place. Also because functions are self-contained, once we’ve tested a function to ensure it works, we don’t need to test it again unless we change it. This reduces the amount of code we have to test at one time, making it much easier to find bugs (or avoid them in the first place).
  • Extensibility -- When we need to extend our program to handle a case it didn’t handle before, functions allow us to make the change in one place and have that change take effect every time the function is called.
  • Abstraction -- In order to use a function, you only need to know its name, inputs, outputs, and where it lives. You don’t need to know how it works, or what other code it’s dependent upon to use it. This is super-useful for making other people’s code accessible (such as everything in the standard library).

Although it doesn’t look like it, every time you use std::cin or std::cout to do input or output, you’re using a function provided by the standard library that meets all of the above criteria.

Effectively using functions

One of the biggest challenges new programmers encounter (besides learning the language) is learning when and how to use functions effectively. Here are a few basic guidelines for writing functions:

  • Code that appears more than once in a program should generally be made into a function. For example, if we’re reading input from the user multiple times in the same way, that’s a great candidate for a function. If we output something in the same way multiple times, that’s also a great candidate for a function.
  • Code that has a discrete set of inputs and outputs is a good candidate for a function, particularly if it is complicated. For example, if we have a list of items that we want to sort, the code to do the sorting would make a great function, even if it’s only done once. The input is the unsorted list, and the output is the sorted list.
  • A function should generally perform one (and only one) task.
  • When a function becomes too long, too complicated, or hard to understand, it should be split into multiple sub-functions. This is called refactoring.

Typically, when learning C++, you will write a lot of programs that involve 3 subtasks:

  1. Reading inputs from the user
  2. Calculating a value from the inputs
  3. Printing the calculated value

For trivial programs (e.g. less than 20 lines of code), some or all of these can be done in main(). However, for longer programs (or just for practice) each of these is a good candidate for an individual function.

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

We’ll investigate this topic in more detail in lesson 1.10a -- How to design your first programs.

1.4c -- Keywords and naming identifiers
1.4a -- A first look at function parameters and arguments

27 comments to 1.4b — Why functions are useful, and how to use them effectively

  • Ishana

    Hi Alex,

    Thank you for putting this new page up. It has given me a better insight to understand the functionality of functions in C++.
    And thank you for this great C++ tutorial website:)

    • Alex

      You’re welcome. Was the article clear? Are there any points that can be clarified further?

      • Ishana

        The article is clear as it is. It clearly communicated the idea of why functions are beneficial in programming. At first, I just learned about functions thinking of it as a necessary requirement, but this article helped me understood its meaning in much deeper context.

  • Can a function call itself? Does that make any sense?

  • HitoShura

    Thanks so much for explaining a lot on this topic and making it easier for us (me) newcomers to understand
    much appreciated

  • Miroslav

    Hello Alex, I really like your tutorial so far. I find it the easiest to learn from all of which I tried in the internet. Please keep up the good work 🙂
    Also I’ve got one question. You call a function which uses an argument and then returns a value that you will use later on. In the function though you change the argument that is passed to it. Is there a way to use that new value in main() (Basically I tried returning 2 values in one function xD of course it didn’t work, but I was wondering how I can use an argument from a function in main() )

    • Alex

      Yes, in chapter 7 we talk about reference parameters, which allow the value of a parameter that is changed in a function to be used by the caller.

      Here’s a sneak peak:

  • cei

    Hi. Thank you for this site, it is really helpful 🙂 .
    I would like to point out that there is a typo at the Reusability paragraph: it should be: "Once a function is written, it can be called […]".

  • Skizzy

    Hey there Alex just want to say i appreciate this site alot so far. I like how much detail and background goes into each lesson. Much better than most prior tuts ive read. in fact the program from the last quiz we had to do, i made very easily.

  • Jim

    Thanks for adding this section. However it brings up a lot of question to mind.  How do the pro’s store the functions they write?  Do they store functions for say integers and floats in different places.?  You mentioned retesting, does this mean that they don’t recompile the function again?  Can you give us some idea of how to do all these and expand on some of the points you listed above.  I would think a set of functions to add, subtract, multiply and divide two variables could be used for all of the intake,long,long long, float, etc., could be written with the same code with minor would the pro’s do that.  You could write a book on the things you mentioned in this section alone.

    • Alex

      Generally, pros will start creating pairs of header (.h) and code (.cpp) files that contain one of two things:
      1) A set of related functions -- For example, math.h and math.cpp would contain math-related functions (including versions for both int and double, if that’s relevant)
      2) A new data type -- For example, if you’re doing geometry, you might need a way to represent a Cartesian point. You could create a point.h and point.cpp that contains the definition for this new type.

      Once these files have been created and tested once, they can be copied and reused in other programs without having to retest them.

      You’re correct that functions to do arithmetic on different types (e.g. int and double) are essentially identical -- and yet, C++ makes you declare them as separate functions. This is where template programming comes in. You can declare a template function, and C++ will instantiate different flavors of that function for each type you call it with. So you could write a single template for function add(), and C++ could create an int and a double version based on this. This can be useful with functions -- it’s even more useful with “container objects” like arrays that need to be able to hold different types. Since template programming is an advanced concept (and the syntax is headache inducing), we talk about it much later in this tutorial series.

  • Tahir

    every time you use std::cin or std::cout to do input or output, you’re using a function provided by the standard library that meets all of the above criteria.

    This statement is not correct …
    cin and cout are not functions they are objects and when we use them the operator overloaded function cout.operator<<(expr ) will be called.

    • Alex

      The statement is correct as written. As you note yourself, when we use cin or cout to do input and output (via operator<&lt or operator>&gt), an overloaded function is called. That function meets the criteria listed.

  • Tony

    I would say easily one of the best tutorials so far. I’ve been through many tutorials that overlook certain points and don’t go into detail of what certain things mean… example "using namespace std", many tutorials do not explain what this is and why it’s needed of in your case, needed at all.

    Kudos to you, and can’t wait to go through the rest of the pages.

  • rdx

    hey alex,,,,hats off,,,a great tutorial,,

  • AmnesiaMaster28

    Hey Alex, I’m curious. Are there any guidelines to doing anything inside main? Like, is it better to do:


    • Alex

      Personally I like to keep my main() functions as simple as possible and delegate responsibilities to subfunctions, but that’s just a matter of style. When programs are this short, it doesn’t matter all that much.

  • Darren

    Learning the functionality of functions, in other words how functions function, was the main function of this page about functions. Function.

  • Hey Alex, I made this simple calculator program after last tutorial and I am wondering whether I should have split calculations and things up into functions, what do you think?

  • reznov

    So basicly instead of using namespaces you could also just write a function that uses std::cout and call a function that’s defined as printNumber(int x) for integers.
    My question is would this also work if I want to print text this way? Defining my function as printText(string x) ???

  • hakeem

    I can’t believe how awesome this tutorial is!!! I wonder if Alex has one for GoLang because that’s next on my list, anyways, kudos!!!

  • GEScott71

    Thanks Alex, this is a great explanation of functions.  I really appreciate you explaining the "why" behind many aspects of C++.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter