In the English language, there are many different ways to convey a certain message or idea: some of these ways are acceptable, whereas others are not. Similarly, there are acceptable and unacceptable ways to express a program in code. These style requirements are intended to help establish good coding practice from the outset. Although there are more than one acceptable way to express code, most companies, will have a coding style guide which all programmers are to follow in order to make it much easier to understand and adapt code. This style code represents the standard for this class.
There are options in the style guide to suite the tastes of a variety of programmers. Whichever option is chosen, be consistent in the use. Do not flip back and forth between style opens. Once a style for a particular program is chosen, it must be consistently used through the entire program.
In the end, take time to review the code you write and make sure it looks good. You should be proud of your code and want to show it to others.
Most of the 7 style categories are made up of specific styles which are explained in detail under each category and are summarized as bullet points at the end of this style guide. Grading will be done independently for each style within a style category.
At the very top of each file, there must be a complement block with the following information:
Here is an example of a reasonable header
/*
Sandra Dean, Section 3, Sandra@hotmail.com
Purpose: Calculate how many pizzas of various sizes a user should buy Input:
Number of people eating
Amount of tip Output:
Number of large, medium, and small pizzas necessary Total area of pizza for everyone
Area of pizza per person
Total cost including tip
*/
At the end of the header comments for the main program file, include test cases or indicate where the test cases are located. Labs 8‐10 have multiple files. For files other than main you should also have header comments. However, in these cases the comments just need to briefly describe the purpose of the file.
This section is focused on how your code looks, not on its functionality. Although sloppy code may accomplish the same thing neat code does, it is much harder to read, debug, and maintain. Furthermore, sloppy code has a defect rate (i.e., a greater likelihood and density of bugs). The goal of format is to write code that is easy to work with since it likely that others will be having to use it (especially in industry).
Do
x = 25; y = x + 1; if (x == 5) { y = 14; }
And Don't
x = 25; y = x + 1; if (x == 5) { y = 14;}
There are widely‐adhered to rules regarding brace placement. Either K&R style or Stroustrup style style is acceptable. For K&R style, branches, loops, and classes, opening braces appear at the end of the item’s line; closing braces appear under the item’s start. Functions however have the opening brace on the next line at the same indentation level of the line. For Stroustrup style, it does not use the cuddled-else.
// K&R Style void who() { if (x == 0) { ... } else { ... } } // Stroustrup void who() { if (x == 0) { ... } else { ... } }
Sub‐statements are indented 3 or 4 spaces from their parent statements. Be consistent in whatever is chosen. One way to do this is to use the tab key in the system you use to write your code as most editors will convert the tabs to spaces Do
if (a < b) { x = 25; y = x + 1; }
And don't
if (a < b) { x = 25; y = x +1; } if (a < b) { x = 25; }
Operators are separated by one space (not less or more). Separate keywords with one space as well.
Do
x = y + 3; if (x > y) { ... }
And don't
x=y + 3; if(x>y){ ... }
Even if there is a single sub-statement, curly braces are required. Do
if (a < b) { x = 25; }
And don't
if (a < b) x = 25;
Many a weekend has been blown by ignoring this style rule as it leads to errors (often).
80 characters is the old rule for how many characters can print on a single line. More practically, code is more readable when lines are kept short (and all visible on the screen). One long line can usually be broken up into several smaller ones. If a line is just inherently long, use newlines with indentation to improve readability. Do
cout << "This is a string" << endl; cout << "This is a second string" << endl; cout << "This is a third string" << endl;
And don't
cout << "This is a string" << endl << "This is a second string" << endl << "This is a third string" << endl;
Group the code into common segments using newlines. For example, if a method consists of three distinct steps, then separate each step with a newline. Whitespace can be very effective in helping the code be readable.
Test cases strive to ensure correctness in the code. Simple situations should be covered, but more importantly, obscure and less common cases need to be considered. For example, when testing a video game, testers do not simply play the game through; instead, they do obscure things such as walk into walls and corners, jump up trees, and cross invisible boundaries. Their goal is to break the code : they want to find every possible error in the game, expose them, and then fix them. Tests should consider where your code could fail, and then test those areas.
Test cases should include the expected output, and where possible, assert that the program output matches the expected output. It is strongly encouraged, where possible, to write test cases first, with the expected output, before writing the program itself. Also, once the program is written, write additional test cases knowing how the program is written. In other words, use the understanding of the program to break the program with unexpected inputs.
Test cases should run automatically. A program should be able to compile or run in test mode. Test mode runs all tests automatically and reports the test results. Failing tests can then be debugged using the test input.
Variable and parameter names must be written in camelCase with the first letter being lowercase or delimiter-separated words that use lower case letters and underscores as delimiters. Which ever style is adopted, be consistent through all the code. Do
//Always use camelCase int numPeople;
or
// Always use underscore delimited int num_people;
And don't
int NumPeople;
or
int numpeople;
or
int numPeople; int num_cars;
Variable names should be descriptive and useful. For code with options, variable names such as “firstOption”, “first”, “seven”, or “optionA” are not useful; to make sense of these names other knowledge is required, which is not discernible from the name alone. Instead, give variables names meaning such as “averageClassSize” or “exitOption”. Furthermore, avoid using abbreviations and single‐letter variables; a good practice is to think, Would a random person understand what this variable name represents? Variable names are usually at least two words, except in exceptional cases like indexes (e.g. i, j, or k). Do
int numberOfBoxes; char userName;
And don't
int boxes; int b; char k; char usrKey;
Use const for any variable whose value will not be changing. Constants are written in upper case and underscore delimited (and are usually at least two words, except in a few obvious cases like PI, etc.). Do
const int MAXIMUM_WEIGHT = 300;
And don't
const int MAXIUMUMWEIGHT = 300; const int maximumWeight = 300; const int MAXIMUM = 300;
Always initialize a variable or constant (meaning give it value) when it is first declared.Do
int numPizzas = 0; char userKey = ‘‐’;
And don't
int numPizzas; char userKey;
In some cases it will not seem necessary to initialize the variable; however, for example, by initializing numbers to 0 you can avoid potential difficult bugs when code is mistakenly using an uninitialized variable which contains an unpredictable value. Some types, like “char”, may not have a canonical agreed upon initial value, but by choosing a consistent initial value, such difficult bugs coming from unpredictable values are avoided. Some types, like strings, are automatically initialized; thus, these do not need initialization.
Variables are declared at the top of their enclosing scope (including main) except iterator variables in for loops; for example:
for (int i = 0; i < MAX_PIZZAS; ++i) { ... }
Declare iterator variables in for-statements as shown above except in cases where the iterator variable is needed after the loop. See the functions section below for variable and constant style when there are multiple functions.
Literals other than 0 and 1 should rarely occur in the body of code. Use constants or variables to replace such magic numbers. Using constants has two important advantages. First, they make the code easier to read. Your code should read more like English prose with numbers replaced by descriptively named constants. And second, in cases where the programmer wants to later change the value of a constant, it need only be changed in one place at the declaration, and it will be updated in all places throughout the program.
For example, you would never have a line of code in you program like:
totalCost = numberOfLargePizzas * 14.88;
The literal 14.88 is a magic number and does into indicate the meaning of the value. Correct style declares and initiates a const variable at the top of the function and then later uses it in the code.
const double COST_OF_LARGE_PIZZA = 14.88; totalCost = numberOfLargePizzas * COST_OF_LARGE_PIZZA;
The end goal is to 1) make the code easier to read, and 2) make the code easier to maintain so if/when the pizza cost is updated, the only change is it at the declaration.
As with anything, there are exceptions for using literals in the body of code. Common mathematical formulas are good examples:
circumference = 2 * PI * radius
In this case there is not good name to replace the 2, and if the literal were replaced with a constant, it would probably make the formula less readable. Also, since it is a mathematical axiom, the value would not be changing in the future, so nothing is gained with a constants. Such situations occur rarely in general. When in doubt though, prefer using a constant.
The literals 0 and 1 are also notable exceptions. Here are some guidelines for when to use such literals
Note that just because a value is 0 and 1 does not mean it should never be a constant. In fact, in cases except for the above, a 0 and 1 should be a constant. For example, a specification may state that 1 large pizza feeds 7, a medium 3, and a small 1. 7 and 3 are obvious magic numbers. But so is 1, both because the meaning of 1 in the coding context may not be obvious, and because the number of people a small pizza feeds may change.
It is important to note that constants can be abused. Two common abuses are
Here are other example of where using a constant is expected and appropriate:
As a final note, string literals are a little different than number literals so magic strings are treated differently than magic numbers. If for example the code is if (userOption = “quit”), “quit” is a magic string. In most of these situations the string is already readable, and just used in one place, so a constant is not required.
The size limit and one-task requirement affect the complexity of the code. Generally shorter code is simpler to write, easier to understand, and less likely to have defect than longer code. Like any guideline though, it is just a guideline. The ability to read and maintain the code is the high-order bit that overrides these guidelines. If something a bit longer or that does multiple things is easier to understand, maintain, and test, then do it.