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

  • AC

    I tried to finish the calculator code you started but it says there are errors. Can you please tell me what is wrong?

    • Alex

      What errors are you getting?

      • AC

        There's an error that states "No 'object' file generated."

        There's also a warning that states "'getEquationAnswer'; not all control paths return a value."

        • Alex

          Oh, you have treat warnings as errors turned on. The compiler is complaining that all return paths are conditional, so if you pass in a different value (e.g. mop = 5) then you'll reach the end of the function without hitting a return value. This can be fixed by adding a non-conditional return statement to the end of your function.

          Add a return -1; before the closing curly brace of function getEquationAnswer().

  • Billy alonge

    Hi Alex,

    Thank you for this good site
    I am new here but found your site and method of teaching very nice
    about the calculator code i have to change the void print result ()
    and return 0;before my progran will compile correctly dont think any other people came across these issue

    • Hi Billy!

      There's nothing wrong with the last snippet in this lesson. If you can't compile it, make sure you properly set up your compiler/IDE to avoid running into more problems in the future.

      • WhackGuy

        I encountered this kind of error and warning:
        error C2220: warning treated as -no object file generated
        warning C4100 'argv': unreferenced formal parameter
        warning C4100 'argv': unreferenced formal parameter

        and this is the code. ive been looking for almost 30mins so i can debug that error. can you tell me what is wrong with this.

  • Zeni

    First thanks for such a nice website for learning C++.
    Next I would like to know your expert opinion about writing an algorithm using tools like Open Office Draw or Microsoft Visio before starting at actual coding.
    Some people are very much against it, but personally I find it very helpful in case of complex programs.

    • If you find it helpful, draw diagrams. If you're working in a big team, draw diagrams (Or write everything down).
      If you already worked it out in your head or would rather find a solution by coding, don't draw diagrams.

    • Alex

      Agree with Nascardriver. Draw diagrams if you find them useful or need to share with others, don't if you don't.

  • MrStark

    int calculateResult(int x, int op, int y)
        // note: we use the == operator to compare two values to see if they are equal
        // we need to use if statements here because there's no direct way to convert op into the appropriate operator

        if (op == 1) // if user chose addition (#1)
            return x + y; // execute this line
        if (op == 2) // if user chose subtraction (#2)
            return x - y; // execute this line
        if (op == 3) // if user chose multiplication (#3)
            return x * y; // execute this line
        if (op == 4) // if user chose division (#4)
            return x / y; // execute this line
        return x + y; // if the user passed in an invalid op, we'll do addition.

        // we discuss better error handling in future chapters

    Does not function stops at first return? In previous lecture, it was mentioned that after first return, everything after it is ignored. Also does not if statement requires {} for its correct execution?

    • Hi Mr. Stark!

      > Does not function stops at first return?
      Correct, but each return is only executed, if the condition in the if-statement is true.

      > does not if statement requires {}
      An if-statement without curly brackets considers the next statement (code until the next semicolon) as it's body. Curly brackets are only required if the body exceeds one statement. This is covered in a later lesson and was not used here, because there are more people who are confused by curly brackets than there are people who are confused by missing curly brackets.

  • Hey
    Is there anyone to tell me that Why this program wasn't showing Result.

    using namespace std;
    int getUserInput()
        int value;
        cout << "Take value from user:";
        cin >> value;
        return value;

    int getMathematicalOperation()
        int op;
        cout << "Choose Operator (1=+,2=-,3=*,4=/):";
        cin >> op;
        return op;

    int calculateResult(int x , int op, int y)
        if (op==1)
            return x + y;
        if (op== 2)
            return x - y;
        if (op == 3)
             return x * y;
        if (op == 4)
             return x + y ;

    int printResult(int result)
        cout << "Your Result is :" << result << endl;
    int main()
        int input1 = getUserInput();
        int op = getMathematicalOperation();
        int input2 = getUserInput();
        int result = calculateResult(input1, op,input2);
            return 0;


  • weed

    Doesn't getUserInput() and getMathematicalOperation() violate the "one task" rule by printing out the instructions in the same function as getting the input? Should I be cautious of this? If I replaced the cout lines with an initialization for a gui pop-up, would this violate the one task rule too?

    • Alex

      To me, the primary objective of the functions are to get user input -- prompting the user to do so is just part of facilitating that task. There probably isn't much value in separating them, as you'd almost never want to do one without the other.

  • Ahmed Abbas sd

    Hi Alex
    hi nascardriver
    well i tried to find other methods to make the calculator.
       so i came up with this
    I noticed that when calling a function arguments are always read from right to left
       do you talk about this in future lessons
         if not could you point me to where i could find more about this, so not to bother you too much

    • nascardriver

      Hi Ahmed!

      The evaluation order of arguments is undefined.

      • Ahmed Abbas sd

        so there is a way to define the evaluation order of arguments
           good to know
        will it be discussed later

        sorry for asking too much
        thank you in advance

        • nascardriver

          If you want your functions to execute in a specific order you need to call them before calling the target function an store their return values in temporaries:

          This way the three functions are guaranteed to execute in the specified order.

  • Hi,

    tried as suggested by designing the whole thing separately using Notepad++ with a plan and all then wrote the following:

    Header file is simple here:

    Keep getting same build error of <<Severity    Code    Description    Project    File    Line    Suppression State
    Error    C4700    uninitialized local variable 'f' used    Dipole    c:\users\nigel\documents\visual studio 2017\projects\dipole\dipole\dipole.cpp    20 >>

    • don't worry, sorted it myself - simply removed the f from the call to getFeq. Now line 20 reads double f = getFreq();

      • nascardriver

        @f in the header is never used, but you have another "f" in @Dipole.cpp. This will cause a collision sooner or later.
        The parameter of @getFreq isn't used, declare it as a local variable instead.
        Don't define variables in header files.

  • Dear Teacher, please let me point out that in your program call user to do operation, including division, on two integers. Result is integer by definition, then, in most cases, is in error.

    • Raviu

      Actually, No.
      Dividing two integers with an int return type results in an integer without decimals - no floating point.
      So 30/10=3 and 33/10=3 also.

  • Trevor

    Can anyone explain me what this "==" symbol does in more details? Thank you for your time (:

    • nascardriver

      Hi Trevor!

      == is used to compare two values
      = is used to assign a value to a variable

      • Trevor

        nascardriver, Thanks for the reply.

        But what do we do by comparing values? Why we need to compare values?

        • nascardriver

          Comparing values is used for all kinds of stuff:
          Do these players have the same score? Tie
          Do we have the right amount of ingredients? Cook
          Did the user enter "Hello"? Write world

          • luqman

            HI, Anyone could help me, this is my first assignment. i really wanted to know for my reference next future. help me, thank you a lot

            write a program to input 5 integar numbers. after the data have been entered, make the program to display the numbers.
            modify the programs so that the numbers displayed will be double from the original values.
            modify the program to find the smallest number in the array
            modify the program so that after display the lowest value, the program will also display the sum of all the values.

  • Prabhat Kumar Roy

    Dear Sir!

    In line no.s 30 through 39, variable 'y' has been used, but it has never been declared;
    how can it be possible?

    Thank you.

    Best regards.

  • Silviu

    Hello . So why didn't you use the switch statement, eliminates the possibility to choose another number ? I'm not saying that your code is written wrong or something, of course your code it's explained very well.

  • Shaheen

    Hi, I tried and my program successfully compiled, however, I am curious to know one thing here; instead of using int for all the functions and variables, is it possible to use floats in order to get appropriate values/ decimal values (especially with the division operator)? If yes how? It would be great if anyone can guide me through. I am using Microsoft Visual Studio 2017.

    • nascardriver

      Hi Shaheen!
      It's as simple as replacing every 'int' with 'float'. I used 'double' as a double is more precise than a float.

  • new student

    Thanks for the lessons.
    One note, this lesson does not appear good and adapted on mobile, unlike other lessons.
    thank you

  • merocom

    • Maxixxx

  • merocom

  • Abdulrahim Rana

  • James Smith

    At "Step 1: Define the problem", it is written "I want a better way to keep track of my friend’s phone numbers." Instead of the singular possessive "friend's" don't you mean the plural possessive "friends'"?

  • Robert

    Hi Alex,

    I have been trying different inputs in the Calculator program to try and break it, for fun. For input1, I entered 999999999999999 so the value overflows. This is what the debugger shows (Xcode on mac):
    input1    int    2147483647
    op    int    32767
    input2    int    32767
    result    int    -2147450882

    My question is, why are the input1 and result int's 4 bytes long (32 bit) and the op and input2 int are only 2 bytes long (16 bit)? Why aren't all of the int's in my program the same length? It seems strange.


    • Alex

      That does seem strange. Are you sure those integers are actually 2 bytes? Or is it just that they've taken the largest 2-byte value for some reason?

      • Robert

        You are correct, they are actually all 4 byte int’s. I used the sizeof() function, this is the output:
        sizeof intput1 = 4
        sizeof op = 4
        sizeof intput2 = 4

        I have not figured out why the value of op and input2 is still only the largest 2 byte value that can be stored. This is my code, if of interest:

        • MikeL

          Robert, I made some minor changes and I am not seeing the input size issues that you saw. Very likely they are due to compiler differences. I am running g++ 4.6 on an Ubuntu Linux machine.
          Can you try rerunning with the slight changes I made? I don’t expect it to fix your problem, but I am curious.

  • William

    Last bulletpoint in step 1 is missing.

  • SoulSeeker

    At what point did we give variable y an input

  • Frodo

    Maybe somebody else mentioned this but I think "I want to write a phone book application to help me keep track of my friends’ phone numbers." is not a problem and should not be in Step 1 : Define the problem.

    You are basically suggesting a solution (a phone book app ... ) in the definition of your problem.

    The problem is "I can't keep track of my friends' phone numbers".

  • Shahmeer

    why do we have to return -1 in calculateresult() function??!!
    And why don't we use:
    int result = calculateResult(int input1, int op, int input2)
    And can we return 0 at the end of main func.?

    • Alex

      If the user passes in an invalid operation, none of the if statements will match. The function says it returns an int to the caller -- so what should we return? I picked -1 -- which is a poor choice, because the entire range of integers is potentially valid, so there's no way to differentiate a valid result from an invalid one. In reality, we'd use some other error handling mechanism to avoid this situation altogether -- but we covered those yet.

      In any case, I changed the behavior of the function so that if the user passes in an invalid op, it will now default to addition.

      I also updated the code to explicitly return 0 at the end of main.

  • Rudi

    Someone please help me troubleshoot this. No matter what I do or name things I get an error "calculateResult function does not take 3 arguments"

    int getFirstInt()
        std::cout << "Please enter your first integer: ";
        int x;
        std::cin >> x;
        std::cout << "You entered " << x << std::endl;
        return x;

    int getMathOp()
        std::cout << "Please enter which operator you want (+, -, *, /)";
        char op;
        std::cin >> op;
        std::cout << "You entered " << op << std::endl;
        return op;

    int getSecondInt()
        std::cout << "Please enter your second integer: ";
        int y;
        std::cin >> y;
        std::cout << "You entered " << y << std::endl;
        return y;

    int calculateResult(int x, char op, int y)
        if (op == '+')
            return x + y;
        if (op == '-')
            return x - y;
        if (op == '*')
            return x * y;
        if (op == '/')
            return x / y;
        return 0;

    int main()
        int x = getFirstInt();

        char op = getMathOp();

        int y = getSecondInt();

        int result = calculateResult(x, op, y);

        std::cin.ignore(32767, '\n');
        return 0;


  • Gurdeep Singh

    Alex You are a great teacher.

  • Ekis

    This is good?

  • himanshu


    #include <iostream>
    using namespace std;
    int getUserInput()
        cout << "Please enter an integer: ";
        float value;
        cin >> value;
        return value;
    int opp()
        cout << "enter operator  1= +,2= -, 3= /, 4= * ";
        int op;
        cin>> op;
        return op;

      float expression( float x,int op, float y)
        return x+y;

        return x-y;

        return x/y;

        return x*y;

        return 8;

    void output( float result)
        cout<< "the result is: "<<result;

    int main()
        int value1=getUserInput();
         int op=opp();
        int value2=getUserInput();

        float result= expression(value1,op,value2);


        return 0;

    • Alex

      function getUserInput() is returning an integer, so the user's floating point input is being implicitly converted to an integer. Your compiler should be generating a warning about this.

    • Ekis

  • himanshu

    HI ALEX!
    WHERE IS SECOND GetUserInput()

    • Alex

      GetUserInput() is a reusable function. We can call it as many times as we need. We call it twice.

      Once to get the first user input:

      And once to get the second user input:

      These are then passed into function calculateResult() as parameters x and y.

      • himanshu

        THANK YOU

        • Alex

          Yes, it's very important to learn about the debugger if you're going to be developing a non-trivial program. A release build target is used when you want to release your program to others, as it optimizes your code for speed and size rather than easy debugging.

  • Ahmed Hamzah

    Hello Alex!
    Sorry for disturbing you again.
    Following is a program which is almost exactly the same as the calculator program above, but with certain variations.
    The program doesn't seem to compile. At the 45th line the compiler says " error : expected primary-expression before 'int' ".
    Could you please help me out? Thank you very much!

    Also, should there be a 'return 0' at the end?

    • Siddharth Singh

      Hi Ahmed,
      Replace line 45 with the following

      Since you have already initiallized the variables p,q and r and you only need to pass them into the function.
      We generally specify the type of the variable during initiallization only and not when we are passing them into a fuction.
      Hope this helps

    • Alex

      should be

      The return 0 at the end of main() is optional, but I like to include it.

  • Ahmed Hamzah

    Hey there Alex!
    Thank you for teaching me the basics of C++!
    I was trying to create a program that would calculate the percentage. Although there are no errors, the percentage is always 0. Could you please look into the program and tell me what is wrong?

Leave a Comment

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