This style guide is mandatory for all submitted work for grading
(homework, projects, labs, exams). The purpose of the guide is not to
restrict your programming but rather to establish a consistent style format for
your programs. This will help you debug and maintain your programs, and help
others (including your instructor) to understand them. As your programs grow in
length and complexity, it is critical to use a consistent style. In the long run
this will help you since one focus of this course is to build a foundation for
later courses. Points will be deducted from submitted work that does not
conform to this style guide.
Visual Layout
Bad Formatting
#include <iostream>
using namespace std
;int main(){int x,y
=1;cin>>x;while(x>0
){y=2*y;x--;}cout<<
y<<endl;return 0;}
|
|
"Whitespace" refers to newlines, space characters and tabs. In source code we
do not generally use tabs. In fact, emacs replaces tab characters with an
appropriate number of space characters.
In many circumstances whitespace is not required in order for compilers to
correctly compile source code, even though the result is unreadable to us.
For example, the left code is a perfectly valid program but pretty hard to
read.
|
Good Formatting
#include <iostream>
using namespace std;
int main()
{
int x, y = 1;
cin >> x;
while(x > 0)
{
y = 2*y;
x--;
}
cout << y <<endl;
return 0;
}
|
|
There are three major ways we use whitespace to format code for maximum clarity:
- Whitespace separating elements of code:
Consistent use of whitespace
transcends blank lines and indentation, it also looks at how
spaces are used to separate elements of a line of code. The style guide
recommends whitespace between operators and operands, except
where precedence is highlighted by leaving out spaces.
| Good |
y = 2*y + x/y + 5; |
if (y >= 2*y - 5 && x*y <= 24) |
| Bad |
y=2*y+x/y+5; |
if (y>=2* y-5&&x * y<=24) |
- Blank Lines:
In source code, use blank lines to separate
chunks of code that accomplish distinct tasks.
While to some extent this is taste and art, you should expect
distinct functions to be separated by blank lines, and a long
function body should usually be broken into chunks by blank
lines as well.
- Indentation:
Indentation highlights the block structure of programs, much
as it does in formatting outlines. Each level of block
nesting must be indented by a consistent number of spaces
(two in the emacs settings we provide you). New levels of
indenting are introduced by function bodies, for, while and
do-while bodies, the then and else blocks of an if
statement, and struct definitions.
|
Curly Braces, i.e. { }'s
Curly Braces, i.e. { }'s in C++ are used to create a "block" from one or more
statements. The delineate the bodies of functions, loops and switch statements,
struct definitions, and the then and else blocks of if statments. Generally,
one should either always put the opening curly brace on a new line (preferred
for this course) or always put it last on the previous line. Once again,
consistency is key. If the opening brace goes on a new line, the preference for
this course is to keep the previous line's indentation — i.e. do not
indent the curly brace. Generally, curly braces of either kind will occupy
their own line, except for rare occasions when an entire block is put on one
line. The exception is that comments may follow either opening or closing
braces.
| Good | Good | Bad | Bad |
while (x < 3)
{
cout << x << ",";
x++;
}
cout << endl;
|
while (x < 3) {
cout << x << ",";
x++;
}
cout << endl;
|
while (x < 3)
{ cout << x << ",";
x++; }
cout << endl;
|
while (x < 3)
{ cout << x << ",";
x++;
} cout << endl;
|
Comments
Comments should be indented consistently with the block of code they
describe. Comments can be divided into two general categories,
strategic and tactical.
- Strategic comments are used to give the reader a
general overview of what is going on. These comments appear at the
beginning of files, before important functions, and above
important blocks of code. Strategic comments tend to be written in
sentences with an emphasis on explaining the big picture of what
the block of code is designed to do.
- Tactical comments are designed to explain tricky areas
of code, what parameters do, and hints about the control flow of
the program. These comments should be intermixed in the code when
needed. They should be shorter than strategic comments, in bullet
format, and may be in inline format. One should, for instance,
place a tactical comment next to the statement that assigns a
fixed, non-obvious value to a variable.
The following example shows good commenting. Note the tactical
comment about why "9.0" is used instead of "9".
|
/***************************************************
Fahrenheit to Celsius Conversion
***************************************************/
#include <iostream>
using namespace std;
int main()
{
// Read temperature in Fahrenheit
double Tf;
cout << "Enter temperature in Fahrenheit: ";
cin >> Tf;
// Compute temperature in Celsius
double Tc;
Tc = (Tf - 32)*(5/9.0); // .0 forces division as double
// Write temperature in Celsius
cout << "That is " << Tc << " degrees Celsius."
<< endl;
return 0;
}
|
Naming
-
Variables should have meaningful names.
For example,
consider a program that uses a variable to track the yards per carry
of a football game. Such a variable should be called
yardsPerCarry
vice ypc for program readability. This must be balanced against
using names which are too long, which can obscure the code. (Fifteen
or so characters approaches the "too long" limit.)
It should be mentioned that this is most important for variables
that have large scope — i.e. they are visible and need to be
used either from different files or from widely separated lines in
the same file. The code example above seems to violate this rule,
but variables Tf and Tc only a appear, and
are only in scope, within less than a dozen lines of code, and in
the context of those few lines they are descriptive enough. Also,
because this is an example embedded in a document, compactness of
the code is very important.
-
Single letter variables or constants should not be used.
An exception to this rule is when it is common practice to identify something
with a single letter. An example of this is the coordinate system (x, y, and z).
A second exception occurs in the use of loop counter variables where it is
common practice to use variables like i and j as counters in for loops.
-
Function names and variable names should begin with a lower case
letter.
An identifier consisting of multiple names SHALL have each
name distinguished by making the first letter of each name part
(after the first)
upper case (e.g. yardsPerCarry) or by using underscores
(yards_per_carry).
The former method is strongly encouraged.
-
Constants should be named in all upper case letters.
Example:
const int PI = 3.14;
It's generally good to avoid lower case letter 'L', or the letter
'O' in names unless they are part of normal words. This is to avoid
confusion with the numbers 1 and 0. For example, is "cell" c- e -
1- ONE or c- e- 1-1?
-
Avoid names that differ only in case, look similar, or differ only
slightly.
For example, InputData, InData and DataInput will certainly be confusing if
used in the same program.
-
Names of functions should reflect what they do (printArray), or what they return (getAge).
-
Boolean variable names should sound like Yes/No things — "isEmpty" and "isFinished" are possible examples.
Miscellaneous but Important Stuff
- No line of code should wrap beyond the right margin. If a line of
code becomes too long, break it up into pieces.
Remember the compiler largely ignores extra whitespace in your programs
(but be careful with strings).
-
Always use the most appropriate operator or construct for the work
you want it to do. Good design and clarity take precedence over
optimization. Do not declare or use more variables than are
necessary.
-
Numerical constants ("magic numbers") must not be coded
directly. The only allowable exceptions are for 0, 1 or -1, and
those which are not likely to change; for example code determining
if a number is even can use the number 2 since it is not likely to
change. Numerical constants must have a comment explaining the
value if it is not evident from the name.
Practical tips for tackling programming problems
Here are a few practical tips that will improve your programming skills.
- The more independent a programmer is, the better. Of course, you need
to look at lecture notes, sample programs, and other materials to write
your program.
However, do this before writing the code, but try to avoid
looking at them if possible while writing your
code. In particular, if you are really new to programming, try to
write your code from scratch without doing any copy-and-paste, at
least for the first three weeks. I know it's impossible to do so; try with
your discretion.
There are some benefits to this approach:
- You will become more conscious which concepts (or less important
details) you miss. This way, you can identify your misunderstandings
and fix them with more ease.
- You will write a code faster. Access to something in your brain is
much faster than in any other storage. Memory
hierarchy matters.
- Your brain seems to do creative
synthesis. You may gain more fundamental perspectives on
programming if you put more in your brain. However, things outside your
brain always stay the same to you.
- The devil is in the details. Don't forget that is it you as a
programmer who are responsible for all the bits and pieces of your
program. Things may seem simple at a first look, but usually they will
take more time and effort to complete than expected.
As one more example, the online notes sometimes explain technical details.
In this case, reading one paragraph may take even 5 minutes or more to
work out all the details in your brain. Don't skip through the details.
The devil is in the details.
- Step back, and think again.
When you finish a task, take a brief moment and step back. Check if you
get both the big picture logic and the small details to implement the
logic. See if there are some inconsistencies and fix them if any.
- How valuable is a car that doesn't run? It's useless, and I
won't buy the car. Likewise, however many lines your source code may
have, if it doesn't work, it's useless, and I won't buy your program. Try
to make a good, working product. If your code doesn't work, you are
missing something; what is it?
Tips for managing your time
At the end of the 2nd week, you must know how long it take you to
finish the following on average:
- Reading one day's lecture notes.
- Finishing one assignment of homework.
- Finishing a lab.
Then, you need to allocate enough of your time in your schedule in order
to be successful in this course.
There are three projects in this course. As a rule of thumb, you will need
3-6x of lab time for finishing a project.