2.13 — How to design your first programs

Now that you’ve learned some basics about programs, let’s look more closely at how to design a program.

When you sit down to write a program, generally you have some kind of idea, which you’d like to write a program for. New programmers often have trouble figuring out how to convert that idea into actual code. But it turns out, you have many of the problem solving skills you need already, acquired from everyday life.

The most important thing to remember (and hardest thing to do) is to design your program before you start coding. In many regards, programming is like architecture. What would happen if you tried to build a house without following an architectural plan? Odds are, unless you were very talented, you’d end up with a house that had a lot of problems: walls that weren’t straight, a leaky roof, etc… Similarly, if you try to program before you have a good game-plan moving forward, you’ll likely find that your code has a lot of problems, and you’ll have to spend a lot of time fixing problems that could have been avoided altogether with a little thinking ahead.

A little up-front planning will save you both time and frustration in the long run.

In this lesson, we’ll lay out a generalized approach for converting ideas into simple functional programs.

Design step 1: Define your goal

In order to write a successful program, you first need to define what your goal is. Ideally, you should be able to state this in a sentence or two. It is often useful to express this as a user-facing outcome. For example:

  • Allow the user to organize a list of names and associated phone numbers.
  • Generate randomized dungeons that will produce interesting looking caverns.
  • Generate a list of stock recommendations.
  • Model how long it takes for a ball dropped off a tower to hit the ground.

Although this step seems obvious, it’s also highly important. The worst thing you can do is write a program that doesn’t actually do what you (or your boss) wanted!

Design step 2: Define requirements

While defining your problem helps you determine what outcome you want, it’s still vague. The next step is to think about requirements.

Requirements is a fancy word for both the constraints that your solution needs to abide by (e.g. budget, timeline, space, memory, etc…), as well as the capabilities that the program must exhibit in order to meet the users’ needs. Note that your requirements should similarly be focused on the “what”, not the “how”.

For example:

  • Phone numbers should be saved, so they can be recalled later.
  • The randomized dungeon should always contain a way to get from the entrance to an exit.
  • The stock recommendations should leverage historical pricing data.
  • The user should be able to enter the height of the tower.
  • We need a testable version in 7 days.

A single problem may yield many requirements, and the solution isn’t “done” until it satisfies all of them.

Design step 3: Define your tools, targets, and backup plan

When you are an experienced programmer, there are many other steps that typically would take place at this point, including:

  • Defining what target architecture and/or OS your program will run on.
  • Determining what set of tools you will be using.
  • Determining whether you will write your program alone or as part of a team.
  • Defining your testing/feedback/release strategy.
  • Determining how you will back up your code.

However, as a new programmer, the answers to these questions are typically simple: You are writing a program for your own use, alone, on your own system, using an IDE you purchased or downloaded, and your code is probably not used by anybody but you. This makes things easy.

That said, if you are going to work on anything of non-trivial complexity, you should have a plan to backup your code. It’s not enough to just zip or copy the directory to another location on your machine (though this is better than nothing). If your system crashes, you’ll lose everything. A good backup strategy involves getting a copy of the code off of your system altogether. There are lots of easy ways to do this: Zip it up and email it to yourself, copy it to Dropbox or another cloud service, FTP it to another machine, copy it to another machine on your local network, or use a version control system residing on another machine or in the cloud (e.g. github). Version control systems have the added advantage of not only being able to restore your files, but also to roll them back to a previous version.

Design step 4: Break hard problems down into easy problems

In real life, we often need to perform tasks that are very complex. Trying to figure out how to do these tasks can be very challenging. In such cases, we often make use of the top down method of problem solving. That is, instead of solving a single complex task, we break that task into multiple subtasks, each of which is individually easier to solve. If those subtasks are still too difficult to solve, they can be broken down further. By continuously splitting complex tasks into simpler ones, you can eventually get to a point where each individual task is manageable, if not trivial.

Let’s take a look at an example of this. Let’s say we want to clean our house. Our task hierarchy currently looks like this:

  • Clean the house

Cleaning the entire house is a pretty big task to do in one sitting, so let’s break it into subtasks:

  • Clean the house
    • Vacuum the carpets
    • Clean the bathrooms
    • Clean the kitchen

That’s more manageable, as we now have subtasks that we can focus on individually. However, we can break some of these down even further:

  • Clean the house
    • Vacuum the carpets
    • Clean the bathrooms
      • Scrub the toilet (yuck!)
      • Wash the sink
    • Clean the kitchen
      • Clear the countertops
      • Clean the countertops
      • Scrub the sink
      • Take out the trash

Now we have a hierarchy of tasks, none of them particularly hard. By completing each of these relatively manageable sub-items, we can complete the more difficult overall task of cleaning the house.

The other way to create a hierarchy of tasks is to do so from the bottom up. In this method, we’ll start from a list of easy tasks, and construct the hierarchy by grouping them.

As an example, many people have to go to work or school on weekdays, so let’s say we want to solve the problem of “go to work”. If you were asked what tasks you did in the morning to get from bed to work, you might come up with the following list:

  • Pick out clothes
  • Get dressed
  • Eat breakfast
  • Drive to work
  • Brush your teeth
  • Get out of bed
  • Prepare breakfast
  • Get in your car
  • Take a shower

Using the bottom up method, we can organize these into a hierarchy of items by looking for ways to group items with similarities together:

  • Get from bed to work
    • Bedroom things
      • Get out of bed
      • Pick out clothes
      • Get dressed
    • Bathroom things
      • Take a shower
      • Brush your teeth
    • Breakfast things
      • Prepare cereal
      • Eat cereal
    • Transportation things
      • Get in your car
      • Drive to work

As it turns out, these task hierarchies are extremely useful in programming, because once you have a task hierarchy, you have essentially defined the structure of your overall program. The top level task (in this case, “Clean the house” or “Go to work”) becomes main() (because it is the main problem you are trying to solve). The subitems become functions in the program.

If it turns out that one of the items (functions) is too difficult to implement, simply split that item into multiple sub-items/sub-functions. Eventually you should reach a point where each function in your program is trivial to implement.

Design step 5: Figure out the sequence of events

Now that your program has a structure, it’s time to determine how to link all the tasks together. The first step is to determine the sequence of events that will be performed. For example, when you get up in the morning, what order do you do the above tasks? It might look like this:

  • Bedroom things
  • Bathroom things
  • Breakfast things
  • Transportation things

If we were writing a calculator, we might do things in this order:

  • Get first number from user
  • Get mathematical operation from user
  • Get second number from user
  • Calculate result
  • Print result

At this point, we’re ready for implementation.

Implementation step 1: Outlining your main function

Now we’re ready to start implementation. The above sequences can be used to outline your main program. Don’t worry about inputs and outputs for the time being.

Or in the case of the calculator:

Note that if you’re going to use this “outline” method for constructing your programs, your functions won’t compile because the definitions don’t exist yet. Commenting out the function calls until you’re ready to implement the function definitions is one way to address this (and the way we’ll show here). Alternatively, you can stub out your functions (create placeholder functions with empty bodies) so your program will compile.

Implementation step 2: Implement each function

In this step, for each function, you’ll do three things:

  1. Define the function prototype (inputs and outputs)
  2. Write the function
  3. Test the function

If your functions are granular enough, each function should be fairly simple and straightforward. If a given function still seems overly-complex to implement, perhaps it needs to be broken down into subfunctions that can be more easily implemented (or it’s possible you did something in the wrong order, and need to revisit your sequencing of events).

Let’s do the first function from the calculator example:

First, we’ve determined that the getUserInput function takes no arguments, and will return an int value back to the caller. That gets reflected in the function prototype having a return value of int and no parameters. Next, we’ve written the body of the function, which is a straightforward 4 statements. Finally, we’ve implemented some temporary code in function main to test that function getUserInput (including its return value) is working correctly.

We can run this program many times with different input values and make sure that the program is behaving as we expect at this point. If we find something that doesn’t work, we know the problem is in the code we’ve just written. Once we’re convinced the program is working as intended up to this point, we can remove the temporary testing code, and proceed to implementation of the next function (function getMathematicalOperation).

Remember: Don’t implement your entire program in one go. Work on it in steps, testing each step along the way before proceeding.

Implementation step 3: Final testing

Once your program is “finished”, the last step is to test the whole program and ensure it works as intended. If it doesn’t work, fix it.

Words of advice when writing programs

Keep your programs simple to start. Often new programmers have a grand vision for all the things they want their program to do. “I want to write a role-playing game with graphics and sound and random monsters and dungeons, with a town you can visit to sell the items that you find in the dungeon” If you try to write something too complex to start, you will become overwhelmed and discouraged at your lack of progress. Instead, make your first goal as simple as possible, something that is definitely within your reach. For example, “I want to be able to display a 2-dimensional field on the screen”.

Add features over time. Once you have your simple program working and working well, then you can add features to it. For example, once you can display your field, add a character who can walk around. Once you can walk around, add walls that can impede your progress. Once you have walls, build a simple town out of them. Once you have a town, add merchants. By adding each feature incrementally your program will get progressively more complex without overwhelming you in the process.

Focus on one area at a time. Don’t try to code everything at once, and don’t divide your attention across multiple tasks. Focus on one task at a time. It is much better to have one working task and five that haven’t been started yet than six partially-working tasks. If you split your attention, you are more likely to make mistakes and forget important details.

Test each piece of code as you go. New programmers will often write the entire program in one pass. Then when they compile it for the first time, the compiler reports hundreds of errors. This can not only be intimidating, if your code doesn’t work, it may be hard to figure out why. Instead, write a piece of code, and then compile and test it immediately. If it doesn’t work, you’ll know exactly where the problem is, and it will be easy to fix. Once you are sure that the code works, move to the next piece and repeat. It may take longer to finish writing your code, but when you are done the whole thing should work, and you won’t have to spend twice as long trying to figure out why it doesn’t.

Don’t invest in perfecting early code. The first draft of a feature (or program) is rarely good. Furthermore, programs tend to evolve over time, as you add capabilities and find better ways to structure things. If you invest too early in polishing your code (adding lots of documentation, full compliance with best practices, making optimizations), you risk losing all of that investment when a code change is necessary. Instead, get your features minimally working and then move on. As you gain confidence in your solutions, apply successive layers of polish. Don’t aim for perfect -- non-trivial programs are never perfect, and there’s always something more that could be done to improve them. Get to good enough and move on.

Most new programmers will shortcut many of these steps and suggestions (because it seems like a lot of work and/or it’s not as much fun as writing the code). However, for any non-trivial project, following these steps will definitely save you a lot of time in the long run. A little planning up front saves a lot of debugging at the end.

The good news is that once you become comfortable with all of these concepts, they will start coming more naturally to you. Eventually you will get to the point where you can write entire functions without any pre-planning at all.

2.x -- Chapter 2 summary and quiz
2.12 -- Header guards

344 comments to 2.13 — How to design your first programs

  • Todd

    Another quick grammatical fix (user 'Twisted Code' alluded to this):

    "That’s a more manageable....However, in this case, 'Do research on carrots is somewhat vague'..."

    should be

    "That’s more manageable....However, in this case, 'Do research on carrots' is somewhat vague..."

    (remove 'a' before 'more' and end quotes after 'carrots' not 'vague')

    Thanks for hearing feedback!

  • crelm

    Hi. I was just wondering if there was any way to create an error message for the calculator, as from what I can understand it will only return -1 if you input a number greater than 4.

    • Alex

      In this program, not really. The problem here is that -1 could be an error value or a legitimate value, and there's no way to tell the difference.

      There are many ways to fix this problem. One of the easiest would be to write a validateOperator() function that returns true if operator is valid and false otherwise. Then you could do something like this:

  • Joeri Vanden Abeele

    Hello. Can you explain this pleace?  How does the program links the nInput1 and the nInput2 to the nX and nY? You tell him to return nX nOperator and nY, to the main.

    • Alex

      When CalculateResult() is called, the value of nInput1 is copied into parameter nX, the value of nOperator is copied into parameter nOperator, and the value of nInput2 is copied into parameter nY.

      The function code determines which value is returned to the caller. This return value is then assigned to variable nResult.

  • Jeremy

    OK so I found another typo in "Step 2" - there's a period missing after the bulleted sentence:

  • David

    Okay so I made a programm that is suposed to convert usd to euros or euros to usd. But I cant get it to work. Despiting my input, it always converts dollars to euros. What did go wrong?

    #include <iostream>
    #include <string>
    using namespace std;
    int getEur()
    int x;
    cout << "Enter ammount of euros to convert";
    cin >> x;
    return x; // x is the euros ( if wanted ) the user typed in.

    int getUsd()
    int y;
    cout << "Enter ammount of dollars to convert";
    cin >> y;
    return y; // y is the dollars ( if wanted ) the user typed in.

    int convertEU()
    int a = getEur(); // attempt to get euros
    return (a * 1.08735); //conversion to dollars

    int convertUE()
    int b = getUsd(); // attempt to get dollars
    return (b * 0.91966); // conversion to euros

    int choose()
    cout << "Type the currency your value uses. (usd / eur)";
    string input;
    cin >> input; // read the users' currrent currency.
    int x = 1;
    int y = 2;
    if (input == "usd") { // return x if it are dollars
    return x;
    else if (input == "eur") // return y if it are euros
    return y;

    int main()
    int a = choose();
    if (a = 1) { // convert usd to euros if chooses' returning was 1
        cout << "The entered value equals: " << convertUE() << "euros" << endl;
    else if (a = 2) { // convert euros to usd if chooses' returning was 2
    cout << "The entered value equals: " << convertEU() << "usd" << endl;
    I didnt know who to ask or where to put it and I hope you can help me lol.

  • Alex

    Error C1083 means the file can't be found.

    I suspect your main.cpp has a line that looks like this:

    But stdafx.h hasn't been included as part of your project.

    Two suggestions:
    1) Make sure your project is a Win32 console application instead of an empty project
    2) You can create stdafx.h if it doesn't exist and add it to your project. The file can be empty, so long as it exists.

    • Scott Matejka

      I think visual studio is too advanced. The functions and even tabs are quite intimidating.

      As a win32 console application it loads a wall of text that is Greek to me so far.  I can't get a grip on where to insert anything and its possible interactions with the stuff they already have up.

      Is there an IDE for newbies/idiots?

      • Tito

        I am using Eclipse IDE and find it simple enough.

      • David

        I use Code::Blocks and yeah, its very easy to use.

      • Alex

        Personally I found Visual Studio easier to use than Eclipse or Code::Blocks. It does have a lot of complexity, but you'll learn to ignore most of it, as it's not relevant. Visual Studio has a fantastic integrated debugger as well.

        Since you're finding Visual Studio complicated, you could try Code::Blocks or Eclipse, but I suspect you won't find them too much different.

    • obwan02

      on my visual studio it uses

      #include "stdafx.h"

      intead of <stdafx.h> maybe that might make a difference

  • Scott Matejka

    Hi Alex,

    I'm really having trouble with the user friendliness of the IDEs.  I'm currently trying to use visual studio.  And I get a Fatal Error C1083 for #include "stdafx.h".

    I'm opening a new empty project in C++.

    Do I need to download that directory from somewhere?
    What am I doing wrong?

  • Sandro

    Help plez. It sais that in main, that CalculateResult is no matching operator.

    Using c++ xCode

    • Alex

      On line 26, you have:

      Note that this function takes no parameters.

      On line 57, you have:

      Note that you're trying to pass 3 parameters to this function.

      Consequently, there's a mismatch between the function definition and the function call.

      Your function call to CalculateResult() is correct. Your definition of CalculateResult() needs some work. :)

    • Abilasha

      Correct code is:

  • Twisted Code

    That’s a more manageable, as we now have three tasks that we can focus on individually. However, in this case, “Do research on carrots is somewhat vague”, so we can break it down further:
    i don't think this is formatted properly...

  • Jay

    Hey, I just wanted to say thanks for this awesome tutorial, I hope that once you reach a point where you are satisfied. That you publish this work in book. I've read many books on C++, but none have had this level of clarity to them. You're doing great work.

  • Hi,

    everything is great. But at the very end the redirection arrows are wrong =P

    Not that it's so important but... it's harmless to fix it.


  • DDrum

    I think the arrows to the links to next or previous chapter are switched. I displays an arrow to the left for the next chapter and an arrow to the right for the previous chapter.

    Great tutorial by the way.

  • artxworks

    So in this example I can actually ask the user to give me 3 numbers by using only 1 "int getNumber()" function .... then call it whenever I want a new user input by changing the variable ....

    int user1 = getNumber();
    int user2 = getNumber();
    int user3 = getNumber();

    etc ...

    then just tweak the corresponding equations in the calculate and result functions ..... that's nice ..... wow I just started yesterday and I'm getting really hooked on C++ .... well, your way of explaining things is really easy to understand .... thanks Alex.

  • Ollie999

    Great tutorials thanks and some good advice in this section.

    I would just like to point out that it's not only new programmers who make the mistake of not bothering with any pre-planning before they start coding. I've worked in software development for many years and quite a high proportion of the experienced developers I work with repeatedly make this mistake on every project and then wonder why they spend most of their working life debugging their code. I would urge anyone new to programming to heed the advice here and put some time into planning out programs in some detail before you start coding. This will avoid a lot of debugging and I can confirm from experience that debugging badly written code is probably the most mind-numbingly tedious activity I've ever come across.

  • Need some help with the calculator code. I wrote it and compiled it. It worked, with small numbers and adding/subtracting. I used it in my other program but when I got someone to test it they used big numbers. It works but gives wrong answer. And if it's a really big number then it just shows the 3 outputs at the same time, asking for operator, new number and result, in the same row and gives result as 0.
    This is what happens:
    Please enter a number: 586565730854226435643
    Please enter an operator (+,-,*,/): Please enter a number: Your result is: 0
    I can't work out where I went wrong.

    • artxworks

      "int" has limits ... try using "double"

      int = signed: -2147483648 to 2147483647
      unsigned: 0 to 4294967295

      double = +/- 1.7e +/- 308 (~15 digits)

  • Maksism

    Finally got it

    • Cleverlegs

      Very nice, but remember that you don't need two different functions to get numbers. i.e
      GetNumber1() and GetNumber2() can be replaced with GetNumber(). Since they're doing the exact same thing

  • Lakshya

    very nice tutorial

  • jlovejoy

    This is my second time reading through this chapter and one particular issue that caught my eye is that in section 0.1, you say "We will also avoid the twin evils...and the unexplained new concept, where a new concept that is integral to the example is introduced without any mention of what it is or how it works..."

    However, in section 1.10a, you use the command "char" without having ever introduced it, or its function anywhere in the tutorial. I was able to eventually pick up on what it did, but still very confusing for first time programmers.

    • Alex

      Guilty as charged.

      I find myself in a tough position here. In order to really make the point of this lesson stick, it's necessary to use a non-trivial example. But I couldn't think of a non-trivial example that didn't use at least one concept I haven't introduced yet.

      I've updated the example to remove the use of "char", but the user of "if" and operator== still remain. I've added a little bit of additional description around these to hopefully make it easier for readers to understand what they are doing.

  • Leo

    Usually in tutorials they talk about the language, and not about this kind of stuff. This is awesome!

  • Phil

    I have read through all the stuff before it now, and i think this is an ideal moment to say thanks for these amazing guides! I just wrote my first program all myself, (basic but it makes me look clever to my friends ;)), it basiclly just adds to numbers together, find multiples, although i did manage to use a IF thingy, (i looked at the later chapter). So YEAH! Just shows how well you have wrote your guides :)

    Thanks sooo much
    I'm gonna be reading all of this no matter what so watch out for more of my posts.


  • Eric

    I must say, I absolutely love your tutorials!
    It's extremely easy to understand, and is fun too!

    I've been doing programming for several years now.
    So far, I know the following: HTML, CSS, JS, PHP, VB.Net & GML.

    I wanted to expand my coding knowledge, and begin writing PC games in C++.
    Sadly, I wasn't able to find any good, full tutorials.

    That is.. Until I found yours!

    Your tutorials are the best on the web, and I thank you for that!



  • Johnny

    Amazingly simple -- awesome work -- thanks!! You definitely used KISS (keep it simple stupid) LOL Again, thanks!!

  • armian

    Thank you a lot for this magical tutorial!!!

    I have a question:"How can I compile my program if I haven't finished it yet?"
    When i compile to see if i have any error till here,my Bloodshed Dev-C++ "says" that i have too many mistakes!

    Thanks a lot again!

    • Alex

      Ideally, you should never end up in this situation -- if you write one piece at a time, and test it, you should never have a ton of code that won't compile, or more than a few errors.

      But if you do end up in this case, one thing that can be helpful is to comment out as much code as necessary until your program compiles. Then you can start uncommenting things (in an order that makes sense) and fixing errors along the way.

  • User1

    I recently decided to teach myself C++ because I would like to get into game programming and well I am glad I found this wonderful tutorial. I understand it will take time and am willing to do give time, but I'm curious if I will be able to make a 2D World (as stated in this article) soon seeing as I am on Chapter 2 at the moment and am a bit confused how to put graphics to program.

    • kurt

      Putting graphics into a program usually uses separate libraries that incorporate c++ to teach the graphics to react/act to one another.
      It is a lot to understand if you want to make games with c++, I am taking a Game Design + Development course and c++ is more used for larger scale games that require a team to implement it.

      If you want to create indie games (games created by you, yourself) you may want to start coding with another program like Flash AS3 (ActionScript) or java.

      This is a really good tutorial on c++ though from all the online / book instructions I have come across (which is a lot) and c++ is really important to know on any coding scale. I would recommend googling graphics programming and see what comes up. Check out DirectX or SDL which are c++ graphic related libraries and there are probably more, those are the only two I know about and somewhat know how to use. DirectX is a very LARGE library though and can be kind of overwhelming. OpenGL is another graphics related one, but I am not sure if it uses windows programming (which is still c++ the libraries are just different)

      Correct me if I am wrong anybody, open to any critiscm.

      Thanks for the great tutorial!

  • Lawrence G

    Fantastic guide, I have been trying to write this carrot report for months; your simple breakdown made it possible.

    • Merv

      Haha me too! Not just those pesky carrot reports, getting dressed and ready for work was a real challenge for me, but now I have this amazing tutorial at hand.

  • tartan

    Thank you very much for this tutorial. Seems to be the best online cpp tutorial so far, and I find this part and your comments on coding style of as great importance as explanation of commands, functions etc.

  • William Manson

    I tried to make a program that does simple operations, but it doesn't seem to work.

    The piece in particular:

    The compiler (code::blocks) gives the error, "error: expected ';' before "chOperation"" and "error: expected ';' before "nInput2""

    I'm trying to make the function return an operation, e.g. 3 + 5 or 4 / 14 or 14 % 8, is this not how I would accomplish this?

    • Deyan

      The "return" function can only return one value at a time. Thus the compiler is expecting to see a ; after nInput1.

      If you really must return more than one value, you may want to try using global variables.

      Good Luck.

    • Alex

      chOperation is a character, not an operator, and there's no way to directly convert one to the other.

      You'll have to use "if" statements to convert each value of chOperator into the respective operator (if chOperator is the '+' character, then do the plus operation)

  • Freacky

    I think you exchanged the arrows with next/previous steps.
    I think this is a very good and "noob friendly" tutorial too, good job ;).

    [ Thanks for the note about the arrows. Fixed! -Alex ]

  • Milten

    Very well done!
    Btw: Thank you very much for your great tutorial!

Leave a Comment

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