Based on a handout by Marty Stepp
These are some of the general style qualities that we expect your programs to have in order to receive full credit. This is not an exhaustive list; please also refer to each assignment spec for other style practices to follow. Certainly it is possible to write good code that violates these guidelines, and you may feel free to contact us if you are unclear about or disagree with some of them. But we do expect you to follow these rules (unless there is an error in this document). In most professional work environments you are expected to follow that company's style standards. Learning to carefully obey a style guide, and writing code with a group of other developers where the style is consistent among them, are valuable job skills.
This document is a work in progress.
Any guidelines written here are in addition to what is mentioned in the given assignment's spec, so you are responsible for reading that spec and following its instructions.
If there is ever a conflict between this style guide and an assignment spec, follow the assignment spec.
Last updated Wed 2014/10/29
Indenting: Increase your indentation by one increment on each brace {
, and decrease it once on each closing brace }
.
Place a line break after every {
.
Do not place more than one statement on the same line.
// bad
int x = 3, y = 7; double z = 4.25; x++;
if (a == b) { foo(); }
// good
int x = 3;
int y = 7;
double z = 4.25;
x++;
if (a == b) {
foo();
}
Long lines: When any line is longer than 100 characters, break it into two lines by pressing Enter after an operator and resuming on the next line. Indent the trailing second part of the line by two increments (e.g. two tabs). For example:
int result = reallyLongFunctionOne() + reallyLongFunctionTwo() + reallyLongFunctionThree() + reallyLongFunctionFour(); int result2 = reallyLongFunction(parameterOne, parameterTwo, parameterThree, parameterFour, parameterFive, parameterSix);
Expressions: Place a space between operators and their operands.
int x = (a + b) * c / d + foo();
Blank lines: Place a blank line between functions and between groups of statements.
void foo() {
...
}
// this blank line here
void bar() {
...
}
Names: Give variables descriptive names, such as firstName
or homeworkScore
.
Avoid one-letter names like x
or c
, except for loop counter variables such as i
.
Capitalization: Name variables and functions with camel-casing likeThis
, name classes with Pascal casing LikeThis
, and name constants in uppercase LIKE_THIS
.
Scope: Declare variables in the narrowest possible scope.
For example, if a variable is used only inside a specific if
statement, declare it inside that if
statement rather than at the top of the function or at the top of the file.
Types: Choose appropriate data types for your variables.
If a given variable can store only integers, give it type int
rather than double
.
Favor C++ strings over C strings: C++ confusingly features two kinds of strings: the string
class from C++, and the older char*
(array of characters) from C. As much as possible, you should use the C++ string
type over the older C string type.
// bad: C-style string
char* str = "Hello there";
// good: C++-style string
string str = "Hello there";
Constants: If a particular constant value is used frequently in your code, declare it as a const
constant, and always refer to the constant in the rest of your code rather than referring to the corresponding value.
const int VOTING_AGE = 18;
Avoid global variables: Never declare a modifiable global variable. The only global named values in your code should be const
constants. Instead of making a value global, pass it as a parameter and/or return it as needed.
// bad int count; // global variable; bad! void func1() { count = 42; } void func2() { count++; } int main() { func1(); func2(); }
// better
int func1() {
return 42;
}
void func2(int& count) {
count++;
}
int main() {
int count = func1();
func2(count);
}
favor C++ idioms over C idioms: Since C++ is based on C, there is often a "C++ way" to do a given task and also a "C way" to do a given task. For example, when printing output to the system console, the "C++ way" is to use the global output stream cout
, while the "C way" is to use global functions like printf
. You should always favor the "C++ way" when possible.
// bad
printf("Hello, world!\n");
// good
cout << "Hello, world!" << endl;
for vs while: Use a for
loop when the number of repetitions is known (definite); use a while
loop when the number of repetitions is unknown (indefinite).
// repeat exactly 'size' times for (int i = 0; i < size; i++) { ... } // repeat until there are no more lines string str; while (input >> str) { ... }
break and continue: In general, you should avoid using the break
or continue
statements in loops unless absolutely necessary.
exit()
: C++ contains an exit
function that immediately exits your entire program. You should never call this function in our assignments. Your program should always exit naturally by reaching the end of your main
function and returning.
always include {}
on control statements: When using control statements like if/else
, for
, while
, etc., always include {}
and proper line breaks, even if the body of the control statement is only a single line.
// bad
if (size == 0) return;
else
for (int i = 0; i < 10; i++) cout << "ok" << endl;
// good
if (size == 0) {
return;
} else {
for (int i = 0; i < 10; i++) {
cout << "ok" << endl;
}
}
if/else patterns: When using if/else
statements, properly choose between various if
and else
patterns depending on whether the conditions are related to each other. Avoid redundant or unnecessary if
tests.
// bad
if (grade >= 90) {
cout << "You got an A!";
}
if (grade >= 80 && grade < 90) {
cout << "You got a B!";
}
if (grade >= 70 && grade < 80) {
cout << "You got a C!";
}
...
// good
if (grade >= 90) {
cout << "You got an A!";
} else if (grade >= 80) {
cout << "You got a B!";
} else if (grade >= 70) {
cout << "You got a C!";
}
...
Boolean zen 1: If you have an if/else
statement that returns a bool
value based on a test, just directly return the test's result instead.
// bad
if (score1 == score2) {
return true;
} else {
return false;
}
// good
return score1 == score2;
Boolean zen 2: Don't ever test whether a bool
value is ==
or !=
to true
or false
.
// bad
if (x == true) {
...
} else if (x != true) {
...
}
// good
if (x) {
...
} else {
...
}
favor &&
, ||
, and !
over and
, or
, and not
: For various reasons mostly related to international compatibility, C++ has two ways of representing the logical operators AND, OR, and NOT. There's the "traditional" way of encoding these operators, which use the symbols &&
, ||
, and !
to represent AND, OR, and NOT, respectively, and these are the preferred ways of writing these operators in C++. There's no deep, fundamantal reason why these are the preferred operators; it's just the historical convention. While you can use and
, or
, and not
to represent AND, OR, and NOT in code, this would be considered fairly unusual in C++ and is therefore not considered to be good style. If you're coming to C++ from Python, keep this in mind.
// bad
if ((x and y) or not z) {
...
}
// good
if ((x && y) || !z) {
...
}