Comments allow us to write in natural language to clarify the intent of the program. You should comment programs internally with clear, coherent statements in concise English, using good grammar, punctuation, and spelling. You should try writing the comments (or at least the design) first, then write the program code from that. Use a spellchecker on the program or at least the comments.
Each variable and named constant should have a comment describing its purpose. In the declarations, provide a short description of the logical role played by each. Organize this section as a "variable dictionary". Declare each variable on a separate line. This allows for easy insertion of a descriptive comment next to each declaration. Don't just say that a variable is "a counter"; say what it is counting. Don't just say that a variable is "an integer"; say that it is "the first number input by the user" or "a roll of the die" or "the sum of the ages of the students". For example, you might have:
const int MAXPKG = 25; // maximum weight allowed for a package
float Weight; // The package's weight in kilograms
int nPackages; // number of packages loaded on van
int pkgCount; // counter for packages processed
Name your variables and constants carefully. Names are the heart of programming. In the past people believed knowing someone's true name gave them magical power over that person. If you can think up the true name for something, you give yourself and the people coming after power over the code. Don't laugh!
The most important consideration in chosing a name for a data item or function in a program is that the name convey as much information as possible about what the data item is or what the function does. If you find all your names could be Thing and DoIt then you should probably rethink your design. If you have a flag named Error that is TRUE if there ARE NO errors, you are setting yourself up for a bug.
Suffixes are sometimes useful:
For example: RetryMax to mean the maximum number of retries, RetryCnt to mean the current retry count.
Prefixes are sometimes useful:
if (IsHitRetryLimit()) ...
Identifiers for types, named constants, and variables should be nouns. Usually every void function performs an action, so the name should make clear what it does: CheckForErrors() instead of Error(), DumpDataToFile() instead of DataFile(). Because of the way that value-returning functions are invoked, their names should be nouns or occasionally adjectives. Here are some examples:
| Variables | address, price, radius, monthNumber |
| Named Constants | PI, TAX_RATE, MAX_LENGTH, ARRAY_SIZE |
| Data Types | NameType, CarMake, RoomList, Hours |
| Void functions | GetData, ClearTable, PrintBarChart |
| Value-returning functions | CubeRoot, Greatest, Color, AreaOf, IsEmpty |
Use capitalization properly. Most variable names should be lower case or mixed case, either "power" or "interestRate". Underscores can make a variable name easier to read, too, as in "money_borrowed". Named constants are usually written in ALL UPPER CASE. Remember that C++ is case sensitive; the case of an identifier name makes a difference. Remember that reserved words like main must be lower case.
Formatting Source Code
Formatting refers to the way statements are placed in a program -- indentation, blank lines, etc. Good formatting can make a program far easier to understand.
C++ allows you to break a long statement and continue on the next line. You cannot split a line in the middle of an identifer or a literal constant. Anywhere you can put a space in a statement, you can go to the next line. You should choose a point that is logical and readable. Try to take advantage of any patterns or repeating expressions. For example:
meanOfMax = (max(value11, value12, value13) +
max (value21, value22, value23) +
max (value31, value32, value33)) / 3.0;
cout << "This is a very long message "
<< "indeed , isn't it?";
White space is essential for clarity. This includes spaces around identifiers,
operators,
at the beginning and end of comments, as well as blank lines, especially to
separate blocks and different sections of blocks.
x = y + 3 * z - 5 * y;is easier to read than
x=y+3*z-5*y;
Comments at the closing braces of blocks are useful, especially if the block is rather long. Example:
while (ct < 10)
{
code
code
code
} // end of while controlled by ct
Indentation
The purpose of indenting statements in a program is to provide visual cues to the reader and to make the program easier to debug. When a program is properly indented, the way the statements are grouped is immediately obvious. Compare the following two program fragments. In the first piece of code, it is VERY difficult to see that the two cout statements are INSIDE the loop.
while (count <= 10)
{cin >> num;
if (num >= 0)
{count++;
num = 1;}
cout << num << endl;
cout << count << endl;}
compared to
while (count <= 10)
{
cin >> num;
if (num >= 0)
{
count ++;
num = 1;
}
cout << num << endl;
cout << count << endl;
}
Some people prefer to indent by 3, 4, 5 or even more spaces. The important thing is to choose a value and be consistent. Most editors will have a standard indentation amount. Indentation makes it obvious when braces are not balanced.
Statements should be indented when they are subordinate, that is, when they are part of another structure or statement. The body of each function should be indented. For another example, the If-Then-Else contains two parts, the then-clause and the else-clause. The statements within both clauses are indented; this makes the if and matching else stand out.
if (age > 65)
{
Eligible = true;
SSctr ++;
}
else
Eligible = false;
Nested if-then-elses can be indented as other if statements, but it tends to push them across the page. A better format is:
if (month == "January") monthIndex = 1; else if (month == "February") monthIndex = 2; else if (month == "March") monthIndex = 3; else monthIndex = 0;
Loop bodies should be indented. Examples:
while (count <= 10)
{
cin >> value;
sum = sum + value;
count ++;
}
for (count = 1; count <= numS; count ++)
cout << "*";
for (count = 10; count > 0; count --)
{
cin >> x;
cout << x;
}
Bad example:
This shows how many people who are beginning programmers
indent:
cout << "Enter num"; cin >> num; if (num > 0) cout << "positive"; else cout << "non-positive"; cout << "All Done " << endl;
This would lead you to believe that the if statement was dependent on the input statement in some way. That is definitely not the case. They are both statements in a sequence structure, and should be indented at the same level.
Be careful! Indentation is useful for humans but the compiler does not consider it significant. If you indent the code as given below, there is still only ONE line in the body of the while, not TWO (and yes, it is an infinite loop!).
while (ct < 5) cout << ct; ct = ct + 1;
Blank lines placed before and after each control structure makes them stand out. Too many levels of nesting can make a program difficult to understand.
Documenting Source Code
There is such a thing as too many comments. They can actually obscure the code itself. And if they don't agree with what the actual code is doing, they can be a source of errors! A comment is NOT necessary on every single line of source. Each loop should have a comment, as well as each if statement. An assignment statement needs a comment if it is important or if the right hand side is particularly complicated. Other statements need comments if they are not self-documenting. cout << "hello"; does not need a comment like // output hello.
Pre-conditions and Post-conditions
Every function should have documentation, at its prototype.
You should be able to state the purpose of the function in a sentence
or two. This sentence should be coherent and grammatically
correct. It should involve all of the function's parameters.
"The function displays a square on the screen that is size
rows high and width characters wide."
Each parameter should be documented. Any parameter that is passed by reference should be especially noted. Why are you changing it? Is it returning a value? If it is being passed as reference for efficiency's sake, say that.
Local variables need documentation just like other variables. The return type of the function, if not void, should be documented. Don't just say what type is being returned; say what the returned value means. "The function returns the average of the 4 parameters" "The function returns the largest number input" "The function returns true if the data was in the correct format, false otherwise".