Table of Contents

A well-written program is about more than just functionality. It's also important that your code follows certain style rules, so that it's easier for you and others understand and fix. In CS11, we'll expect you to adhere to the following style guidelines. Some of these points will not apply until later assignments.

Indentation

Every time a new block of code is introduced via a curly brace, the code within it should be indented 2 or 4 spaces more than the code in the next outer block. Be consistent! Pick either 2 or 4 and use that for the whole program.

This makes it easy to see which code is in the same block and is so fundamental to coding style that you would likely have trouble reading your own code without it!

Example:
int main(int argc, int argv[]) {
   cout << "First outer block, one level of indentation" << endl;

   if (...) {
      cout << "Second block, two levels of indentation" << endl;

      if (...) {
         cout << "Third block, three levels of indentation" << endl;
      }
   }
}
You should always use spaces instead of tabs for your indentation, as different editors interpret and display tabs differently. The good news is that VSCode does this for you. When you hit the tab button, it inserts 4 spaces. If you want, you can change this number of spaces in File -> Preferences -> Settings, search for "tab size", and change the number.

Statements and Spacing

C++ doesn’t care if you put multiple statements on a single line, but we do! A statement in C++ is simply some instruction that ends in a semicolon, so it could be an assignment, a cout or cin, or any number of interesting things. Each statement should go on its own line.

You should also strive to separate your code into logical sections using single blank lines. This will make it much easier to locate a particular section of code.

Example:
double sum_elems(double arr[], int length) {

   // Local variable declarations
   double sum = 0;
   int i;

   // Loop through array, accumulate sum
   for (i = 0; i < length; i++) {
      sum += arr[i];
   }

   // Return sum to the caller
   return sum;
}
Finally, as demonstrated above, binary operators (=, +, <, &&, etc.) should be buffered with a single space:
sum = 0; // Correct
sum=0;   // Incorrect

Line Length

A good rule of thumb is that a single line of code should not exceed 80 characters in length; anything longer than that becomes less readable, particularly during grading.

In this class, having a couple lines of code that exceed the 80-character limit by a few characters is not world-ending. However, if you are consistently writing lines of code longer than 80 characters you need to re-strategize.

Function Length

In CS11, you'll get practice breaking a complex programming task into smaller, simpler operations. To do so, you'll want to decompose the programs you write into several functions.

Any C++ style guide you read will include this general principle: keep functions focused and concise. This is because shorter, simpler functions are easier to write, edit, debug, and test.

In CS11, we say that no function you write should exceed 40 lines in length. While this number is somewhat arbitrary, and there will be a few clearly marked exceptions on the assignments, we find that 40 lines roughly captures the spirit of a focused and concise function.

Here are some more principles you should follow (although when grading, we will focus on the 40-line limit):
  • Functions should have a single purpose.
  • Functions should have at most about 5-10 local variables.
  • Functions should be short; less than or equal to 40 lines in length.

Global Variables

Global variables should only be reserved for constants (variables whose values do not change after initialization). To indicate that a variable is global, make its name uppercase, with underscores to indicate spacing.
const int NUM_FRIENDS = 3; 

Naming

It's ideal to use short, descriptive names for variables, functions, and classes to keep your code concise yet understandable. The names should describe what you're trying to represent without being too wordy.

Here are some general guidelines on what kinds of variable names to use:
  • A noun saying what the variable represents.
  • A specific name given in the assignment description.
  • A conventional name, e.g. a loop counter is often called i, j, or k.
Once we start writing functions in this course, each function should be named either with a noun describing the result it returns (e.g. sum), or with a verb describing the action it does (e.g. sum_elems).

Variable, function, and class names should also look a certain way:
  • Names should either be snake_case (lowercase words separated by underscores), or camelCase (every word but the first capitalized, no underscores). Be consistent with your style.
  • If your name looks ridiculously long, it probably is. Shorten where appropriate.
  • Function names should not include information about the return type. That's evident from the function definition/declaration.
Class names should start with capital letters and be single words, if possible. If this is impossible, do your best to get there or use shorthand. Upper CamelCase is used if there are mulitple words.

Sometimes we break these rules at the start of the course for pedagogical reasons. For example, in encrypt.cpp we were being overly descriptive with variable names in order to make the code as interpretable as possible!

General Commenting

It's hard to read code without any documentation. This is particularly true when we're grading your programs! This is why we ask you to write good comments. Comments let you share your thought process and explain any tricky code. Comments should occur frequently enough in your code to be informative, but not so frequently as to be overwhelming. This can take some practice! Some examples of places comments belong:
  • Above variable declarations (one comment for a group of variable declarations suffices).
  • Above a calculation, especially if it's complex and/or unclear.
  • Above a conditional or loop.
  • At the top of each file (see Header Comments below).
  • Above function definitions (see Function Contracts below).
In general, comments should be useful to the person reading your code. They should not be a narration of every step of your program. Furthermore, while it's useful to comment out code snippets while you're working on a program, commented-out code should be removed from your programs before they are submitted.

Header Comments

Every C++ program you write in CS11 must start with a "header" comment that summarizes the file's contents. Again, this should be the first thing in your file. Some of the contents of a header comment may seem redudant to you, but it's actually useful for grading and in real-world projects! This header comment must include:
  1. The name of the program file.
  2. Your name as the author of the program.
  3. The date when you started working on the file.
  4. A succinct description of the program's purpose.
Here's an example of a header comment:
/*
 * welcome.cpp
 * Author: Richard Townsend (rtowns01)
 * Date: 9/6/2022
 * Purpose: Print a greeting out to the screen.
 */

Function Contracts

Each function you write in this class is expected to have a "function contract" - a comment above the function definition that explains how the function operates. Coming up with the contract first can simplify the implementation process, because you've already written out the key information about the function.

Every function contract should include:
  • The name of the function.
  • The arguments the function expects, and what they represent.
  • A succinct description of the function's action or purpose.
  • What the function returns or what effect it has. Again, you should try to describe what the returned value represents, not just its name and type.
Here are some examples. You should be able to understand what the function will do even without seeing its code!
/* distance
 * Input: Two points on the plane (x, y) and (u, v).
 * Description: Compute the distance between points (x, y) and (u, v).
 * Output: The distance between the two points.
 */
double distance(double x, double y, double u, double v) {
  // Code goes here!
}

/* print_menu
 * Input: None (so this function always computes the same thing).
 * Description: Print out a menu of options for the user.
 * Output: A message printed to standard output.
 */
void print_menu() {
  // Code goes here!
}

/* read_line
 * Input: The name of a file and a pointer to an empty array of
 *        characters.
 * Description: Read the first line of text from the file named by
 *              'filename' and store that text in the character array
 *              pointed to by 'words'.
 * Output: Populates the array pointed to by 'words' and returns the
 *         total number of characters read in.
 */
int read_line(string filename, char *words) {
  // Code goes here!
}