As we discussed in class what is considered a good program is a larger issue than just that it works. In order to promote this in this class here are a set of guidelines that you should follow in your programs.
These guidelines are based on my experience and study. I am constantly thinking and reevaluating the recommendations that I give here. I also "practice what I preach" and make sure that all of my examples follow these guidelines. If you find an example where I violate any of these notes then please bring it to my attention.
A good programmer has a reason for everything that they do.
All files should have a set of comments at the top of the file:
// Adds two numbers- What the contents of the file are for // Project #1 Add Program- The assignment name and class if the file is part of a class program assignment. // CS 23021 // John H. Doe- Who wrote the program // 9/14/99 - the date the program was created or last modified
For some of the guidelines there is a choice of different personal styles that you could use.
You should pick a style for a program and use it consistently. Inconsistent use of a style makes the programmer appear to not care.
Variables should be declared as close as possible to where they are going to be used. If a variable can be, make it as local to the block that it is being used in. Note, that if a variable is used in multiple places of a block, then it should be declared at the beginning of the block rather than close to its first place of use.
Variables should also be given an initial value. The only exception would be the following:
int n; cin >> n;
Identifiers, things you get to name in a program such as variables, constants, etc., should be given clear names. If you are not able to come up with a good name for an identifier then you need to think some more of what the variable is for.
Comments in a program allow the programmer to clearly express the what and why the statements are there.
The program statements that are written are there for a reason. The reason should be expressed in the comments. For that reason comments should be written before the code that they describe.
If you can't think of what a comment should say then you don't understand enough of the code that you are trying to write.
Programmers that say that they didn't have time to write the comments are saying that they are not sure what the code is supposed to do. It is hard enough to program successfully even when we know what the code is supposed to do we let alone when we can't express it.
I suggest that you use the C++ style comments (//). Leave the C style comments (/* ... */) for special purposes.
Comments explaining what a particular statement is doing (unless it is relatively obscure or not obvious) are useless. You can assume that the reader is familiar with C++:
total++; // increment total bad comment
Rather your comments should explain the meaning of the statement:
total++; // another element is processed good comment
Start every block of your program that a does separate function
with a line of comments. Put an in-line comment on the side of
some statement that you feel deserves extra explanation. Commenting
every line of code is not only unnecessary but it actually
makes the program less readable since important comments and code
is drowned in the rest of the comments.
Put an inline comment for every variable declaration (except for obvious cases such as loop variables used right after the declaration) explaining what this variable is for.
Put (at least) a line of comments in front a function prototype. Put more extensive comments in front of a function definition, possibly explaining the purpose for the parameters and the function's return value:
// sorts an array a[] using quicksort method // returns the smallest element int qsort(int a[]){ ... }
In English we often put a blank line between paragraphs. A paragraph has a complete thought.
We can do the same thing with program statements. Use a blank line between paragraphs of code. For example, instead of:
// read in the valuesThese lines are hard to read. It is hard to see what the different parts of the code are.
cout << "Enter ...";
int n1, n2;
cin >> n1 >> n2;
// calculate
int total = n1 + n2;
// print out the results
cout << "Total is " << total << '\n';
Use instead:
// read in the valuesThese lines are much easier to read. The placement shows the different "paragraphs" of code.
cout << "Enter ...";
int n1, n2;
cin >> n1 >> n2;
// calculate
int total = n1 + n2;
// print out the results
cout << "Total is " << total << '\n';
People should be able to read your code. Separating into paragraphs makes it easier to understand and follow.
Note that we didn't separate each statement by a blank line. The part that reads in the values has all the statements in a paragraph that expresses the complete thought of reading in the values.
Programs should use named constants instead of literal constants for many values. So instead of:
int calc = 20 * 90;
We would have:
const int NUM_STUDENTS = 20; // number of students const int LOWEST_A = 90; // lowest score for A int calc = NUM_STUDENTS * LOWEST_A;
Use const rather than #define for these kinds of constants (ANSI C also).
Named constants are often put in all uppercase.
Constants are typically placed at the top of the file that they are being used in. If that file contains the main function then they are placed before the main function. If the file contains function or class declarations they are typically placed before those in the file.
Constants placed in include files (.h) can be used by anybody that includes the include file (hard to say). Constants placed in .cpp files are only used within that file.
Indenting statements should follow the flow of control of the program.
Sequential statements should line up:
int v; cin >> v; v *= 2; cout << v;
Special Note: the return statement is a sequential statement. It should line up just like any other statement.
Conditional statements should indent for the statements that they contain:
if (s < 0) cout << s; Indent then statement else cout << (s * 2);Indent else statement
If you use braces in the conditional statements place them as follows:
if (s < 0 ) { s++; indent then statements cout << s; } else { s--; indent else statements }
Loop statements should indent for the statements that they contain:
while (s > 0) {
cin >> s; Indent inside loop body
}
Nested conditional and loop statements should be properly indented:
while (s < 0) { cin >> s; Indent inside loop body if (s < 0 ) { s++; Indent inside then-statements cout << s; } }
If-else-if sequences of similar nature may be indented as follows:
if (i=1){ i+=1; then action of the first if indented cout << i; } else if (i=2){ i+=2; then action of the second if indented cout << i; } else if (i=3){ i+=3; then action of the last if indented cout << i; }
In C++ we can only declare an identifier (the name of a variable, constant, function, etc.) once. If the compiler "sees" the identifier being declared again it will generate an error message. This becomes a problem once we start to use include files.
If in compiling a file the compiler "sees" the same include file more than once we will get an error message.