Style Guide
When you are modifying an existing program, the first and foremost rule of good coding style is that the style of your code, e.g., its indentation, should match the style of the surrounding code. In effect, it should not be obvious to a reader where different people have edited the code. Also, keep in mind that if you consistently indent your code, it will make it easier for someone else (i.e., the graders) to understand your code.
Specific Guidelines
Any comment that does not appear on the same line as code must consist of one or more complete sentences./* * VERY important single-line comments look like this. */ // Most single-line comments look like this. /* A single-line comment can also look like this. */ /* * Multi-line comments look like this. They should consist of real * sentences. Fill them so that they look like real paragraphs. */Include directives come first. More precisely, if operating system header files (i.e., sys/*.h) are used, they come first, followed by a blank line. Include directives for C standard library header files come next. These include directives should be sorted alphabetically by file name. If application header files (e.g., csapp.h) are used, they come last, preceded by a blank line.
#include <sys/types.h> // Operating system files in angle brackets #include <assert.h> // C standard library files in angle brackets #include <math.h> #include <stdio.h> #include <string.h> #include "csapp.h" // Application files in double quotesMajor structures should be declared near the top of the file in which they are used, or in separate header files if they are used in multiple source files. Try to align the field names in the structure declaration using tabs. Do not, however, use more than two tabs between the type and the field's name.
struct foo { struct foo *next; // List of foo struct mumble amumble; // Description of amumble int bar; // Description of bar struct verylongtypename *baz; // Description of baz };All functions are prototyped somewhere, either in a header file or a source file. Function prototypes for private functions (i.e., functions not used elsewhere) go near the top of the source file. Private functions should be declared static.
All functions should have a requires/effects comment that states the requirements of the function and briefly describes what the function does. As a special case, the requires/effects comment before the "main" function should describe what the program does.
/* * Requires: * Nothing. * * Effects: * If the "-t" option is specified on the command line, then test code is * executed. Otherwise, a simple message is printed to standard * out. Upon completion, the program always returns 0. */ int main(int argc, char *argv[]) { long num; int ch; char *ep;The function type should be on a line by itself preceding the function. The opening brace of the function body should be on a line by itself.
static char * function(int a1, int a2, float fl, int a4) {
There is a space after keywords (if, while, for, return, switch).
There are no spaces after function names. Commas have a space after them. Semicolons not at the end of a line have a space after them. There are no spaces after `(' or `[' or preceding `]' or `)' characters.
error = function(a1, a2); if (error != 0) exit(error);Unary operators do not require spaces, but binary operators do. Do not use parentheses unless they are required for precedence, or unless the statement is confusing without them.
a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1; k = !(l & FLAGS);
Each level of indentation should consist of 8 character positions. By default, in most text editors, including nano, a tab character skips ahead to the next tab stop, which is the next character position that is a multiple of 8. Thus, you may use the tab character instead of multiple spaces to easily indent your code.
Statements that would exceed 80 characters must be wrapped. In other words, the statement should occupy multiple lines. The continuation lines of a wrapped statement are indented an extra four character positions over the line being wrapped. If you have to wrap a long statement, put the operator at the end of the line.
while (cnt > 20 && this_variable_name_is_too_long && ep != NULL) z = a + really + long + statement + that + needs + two + lines + gets + indented + four + spaces + on + the + second + and + subsequent + lines;Closing and opening braces go on the same line as the keyword (if, else, while, for, switch). Braces that are not necessary may be left out.
if (test) stmt; else if (bar) { stmt; stmt; } else stmt;When defining variables in functions, there are two styles: classic and modern. In the classic style, all variables are defined at the beginning of the function. In contrast, in the modern style, a variable is defined when it is first used. You may use either style. When using the classic style, define variables sorted by the size of the type, then in alphabetical order. Note that this means that arrays of and pointers to a particular type should be grouped with objects of that type. Defining multiple variables per line is okay. However, the line must not exceed the 80 character limit. Repeat the type on the continuation line.
struct a_32_byte_struct alfa, *bravo; double charlie, *delta; int *echo, foxtrot, **golf; char hotel, *india, juliett, kilo, lima, mike, november, oscar[16]; char papa, quebec, **romeo;When using the modern style, both the variable's definition and the first assignment to the variable take place in the same statement. Try to minimize the scope of the variable.
long function(long array[], int length) { long sum = 0; for (int i = 0; i < length; i++) { long multiplier = random(); sum += multiplier * array[i]; }
Portions of this style guide have been borrowed from STYLE(9)
from the FreeBSD Kernel Developer's Manual. The original copyright
notice is reproduced below:
Copyright 1992-2012 The FreeBSD Project. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project.