Everyone develops a unique programming style over time, much like your “voice” in writing. However, it is important to be consistent and readable. The following are some guidelines that will help ensure your code makes sense when you look at it a month from now, or a year from now… and also to ensure you get credit for the “style and documentation” portion of your assignment grades.
Each instructor (and work place) will have their own preferences and opinions on style, so if a different instructor asks for something different in their course, do that! My preferred style is based on the Google Style Guide , with some small changes.
Most important: be consistent!
Formatting
Which of the following is easier to read?
int x=0;while(x<10){int y=(x<5)?-1:1;cout<<y<<endl;x++;}
int x = 0;
while (x < 10) {
int y = 1;
if (x < 5) {
y = -1;
}
cout << y << endl;
x++;
}
Whitespace is used to make code more readable. Unlike Python, it has no meaning to the compiler. The following are some whitespace guidelines:
- Use 4 spaces for indentation (this is the default in Emacs).
- Indent all blocks (e.g. in a function,
if
statement,for
loop, etc.). - Keep each statement on its own line.
- Prefer space around operators (e.g.
x = 0
instead ofx=0
). - Use empty lines to separate logically related blocks of code (like paragraphs in writing).
- Stick to a maximum of about 80 characters per line.
Braces indicate blocks and are necessary for the compiler, but stylistically both of the following are acceptable - just be consistent within a project:
int main() {
cout << "Hello, world!\n";
}
int main()
{
cout << "Hello, world!\n";
}
Naming convention
Variables and functions must be descriptive (aka “self-documenting”). This usually means longer names, but that’s okay - for example num_students
is better than n
.
Variables and functions can either be camelCase or snake_case - again, just be consistent.
Variables and functions should start with a lowercase letter, while struct
s and class
es should start with an uppercase letter.
Note: often my class examples have poor naming convention, like
x
anda
. This is done for several reasons, none of which should be applicable for your own projects:
- Saving space on slides
- Illustrating an abstract concept, so the variables are actually meaningless
- Deliberately using names that hide meaning so you have to trace to know what it’s doing
Variables
Declare variables as close to their first use as possible. Alternatively, declare all variables at the top of a function, but be consistent.
Prefer to declare and initialize variables in one statement (sometimes this is unavoidable, e.g. when reading a value with cin
).
Use named constants to avoid “magic numbers” (e.g. const int NUM_STUDENTS = 10;
).
Avoid global variables, except for constants.
Declare variables in the smallest scope necessary. For example, if you only need a variable inside a loop, declare it inside the loop:
Good
for (int i = 0; i < 10; i++) {
cout << i << endl;
}
Ungood
int i;
for (i = 0; i < 10; i++) {
cout << i << endl;
}
Documentation
C++ does not have docstrings like Python, but it is still a good idea to add a descriptive comment for each function, and for any complex or non-obvious code.
Short comments can go on the same line as a short statement, but stick to the general rule of “no more than 80 characters per line” for readability. This is most common for variable declarations that might need a bit more context, for example:
double total = 0; // The sum of all the numbers
In general, use comments to explain why you are doing something, not what you are doing.
Good
// Check for game end condition
int sum = 0;
bool win = false;
for (int i = 0; i < ROW_LENGTH; i++) {
sum += board[i];
}
if (sum == WINNING_SUM) {
win = true;
}
Ungood
// Sum the elements in the array
int sum = 0;
bool win = false;
for (int i = 0; i < ROW_LENGTH; i++) {
sum += board[i];
}
if (sum == WINNING_SUM) {
win = true;
}
The code should be largely self-documenting. How do you know if a comment is needed? If you go away from the code for a day or two and come back and it takes a few minutes to remember what you were doing, you should probably add a comment.
Functions in C++ should have a short comment describing what they do. My preference is to put this by the declaration so that people reading header files can see it, but you can also put it by the definition (just be consistent!).
// Prompts the given player for a move and updates the board
void take_move(int board[], int player);
In your function definition, it’s appropriate to put a short comment describing any specific implementation details or references that you used. Feel free to describe any important or potentially confusing parameters, but don’t just repeat the information in the declaration (this leads to inconsistent comments when the declaration changes).