User Tools

Site Tools


style

Phys2660 Style Guide

This page gives a few stylistic recommendations for writing programs in the C/C++ programming language. The recommendations are based on standards commonly applied in the programming world. Source code should always be written to maximize readability independently of how the code is viewed. For example an editor or IDE may display your source with color coding to enhance readability, but you should never rely on such features to replace good style practices for making your code readable in plain text format. Careful attention to code indentation and sensible names for variables and functions will often go a long way towards improving readability.

The main goal of adhering to style guidelines is to improve the readability of your code and thus enhance understanding of how it works and to make your code easier to debug and maintain. Good programming style is not a one of a kind thing, though experienced programmers will largely adopt practices like those below. As a rule, you should closely adhere to these general guidelines when writing your programs, but the guidelines may occasionally be violated (if necessary) to increase the readability of your code in specific cases. Think about how your code would look to someone else (your TA for example). Always take a few minutes after you are finished writing your program to polish up your code before you present it. Comment blocks of code to easily identify significant pieces of functionality and where the functionality may not be clear. A superior approach is to avoid cryptic looking code so that the source is largely self documenting.

Naming Conventions

Write named constants and enumeration types in UPPER case, using an underscore to separate words

const int MAX_ITERATIONS = 100;
const float ALPHA = 1/137.0;
const double TWO_PI = 6.283185;

Avoid #defineing constants.

Write variable names in mixed case, starting with a lower case letter

int count;
float fieldStrength;

Write function names in mixed case, starting with a lower case letter

float area(float length, float width);
void printStatus();

Write names for user-defined data types in mixed case, starting with an UPPER case letter

typedef Uint64 unsigned long;
typedef struct {
  double real;
  double imaginary;
} Complex;

Variable names should be instructive about the function of the variable

char timeZone[4];

float area, length, width;
...
area = length * width;

This is especially important for variables with a large scope 
i.e. those used throughout many lines of code.

Short variable names are preferred for variables with limited scope or for temporary storage

for (int i=0; i<100; i++) pages[i]=0;

i, j, and k, are commonly used as iterator variables

Pointers should have their reference symbol next to the variable name, not the type name

float *x; // NOT float* x;

Related variables of the same type can be declared in a common statement, unrelated variables should be declared in separate statements.

float x, y, z;
float dxdt, dydt, dzdt; 

Other comments:

  • Do not use capitalization alone to differentiate variable names e.g.
 int abc, aBc  // avoid this!
  • Do not use the names of functions in the standard C libraries for your variables or functions
  • Use the prefix n for variables representing a number of objects e.g.
int nPoints, nObjects;
  • Avoid Abbreviations
float classAverage; // Not classAvg
  • Variables should not have a dual meaning. Use different variables for different concepts in your code.
  • The use of global variables must be minimized.

Source Files

File Names

For your assignments in this class:

Your header files must have the extension: .hpp
Your source files must have the extension: .cpp

Keep the lines in your program to 80 characters or less.

This facilitates printing and viewing your files in different editors. Use indentation to clearly identify statements that are split into two or more lines.

printf("Acceleration of %f Kg body due to force of %f Newtons is %f m/s^2:\n",
      mass, force, force/mass);
totalSum = a + b + c +
           d + e;

makeGraph(xValues, yValues, xRMS, yRMS,
          outputArray);

Special characters like TAB and page break must be avoided. These often cause problems in displaying and printing your code in different environments and can even prevent you code from compiling. Use spaces in stead of TABS. Fortunately, editors like emacs automatically convert TABs to spaces when they auto-indent your code.

Aviod Abbreviations

float computeAverage(); // and not: float computeAvg();

Include statements

Include statements should be sorted and grouped by hierarchical position in the system. Low levels files are listed first, followed by higher level includes. Put a space between groups of include statements.

#include<stdio.h>
#include<stdlib.h>
#include<X11/X.h>
#include<X11/Xutil.h>
#include<phys_2660.h>

Locate include statements only at the top of your source files.

Conditionals and Loops

Implicit tests for 0 should be used only on boolean data (C++ only) or pointers

int nLines = getLines();
if (nLines !=0 ); // Not if (nLines)

Do not test for 0 directly on floating point data

if ( fabs(xValue) < SMALL ) // Not if (xValue == 0)

Avoid complex conditions, use temporary variables instead

if ( (nElement<MAX_ELEMENTS) && (newElement< HIGH_LIMIT) && 
     (newElement> LOW_LIMIT) )

can be written as

isInRange = (newElement< HIGH_LIMIT) &&  (newElement> LOW_LIMIT);
if (nElement<MAX_ELEMENTS && isInRange)

Place only control statements in a for() construction

sum=0;                //Not: for(i=0, sum=0; i<100; i++)
for(i=0; i<100; i++)  //       sum+=value[i];
  sum+=value[i];

Beware “MAGIC NUMBERS”

int items[10];              // do not repeat “magic numbers”
for (int i=0; i<10; i++){   // throughout your code
  items[i] = myFunction(i);
}

It is very difficult to maintain code that has numeric constants defined in many places. Such values should only be defined once. This way changes may easily be propagated through your code. And you can better avoid bugs related to inconsistent definitions of your constant values throughout your code. A better way to write the above code is as follows:

const int NITEMS=10;        // define data size
int items[NITEMS];          // array is NITMES in size    
for (int i=0; i<NITEMS; i++){ // loop over NITEMS
  items[i] = myFunction(i);
}

The constant should be defined in the appropriate scope for where it needs to be used in your code. If necessary the value may also be defined via the preprocessor, but a constant data type is generally preferable.

Nice features of C++

Although this class concentrates on aspects of programming in C, we will be using the C++ compiler. And therefore we encourage the use of a few extensions to C that may be used to increase code readability.

Comments

  • Usage of the // syntax for comments at the end of a line (valid in C++ and C99) e.g.:
int nFrogs;  // number of frogs in my pond

this is preferred to commenting your code in the old C style

int nFrogs;  /* number of frogs in my pond */

For commenting blocks of code use the form below (this makes multiline comments easier to identify):

// function: float rms(float sum, float sum2, int nPoints)
// This function calculates the RMS of a data set
// Inputs: float sum,  sum of values
//         float sum2, sum of squares of values
//         int nPoints, number of data points
// Returns: float, the RMS of the data
float rms(float sum, float sum2, int nPoints)

// The following block of code does something very interesting
// if not exciting
for (int i=1, i<MAX_TRIALS, i++)
...
  • In C all variable declarations are performed at the top of your functions, before the start of executable statements. In C++ variables may be defined at the point in the code where they are first used. This can greatly increase readability for long functions, because it is not necessary to scroll to the top of your source code to compare a variable's definition to it's usage. Another advantage is that variables can be limited to much smaller scopes, this can help a great deal in preventing bigs from creeping into your code. We will use this feature frequently in the homework and lab solutions.

Limiting Variable Scopes

In general

  • It is generally good practice to limit a variable to the smallest possible scope in your programs.
  • Do not use global variables to pass variable data between functions. Instead pass your data in the function calls.

In C++ it is possible to define variables at any line in your functions. Two simple examples are to restrict iterator variables to the scope of a loop construct and to define temporary variables at the point where they are used, eg:

for (int i=0; i<10; i++){ // iterator variable "i" is not valid outside of this for loop
  // ...some code... 
}
//...
for (int i=0; i<10; i++){ // "i" may be redefined in a later loop, the previous
  // ... more code ...    // instance was deleted after leaving the scope of the above loop
  double temp = i*100;    // Similarly any temporary variable defined in the limited scope 
  // ... more code ...    // of a code block, is confined to that region of code.
}

Defining variables locally in the most limited scope will often make your code more readable and also prevent misuse of variables in unexpected places in your programs.

Various links to programming style references

We suggest the following links as sources of further guidance for developing your programming style.

  • Check the web for many other resources
style.txt · Last modified: 2015/01/22 05:48 by neu