CPE 101 Coding Style

Why style?

Uniformity. When you work for a software development company, your code is read and worked with by many other people. Because of this, you want to make your code readable. Because there is usually more than one person writing code, you want all code written to be consistent. Style rules set up the guidelines for how the code should look. Knowing what they are and following them allows others read and understand your code with more ease, and, in turn, allows you to work with other people's code and not be afraid of surprises.

 

Convenience. Uniformity, in many cases, just means picking some style, any style, and following it. However, there are some rules that make sense even in the absence of the need for uniformity. Certain ways to write code are a bad practice and needs to be prevented regardless of anything else.

Spacing

Braces

Opening braces belong on their own line directly after a function name or the if, else, switch, while, do, and for keywords.

Closing braces also belong on their own line.

Orphans

ALWAYS use braces with control flow statements (if, else, switch, while, do, and for).

Although allowed by the syntax, I always see some unfortunate student make the following mistake.


if (some_number != 1)
   do_something();
                  

Then when they are trying to debug their code, they do the following:


if (some_number == 1)
   printf("Debugging print: %d\n", some_number);
   do_something();
                  

Now, the do_something() function will always be called. Further breaking the code.

Indentation

Horizontal whitespace (indentation) helps make code much more readable by making the different blocks (think of them as paragraphs in a paper) immediately apparent.

NEVER use tabs.

Instead of tabs, use 3 spaces.

All reasonable text editors can be automatically configured to use spaces instead of tabs.

After each open brace, you should increase the indentation level by one. The closing brace should be on the same level as the opening brace.

Compare the following code segment with and without proper indentation.


if (num >= 0)
{
printf("Print 0\n");
if (num % 2 == 0)
{
printf("Print 1\n");
}
else
{
printf("Print 2\n");
if (num == 3)
{
printf("Print 3\n");
}
else
{
if (num == 5)
{
printf("Print 4\n");
}
else
{
printf("Print 5\n");
}
}
}
}

printf("Print 6\n");

if (num == 0)
{
printf("Print 7\n");
}
               

if (num >= 0)
{
printf("Print 0\n");
if (num % 2 == 0)
{
   printf("Print 1\n");
}
else
{
   printf("Print 2\n");
   if (num == 3)
   {
      printf("Print 3\n");
   }
   else
   {
      if (num == 5)
      {
         printf("Print 4\n");
      }
      else
      {
         printf("Print 5\n");
      }
   }
}
}

printf("Print 6\n");

if (num == 0)
{
printf("Print 7\n");
}
               

Vertical Whitespace

Use vertical whitespace to make your code more readable.

Use it to break apart pieces of code that are logically different.

Only use a single newline in a row. Too much whitespace can make a file too long and hard to read.


int a;
int b;
// Do some math with a.
a = someFunction();
a -= 5;
printf("a is %d\n", a);
// Do some different math on b.
b = someOtherFunction();
b += 5;
printf("b is %d\n", b);
               

int a;
int b;

// Do some math with a.
a = someFunction();
a -= 5;
printf("a is %d\n", a);

// Do some different math on b.
b = someOtherFunction();
b += 5;
printf("b is %d\n", b);
               

Operator Spacing

All binary and tertiary operators should be surrounded by a single space.

Unary operators (such as '++' and '--') do not need a space between the operator and its operand.

Bad


int val=a+b-c*d+5;
val ++;
               

Good


int val = a + b - c * d + 5;
val++;
               

Guard Spacing

The expression in parenthesis after an if is called a boolean guard.

There should always be a space between the if and the guard.

The same rule applies for for, while, and switch.

else if

C does not syntacticly support an 'else-if' operator.

However, this can be simulated by placing an if directly after an else.


if (number < 0)
{
   printf("Positive\n");
}
else if (number > 0)
{
   printf("Negative\n");
}
else
{
   printf("Zero\n");
}
               

Naming

Meaningful Names and Abbreviations

You should always strive to use meaningful variable names and abbreviations.

The name of a variable can be very useful in figuring out what a piece of code does.

Variable Names

All variables names should be in all lowercase letter. All subsequent words should be separated with an underscore.


int num;
int some_number;
int some_other_number_whose_name_is_a_bit_too_long;
                  

Struct Names

All struct names should be named the same as variables.


struct poiont
{
   int x;
   int y;
};

struct some_really_cool_struct
{
   float value;
   int dogs;
   int cats;
}
                  

Function Names

Functions names should be the same as variable names.

Constant Names

Constants (#define's) should be named in ALL_CAPS with an underscore between words.

Line Length

Lines should be no longer than 80 characters.

Magic Numbers

A 'Magic Number' is any number whose meaning is not immediately apparent.

Pretty much, any number but 0, 1, -1, and 2 is a magic number.

Magic numbers are not allowed.

If you need an arbitrary number, it should be #define it as a constant.

For example, what does the following code calculate?


int val = 3 * 10 - 2
               

val will be 28, but what does that mean? Alone, the value 28 means nothing.

Constants give the code some context:


#define LECTURES_PER_WEEK 3
#define WEEKS_PER_TERM 10
#define HOLIDAYS_PER_QUARTER 2

int val = LECTURES_PER_WEEK * WEEKS_PER_TERM - HOLIDAYS_PER_QUARTER
               

Now we can see that this code is calculating the number of lectures in a academic term.

If we switch to the longer terms (like a semester system) or change the number of lectures per week, we can do it in a single place.

Global Variables

NEVER use global variables.

Circular-Inclusion

All header files (.h) must actively prevent circular-inclusion.

This is done by #define'ing a unique constant in the header file and checking if it exists.

By convention, the constant is named the same as with file in all uppercase with an underscore instead of a period before the extension.

For example, the file point.h will have a header that looks something like:


#ifndef POINT_H
#define POINT_H

// The actual header content.
.
.
.

#endif POINT_H
               

his code checks to see if the constant POINT_H is defined. If it is, then it ignores all the code up until #endif. If it is not defined, then it will execute all the code up until #endif. Which includes defining the POINT_H constant.

Function Length

Write short functions. Keep the short and simple.

Functions should be doing a single, clearly identifiable action.

Function should rarely be long. You should be prepared to justify any long functions.

Comments

Helpful Comments

Your code should be peppered with comments that explain all complex logic.

Header

Each .c and .h file you submit must contain a header comment at the top. The comment shall contain, at the very least, the following information:

If the file is part of a team submission, put team name and names of all students of the team on the header comment, regardless of who actually created the file. You can use a separate comment to identify the specific author/authors.


/*
 * Assignment: Assignment 1
 * Course: CPE 101
 * Author: Eriq Augustine (eaugusti)
 *
 * Does all the code and things.
 */
                  

Some information take from Professor Mammen's and Professor Dekhtyar's 101 styles guides.