Organized C code – Part 1 – The Headers

This is a step-by-step guide to writing code in C and keeping it organized as you go.  It will help you write code that can be reused on multiple projects and hardware platforms.  I will explain some of the finer details along the way so, technically, you don’t even need to know how to program in C to use this guide.

This first part will just go through some templates that every set of C header files will start with.  These header files are used to pre-define the C code you will be writing in a future part of this guide.  That is it for the introductions, now on to your first step writing organized C code!

Step 1

Create a directory for your files with two subdirectories: include and src.  For example, my directory structure looks like this:

directory structure

organized/
organized/include/
organized/src/

The include directory will store all of your header (.h) files and the src directory will store all of your source (.c) files.  These are the files that the C compiler will use to generate machine code (binary language) for your computer.  The C compiler has a “preprocessor” that will look through the code and make changes before attempting to generate machine code.  The C preprocessor is your friend and I will refer to it often.

Step 2

If you need a program to write files, I suggest Microsoft’s Visual Studio Code available here.

Create a text file for the public header that ends with .h to indicate it is a header file.  Save this file in your include directory. For example, the path to my file is:

organized/include/organized.h

snap_2016-10-04_13h51m22s_003_organized-h-visual-studio-code

Paste the following code into your file.  This is the code needed for every header file.  Each time you use this code, replace “ORGANIZED_H” with something that matches your file name.  The only requirement is that you make it unique.  The same name cannot be defined by any other code within a project that uses this header file and I will explain why below.

#ifndef ORGANIZED_H
#define ORGANIZED_H
#ifdef __cplusplus
extern "C" {
#endif
// public header code goes here
#ifdef __cplusplus
}
#endif
#endif // ORGANIZED_H
// empty line

Here are details on this template line by line:

  1. #ifndef is a command used by the C preprocessor that means “If not defined”.  It is used here to check for the name that uniquely identifies this header file so that the entire file can be skipped if it has already been included in the project.  There are other ways to do this, but this method is the only one that is supported by ALL C compilers.
  2. #define is a command used by the C preprocessor that means “Define this value”.  It is used here to define the name you have chosen, which means the next time this header file is included somewhere in the project, the name will already be defined.
  3. #ifdef is a command used by the C preprocessor that means “If defined”.  It is used here to check if the compiler is actually a C++ compiler.  A C++ compiler can do everything a C compiler can do (and more), but it likes to keep things separate.  That is why we will add some code only if this is a C++ compiler.
  4. extern is a keyword that tells the compiler the following code should be made available throughout the program and not just to this file.  It is used here because a C++ compiler was detected at line 3 and we want all of our header code to be made available to C and C++ alike.  The { open brace starts a group of code (code block) that will be made accessible because of the extern keyword.
  5. #endif is a command used by the C preprocessor that means “End if”.  It is used here to end the #ifdef statement from line 3.  Every #if statement requires a matching #endif
  6. // is a single line comment.  Almost all C compilers support this.  If you want to be extra careful that your code will be portable (supported by ALL C compilers), you should write all comments like this instead:
    /* public header code goes here */
  7. #ifdef is here again to ensure we only write the code below it if this is a C++ compiler
  8. } is a closed brace that ends the extern group started at line 4
  9. #endif ends the #ifdef at line 7
  10. #endif ends the #ifndef at line 1.  The single line comment // to the side of the #endif makes it easy to find the #if statement that is being ended here.  This is because there could be hundreds of lines of code between the #if and #endif so it is not easy to read without the extra comment.
  11. This line should be empty.  This webpage won’t let me show it, but this should be an empty line.  If the last line in your file is not empty, the preprocessor could accidentally put code right next to it without any indication that it should have been separate.  If any of your .h or .c files do not have an empty line at the end, go add them now.

Step 3

Create a text file for the private header that ends with .h to indicate it is a header file.  Save this file in your include directory.  For example, the path to my file is:

organized/include/organized_private.h

Paste the header template code into your file and change the #define name and the comment to indicate this is your private header.  For example, I have changed lines 1,2,6,and 10:

#ifndef ORGANIZED_PRIVATE_H
#define ORGANIZED_PRIVATE_H
#ifdef __cplusplus
extern "C" {
#endif
// private header code goes here
#ifdef __cplusplus
}
#endif
#endif // ORGANIZED_PRIVATE_H
// empty line

That is it for Part 1.  You can download the sample code here.

In the next part we will start to fill-in the public header file.

Author: sirspot

I write software, love my wife and kids, do various house projects, play video games when I have time, and could use a little more sleep