Preface
This tutorial series was created by me to help me put what I am learning down "on paper" as I learn it. This reinforces what I have learned and hopefully my insights will help others. These tutorials cover the basics of cross platform ANSI C programming. You should know how to use a text editor to create your own program source files and how to use a compiler to create executable files from your source files for your computer platform.
Part 1: Structure
Structure. The C programming language begins and ends with structure. The layout of the text, the breakup of the functions, the design of the program itself is all built around the structure of the C program. The design allows you to easily separate ideas and processes into small groups that are easier to manage, create, correct, and expand. In order to write programs in C, it is best, although not required, to understand the structure of a C program.
First you have comments. These are arguably one of the most important single parts of any program in any language. Comments are notes to your self hidden within the program. Your compiler will ignore and completely skip over any text within a comment. They are used to remind you what a function does, what a variable is for, or anything else you want to tell yourself. Having too many comments can be distracting from the program itself, and too few can be useless. You don't need to teach a reader how to program with your comments, usually, but you do want to describe how your program works in case you need to change, correct, or redo whole sections of it.
In C, comments are denoted with a preceding /* and followed by */. Comments can be alone on a line or with other text on a line:
/* This is an example of a comment */ #include <stdio.h> /* This is another comment */
Or a comment can be spread out on any number of lines:
/* This is a multiple line comment */
Comments cannot be nested within one another. As soon as the compiler comes to the first end comment it will continue with the text.
/* This text is hidden /* as is this text, still within the comment until the first end comment here */ This text is not hidden and will cause an error */
If your C compiler supports C++ in addition to C, you could also use // to precede a comment. This only works for single lines and does not require and ending character. However, it is bad practice to use C++ code in a C program, and if you are going to be giving your C source files out to others, or using them on other platforms where you don't have a C/C++ capable compiler, it is not wise to use C++ style comments.
Second are the preprocessor commands. These are commands that tell your compiler what files to include, what to do when it encounters certain settings, what certain words should be replaced with, and more. Preprocessor commands are preceded with a # sign and they generally, but not always, come at the top of the source code.
There are only a few preprocessor commands, but they can be used in very powerful ways.
#include <stdio.h> #include "myincludes/include1.h"
This example tells the compiler to include the files stdio.h and include1.h in with the source code when compiling it. These commands should always be at the top of the source code since they define the functions you will use later on. If the file you are including is not one of the default include files, for example an include file you created, you cannot use < > around the name, but must use quotes and list the path to it like the second example.
#define NULL 0
This creates a constant called NULL. Everywhere in your source that the compiler sees the word NULL, except within string constants like "This is a string constant with NULL", it will automatically replace it with the defined value, in this case, 0.
#if SYSTEM == AMIGADOS #define SYS_FILE <amigados.h> #endif
The #if preprocessor command makes a comparison. It wants to know if SYSTEM has been defined to be equal to AMIGADOS. If it has, it checks the lines after it up until the #endif. For every #if you require an #endif to end the changes.
#if defined(EOF) #undef EOF #endif
This checks to see if EOF was defined at all. If it was it undefines it so that EOF now will not be replaced within the source by the compiler. Don't forget your #endif for every #if.
#if !defined(EOF) #define EOF NULL #endif
The exclamation point ( ! ) is the inverse or NOT operator and checks to see if EOF is NOT defined. If it is not, it defines it. Again, the #endif is required. You could also use shorter forms of #if defined() and #if !defined(). They are #ifdef and #ifndef respectively. If you want to make more than one check you can use #else or #elif.
#ifdef SYSTEM == AMIGA #define DOSINCL <amigados.h> #elif SYSTEM == MSDOS #define DOSINCL <msdos.h> #else #define DOSINCL <cpm.h> #endif #include DOSINCL
This simple example checks to see what SYSTEM is equal to. Equality checks in C are done with two equal signs ( == ), while assignments are done with only one equal sign ( = ). Forgetting this simple fact can cause a lot of simple mistakes that may completely alter the affects of your program.
With these basic preprocessor commands you can do some powerful macro creations.
#define SQUARE(x) ((x)*(x))
Anyplace the compiler finds SQUARE(x), where x can be anything, it replaces it with ((x)*(x)) There are so many parenthesis since x could be a number, an equation, or a call to a function. For example, if it was used like this:
y = SQUARE(3+2);
The compiler would replace SQUARE(3+2) with ((3+2)*(3+2)). Now imagine if it was only defined like this:
#define SQUARE(x) (x*x)
The result would be far different, the compiler would replace SQUARE(3+2) with (3+2*3+2) which is 11 instead of the desired 25.
Lastly there are functions. Functions break the processes that your program has to perform into small groups of other functions, identifiers and assignments. There are the heart and blood of the C program. Functions are what make the program do what you want it to.
There are only about 30 defined identifiers in C like if, break,
and void. Then there are the standard
ANSI includes which define
a few hundred functions. On top of that are an uncountable amount of additional libraries
and includes which add more functions for your use. And you can write your own functions
and your own libraries.

