Typical Layout of a Program
◀ Layout of a Program▶ How to Program Efficiently Amazon
In this chapter we are going to discuss where things are in a program. Sometimes some things need to be at specific places in order for the program to compile successfully, but most of the time you can arrange the layout of a program any way you want.
It is important to adhere to a layout scheme because doing so removes confusion and speeds up debugging as you are fully aware where things go. Throughout my programming life, I have come to stick to the following layout in a typical program:
Comments about the author, what the program does, etc
Headers
Global variables and objects, initialized or not initialized
Function prototypes (may be omitted)
Function definitions (can also go after main)
main {
All conditions that need to be satisfied to continue*
Main body
comments where appropriate
variable and object declarations and initializations where appropriate
delegate work to functions
return 0;
}
*Sometimes the command line inputted by the user does not fulfill the requirements necessary for the program to run. In that case, print an error message (and a message telling the user how to use the program) and exit.
Let’s look at each component of the layout.
First, you include comments about the author and what the program does, how to run it, and so on. Then you include the necessary headers that provide functions your program needs. If you need to include a library that is less often used, it is advisable for you to also include a comment indicating what functions it provides will be used.
Next, you declare all the global variables. Sometimes you want to assign values to the global variables but other times you do it inside
main() or other functions. Also, if you want to declare an object of a particular class to be global, you can do it here.
Next you put function prototypes, but they are not necessary for the program to compile as long as you always call a function after you define it.
Next, put function definitions. You can put them before
main() or after
main(). I like to put them after
main() so that it’s easier for me to debug later.
What comes next is our favorite function -
main(). In the argument of
main(), you may want to include
(int argc, char **argv) to receive data from the command line.
Inside
main(), before you declare your variables, sometimes you want to check to see if the user has given correct information for the program to run. This happens a lot because the program may run different routes depending on the given parameters. The results of running a program, thus, depend on what the user inputs.
It is generally easier to receive all data from command line once and for all. After the program receives valid data, it can proceed to the main body which is where the business logic is.
In the main body I put comments where appropriate for clarity and readability of the program. I declare and initialize variables and objects where appropriate. You should always declare a variable and assign a value to it right before you need it to limit their scope and thus impact to the minimum.
If I declare a pointer which I don’t use at the moment, I always assign NULL to it. Most importantly I delegate the work to functions.
main() should be easy to read!
Here’s an example of an easy-to-read
main():
int main() {
get_input_from_user();
convert_input_to_canonical_form();
process_input();
compute_result();
process_result();
return_result_to_user();
}
Here is a sample program following the above layout:
/*
Michael Wen
7/1/2003
This program, given the number of sides, produces code for Matlab to display on the screen a regular polygon of specified number of sides.
*/
#include<iostream>
#include<math.h> /* for acos() */
#include<vector>
#include<fstream>
using namespace std;
const double PI = acos(-1.0); /* value of pi */
/* function prototypes are omitted */
void output_polygon_to_file(ofstream fout, char *file, double offset, vector<double> x, vector<double> y) {
fout.open(file);
fout<<"axis([0 "<<offset*2<<" 0 "<<offset*2<<"]);\n";
fout<<"x=[";
for(i=0;i<x.size();i++)
fout<<x[i]<<' ';
fout<<x[0]<<"];\n";
fout<<"y=[";
for(i=0;i<y.size();i++)
fout<<y[i]<<' ';
fout<<y[0]<<"];\n";
fout<<"line(x,y);\n";
fout.close();
}
int main(int argc, char** argv){
if(argc!=3){
cout<<"usage: exe <num> <file>\n";
cout<<"<num>: number of sides\n";
cout<<"<file>: output file's name\n";
exit(1);
}
int num, i;
double degree, transition;
num=atoi(argv[1]);
char *file=argv[2];
degree=transition=0;
transition=360.0/num;
double length=4.9;
double offset=length/2;
double unit=offset*0.81;
vector<double> x;
vector<double> y;
// generate all the points of the polygon
for(i=0;i<num;i++){
x.push_back(unit*cos(degree*PI/180)+offset);
y.push_back(unit*sin(degree*PI/180)+offset);
degree+=transition;
}
ofstream fout;
output_polygon_to_file(fout, file, offset, x, y)
return 0;
}
In this small program you see how
main() delegates the core work to a nonmember function
output_polygon_to_file().
Our sun can hold about one million Earths.
◀ Layout of a Program▶ How to Program Efficiently