How to Develop a Simple C Program
Last Revision: January, 1999
( McCann )

Students always seem to have trouble understanding (or maybe just doing) what I expect of them when I assign a program. The requirements are really very straight-forward; it's mostly a matter of leaving yourself plenty of time to get everything done.

To help you understand what's expected of you, in this document I'll take a simple sample programming assignment and guide you through the major steps in the program development process.

(If you are looking for details on program documentation, you will find some here but you really should visit my Programming Style page, which has my collection of style documents, including a few style pages from other people. Most of it is developed with experienced programmers in mind. This document is meant for students who are just starting to learn C.)


Step #1: Start Early
Programming is not an activity that can be reliably scheduled to take a predetermined amount of time. Even programs that look like they should be doable in 2 hours will often take 4 or 5 hours to complete. The best thing you can do for yourself is say, "I have no idea how long this will take; I'd better get started right away."

Step #2: Read the Assignment Handout Carefully
My programming assignment handouts tend to be very detailed, if not perfectly organized. Everything that I expect from you is given in there somewhere, so read it carefully and highlight the key points so that you don't overlook any of them.

For example, let's consider this example assignment:




COMSC 1613 – Programming I

(McCann)

Program #0: Calories Due to Fat

Due Date: Smarch 36th, 2028, at the beginning of class

System Requirement:

You must do this assignment on the AIX1 system.

Overview: Any dietician will tell you that limiting your daily fat intake to be under 30% of your total calories is a good idea. But how many of the calories in your favorite foods are from fat? Nutrition labels will tell you how many grams of fat are in a serving, and how many total calories are in that serving, but you need to do the rest of the figuring on your own.

As it happens, a gram of fat has about 9 calories. Therefore, if you take the grams of fat in a serving of a particular food, multiply it by 9 and divide by the total calories in the serving, you'll get the fraction of the calories due to fat. To get the result as a percentage, just multiply by 100.

For example, consider a product that has 3 grams of fat and 170 calories per serving. There are 27 calories due to fat (3 * 9), and 27 / 170 = 0.1588. Multiplying by 100 gives the final answer: 15.88 percent of the calories are due to fat.

Assignment: Write a complete, well-documented C program that begins by asking the user to enter the grams of fat and the calories in a serving of a food product. The program will compute the percentage of the food's calories that are due to fat, and will display the input information and the percentage in the form of a complete English sentence.

Data: Run your program twice, once for each set of data shown in the following table:

 

Fat (grams)

Total Calories

1

1

66

2

21

480

Hand In: On the due date, turn in the following items: A printout of your documented C program, and a printout of the output your program produced when run on each of the sets of data given above. Be sure to write your name in the upper right hand corner of the printout; this will make it easier for you to reclaim your program when I return it to you.




This is pretty typical of my program handouts. Things to notice: In this case, you need to write a program that gets two pieces of input, computes a percentage, and outputs all three pieces of information. This is obviously very simple, and the first program or two of the semester will be about as simple as this one. After that, they'll get more complex, so that you can start using more features of the language.

Step #3: Write the External Documentation
I can already hear the smirking ("Write comments now? Get serious!") but I am serious: You should write your documentation as you write the program, not afterwards. In particular, the External Documentation should be almost complete before you write even a line of code.

I hand out a one-page document to my programming classes that lists the information that I expect to see in your programs. In particular, here's what the External Documentation should contain:

  1. Your name, the course name, assignment name/number, instructor's name, and due date.
  2. Description of the problem the program was written to solve.
  3. Approach used to solve the problem. This should always include a brief description of the major algorithms used, or their names if they are common algorithms.
  4. The program's operational requirements: Which language system you used, special compilation information, where the input can be located on disk, etc.
  5. Required features of the assignment that you were not able to include.
  6. Known bugs should be reported here as well. If a particular feature does not work correctly, it is in your best interest to be honest and complete about your program's shortcomings.
To help you, I've created a template that you can import into your program that contains a label for each section that I want to see. All you have to do is fill in the blanks; I can't make it much easier than that. The Block Comment Templates with Examples page shows the External Documentation template, and you can find it on AIX1 in the file ~mc/docs/external.c as well. Having a copy on AIX1 is nice because you can use your editor's file import command (:r in the vi editor, for example) to drop it into your program; importing the template can save a lot of typing.

Here's what the template looks like:

/*=============================================================================
 |   Assignment:  ASSIGNMENT NUMBER AND TITLE
 |
 |       Author:  STUDENT'S NAME HERE
 |     Language:  NAME OF LANGUAGE IN WHICH THE PROGRAM IS WRITTEN AND THE
 |                      NAME OF THE COMPILER USED TO COMPILE IT WHEN IT
 |                      WAS TESTED
 |   To Compile:  EXPLAIN HOW TO COMPILE THIS PROGRAM
 |
 |        Class:  NAME AND TITLE OF THE CLASS FOR WHICH THIS PROGRAM WAS
 |                      WRITTEN
 |   Instructor:  NAME OF YOUR COURSE'S INSTRUCTOR
 |     Due Date:  DATE AND TIME THAT THIS PROGRAM IS/WAS DUE TO BE SUBMITTED
 |
 +-----------------------------------------------------------------------------
 |
 |  Description:  DESCRIBE THE PROBLEM THAT THIS PROGRAM WAS WRITTEN TO
 |      SOLVE.
 |
 |        Input:  DESCRIBE THE INPUT THAT THE PROGRAM REQUIRES.
 |
 |       Output:  DESCRIBE THE OUTPUT THAT THE PROGRAM PRODUCES.
 |
 |    Algorithm:  OUTLINE THE APPROACH USED BY THE PROGRAM TO SOLVE THE
 |      PROBLEM.
 |
 |   Required Features Not Included:  DESCRIBE HERE ANY REQUIREMENTS OF
 |      THE ASSIGNMENT THAT THE PROGRAM DOES NOT ATTEMPT TO SOLVE.
 |
 |   Known Bugs:  IF THE PROGRAM DOES NOT FUNCTION CORRECTLY IN SOME
 |      SITUATIONS, DESCRIBE THE SITUATIONS AND PROBLEMS HERE.
 |
 *===========================================================================*/
Note that I've included some brief comments with each section, to let you know what you need to add. Because deleting all of those comments is a pain, I've got a comment-free version on AIX1 called ext.c that you can import instead. It's in the same directory as external.c.

You should be able to fill out all of this template except for the last two sections before you write the program. Here's what it might look like for our example assignment:

/*=============================================================================
 |   Assignment:  Program #0 -- Calories Due to Fat
 |
 |       Author:  Reg LeCrisp
 |     Language:  AIX C (the xlc compiler)
 |   To Compile:  At the AIX prompt, type:  xlc prog0.c
 |
 |        Class:  COMSC 1613 (Programming I)
 |   Instructor:  Dr. McCann
 |     Due Date:  Smarch 36th, 2028
 |
 +-----------------------------------------------------------------------------
 |
 |  Description:  This program determines what percentage of the calories
 |		in a food product are due to the food's fat content.  
 |
 |		The user is asked to input the number of grams of fat in one
 |		serving of the food, and the total calories in one serving.
 |		A gram of fat contains 9 calories, so the percentage of
 |		the food's calories that are due to fat is found by using
 |		this formula:
 |
 |				# of grams of fat  *  9
 |		percentage = ----------------------------- * 100
 |				calories in a serving
 |
 |        Input:  The user is required to enter the grams of fat in one
 |		serving of the food in question, and the total number of
 |		calories in that one serving.  It is expected that the
 |		user will type these two pieces of information at his or 
 |		her keyboard.
 |
 |       Output:  The program will display an explanation of its purpose,
 |		will prompt the user for the input, and will display the 
 |		percentage of the food's calories that are due to fat.  All
 |		output is displayed on the user's screen.
 |
 |    Algorithm:  The program's steps are as follows:
 |
 |			1.  The program displays its purpose
 |			2.  The user is prompted to enter the grams of fat
 |				and calories per serving
 |			3.  The percentage of calories due to fat is
 |				computed
 |			4.  The percentage is displayed to the user, along
 |				with the given input information.
 |
 |   Required Features Not Included:  
 |
 |   Known Bugs:  
 |
 *===========================================================================*/
Please pay attention to the level of detail; the explanations are all quite detailed. Many students try to include a bare minimum of information in their documentation; that's not good at all. The documentation should help the reader understand the program, not raise more questions than it answers. This example shows an adequate amount of information. (Can you think of some additional information that you'd like to see included?) Some students think that the reader can just refer to the assignment handout to get the information. Remember two things: First, the documentation is part of the program code; the handout isn't. Second, when you get a job as a programmer, your boss is not going to go around giving you assignment handouts. You might as well get in the habit of writing good, informative documentation now.

Naturally, the programmer will need to revisit the documentation after the program is complete and verify that all of the information is correct (and fill in the final two sections). But, if you do a good job of planning the details of the program in advance, you won't have to change much, if anything.

Step #4: Write the Program a Piece at a Time
Students like to try to write their programs all at once. You can get away with this on small programs, but as the amount of code increases, you're asking for headaches if you don't write a little at a time, and test each section as you write it.

For example, in our program we know that we need to read two pieces of data and output three, with some calculations in-between. Forget about the calculations for the moment, and just try to deal with the input and output. Your program might look like this: (I left off the external documentation in the interest of saving space.)

#include <stdio.h>

int main (void)
{
        int     grams_of_fat,   /* number of grams of fat in one serving */
                total_calories; /* number of calories in one serving */
        float   percent;        /* percentage of total calories from fat */

        scanf("%d",&grams_of_fat);
        scanf("%d",&total_calories);

        printf("%d %d %f\n",grams_of_fat, total_calories, percent);

        return 0;
}
Yes, this is very spartan. Don't worry, we'll fill in the details in due time. The point is, we can compile and run this program as-is, and be convinced that we are able to successfully read and write the data. It doesn't make much sense to write the percentage calculations until we know that the calculations will have the correct values to work with. By including a simple output statement, we can see that the values are being read correctly.

If you were to compile and run this program, here's what you'd see:

$ xlc prog0.c
$ a.out
3
76
3 76 0.000000
Obviously, we'll need to make these input and output actions a lot more "user friendly" before we finish.

Next, we can add the calculations:

#include <stdio.h>

#define CALORIES_PER_GRAM 9.0   /* there are 9 calories per gram of fat */

int main (void)
{
        int     grams_of_fat,   /* number of grams of fat in one serving */
                total_calories; /* number of calories in one serving */
        float   fat_fraction,   /* fraction of calories due to fat */
                percent;        /* percentage of total calories from fat */

        scanf("%d",&grams_of_fat);
        scanf("%d",&total_calories);

        fat_fraction = (grams_of_fat * CALORIES_PER_GRAM) / total_calories;
        percent = fat_fraction * 100;

        printf("%d %d %f\n",grams_of_fat, total_calories, percent);

        return 0;
}
Don't forget to test the calculations to ensure that they are working correctly. Remember the example calculation given in the assignment handout? It makes for a good test case:

$ xlc prog0.c
$ a.out
3
170
3 170 15.882354
Eventually, you'll have added all of the functionality that is required of your program, will have tested its operation thoroughly, and will have added any remaining documentation. At this point, you may choose to add some "extras" that enhance the program but were not required by the assignment. (I never have problems when you do more than the assignment requires!) Here's what the completed program might look like:

/*=============================================================================
 |   Assignment:  Program #0 -- Calories Due to Fat
 |
 |       Author:  Reg LeCrisp
 |     Language:  AIX C (the xlc compiler)
 |   To Compile:  At the AIX prompt, type:  xlc prog0.c
 |
 |        Class:  COMSC 1613 (Programming I)
 |   Instructor:  Dr. McCann
 |     Due Date:  Smarch 36th, 2028
 |
 +-----------------------------------------------------------------------------
 |
 |  Description:  This program determines what percentage of the calories
 |              in a food product are due to the food's fat content.
 |
 |              The user is asked to input the number of grams of fat in one
 |              serving of the food, and the total calories in one serving.
 |              A gram of fat contains 9 calories, so the percentage of
 |              the food's calories that are due to fat is found by using
 |              this formula:
 |
 |                              # of grams of fat  *  9
 |              percentage = ----------------------------- * 100
 |                              calories in a serving
 |
 |        Input:  The user is required to enter the grams of fat in one
 |              serving of the food in question, and the total number of
 |              calories in that one serving.  It is expected that the
 |              user will type these two pieces of information at his or
 |              her keyboard.
 |
 |       Output:  The program will display an explanation of its purpose,
 |              will prompt the user for the input, and will display the
 |              percentage of the food's calories that are due to fat.  All
 |              output is displayed on the user's screen.
 |
 |    Algorithm:  The program's steps are as follows:
 |
 |                      1.  The program displays its purpose
 |                      2.  The user is prompted to enter the grams of fat
 |                              and calories per serving
 |                      3.  The percentage of calories due to fat is
 |                              computed
 |                      4.  The percentage is displayed to the user, along
 |                              with the given input information.
 |
 |   Required Features Not Included:  All required features are included.
 |
 |   Known Bugs:  None; the program operates correctly.
 |
 *===========================================================================*/

#include <stdio.h>

#define CALORIES_PER_GRAM 9.0   /* there are 9 calories per gram of fat */

int main (void)
{
        int     grams_of_fat,   /* number of grams of fat in one serving */
                total_calories; /* number of calories in one serving */
        float   fat_fraction,   /* fraction of calories due to fat */
                percent;        /* percentage of total calories from fat */

        printf("This program will tell you how much of the calories in\n");
        printf("a food are from the food's fat content.\n\n");

        printf("How many grams of fat are in one serving?  ");
        scanf("%d",&grams_of_fat);
        printf("How many total calories are in one serving?  ");
        scanf("%d",&total_calories);

        fat_fraction = (grams_of_fat * CALORIES_PER_GRAM) / total_calories;
        percent = fat_fraction * 100;

        if (grams_of_fat == 1) {
                printf("\nA food with 1 gram of fat ");
        } else {
                printf("\nA food with %d grams of fat ",grams_of_fat);
        }

        if (total_calories == 1) {
                printf("and 1 calorie per serving\n");
        } else {
                printf("and %d calories per serving\n",total_calories);
        }

        printf("has %.2f%% of those calories from fat.\n\n",percent);

        return 0;
}
In this program, I decided that it would be nice if the output wording matched the values the user entered. The IF-ELSE statements will make the words match the quantity; for example, "1 gram" instead of "1 grams". This step wasn't required, but it does make for a more polished final program.

And here's what the user will see when s/he runs it:

$ xlc prog0.c
$ a.out
This program will tell you how much of the calories in
a food are from the food's fat content.

How many grams of fat are in one serving?  3
How many total calories are in one serving?  170

A food with 3 grams of fat and 170 calories per serving
has 15.88% of those calories from fat.


Step #5: Prepare Your "Hand In" Printout
Once you have convinced yourself that your program does what it should and meets all of the requirements, you need to create a printout of the program and of the output to turn in to me on the due date.

In order to print out program's output, you have to save it to a file somehow. The recommended way to do this is to rely on UNIX's script utility. When script is active, anything that appears on the screen is captured to a file. So, the idea is to start script, run the program as many times as is necessary, and then stop script. For this program, here's how the whole process would work:

$ script
Script command is started. The file is typescript.
$ xlc prog0.c
$ a.out
This program will tell you how much of the calories in
a food are from the food's fat content.

How many grams of fat are in one serving?  1
How many total calories are in one serving?  66

A food with 1 gram of fat and 66 calories per serving
has 13.64% of those calories from fat.

$ a.out
This program will tell you how much of the calories in
a food are from the food's fat content.

How many grams of fat are in one serving?  21
How many total calories are in one serving?  480

A food with 21 grams of fat and 480 calories per serving
has 39.38% of those calories from fat.

$ exit
exit
Script command is complete. The file is typescript.
Clearly, the command to stop script is the exit command. The text that appeared on the screen in-between those two commands is saved in your account in a file named typescript. As you saw, the program was run twice, once for each set of data provided in the assignment handout.

To print your files on the printer in the main terminal room (MCS 126), use the lpr command (yes, the first letter is a lower-case "L"), like this:

$ lpr prog0.c typescript
By listing the two files together, as shown, UNIX will print them consecutively on the printer (that is, no one else's printout will be between them).

Please leave the printout as-is, with the pages connected in a fan-fold manner and the header page on the top. To facilitate finding your program in the pile when I return them to the class, please write your name in the upper right-hand corner of the printout.

Step #6: Double-Check Your Work
I can't begin to relate to you how frustrating it is for me to have to take off points, or even require that a student resubmit a program, just because the student didn't take the time to double-check that their program is really complete. When you think that you are done, try running through this little check-list and see if you really are done:
  1. Have I reread the assignment handout to make sure I found all of the requirements?
  2. Does my program meet all of the requirements?
  3. Is my documentation complete? (Did I finish the external documentation? Are my variable names meaningful? Are the variable declarations documented? Did I use white space effectively? If I included any user-defined functions, did I include an internal block comment for each?)
  4. Did I run my program on all of the provided test data?
  5. Did I check the results by hand to ensure that the program's logic is correct?
  6. Have I printed out everything that I need to turn in?
If everything looks good, then you're ready to hand it in. Within the first 5 minutes of class on the due date, place your printout (and disk, if you're submitting a PC version instead of an AIX1 version) on the front desk in the classroom.

Step #7: Reclaim the Now-Graded Program
I try very hard to get your programs graded and back to you at the next class meeting after the due date. (Because you have a limited amount of time in which to resubmit incomplete programs, I want you to have access to my comments as soon as possible.) Some students don't seem to care whether or not they reclaim their programs; that's their business, but I really recommend that you get your programs back from me, if only to verify that you don't have to fix anything.

Step #8: Complete and Resubmit the Program (Only If Necessary!)
If I want you to fix your program and resubmit it, you'll know because (a) your score is 50 or less, and (b) I wrote "Complete and Resubmit" on it. I'll ask you to resubmit a program that has significant errors and/or omissions, or a large number of little problems. Most of the time, students know all to well that their program isn't working, and don't need me to tell them. But, I can't assume.

If you are working on a resubmit, please be aware that you can still stop by my office for help on resubmits. When you fix everything and are ready to resubmit the program, create a new printout of the program and its output, and turn it in along with the original graded program. I want to see them both so that I can see what changes you made. If you don't turn them both in, I won't grade the resubmission!


Want to learn more about good programming style? Please visit my Programming Style Documents page for pointers to additional documents about programming style.

Do you have a comment on this page? I'd like to hear it; you can email me at mccannl@acm.org.