The Preprocessor in C: The #include Statement

After you have programmed in C for a while, you will find yourself developing your own set of macros that you will want to use in each of your programs. But instead of having to type these macros into each new program you write, the preprocessor enables you to collect all your definitions into a separate file and then include them in your pro- gram, using the #include statement. These files normally end with the characters .h and are referred to as header or include files.

Suppose you are writing a series of programs for performing various metric conver- sions.You might want to set up some defines for all of the constants that you need to perform your conversions:

#define INCHES_PER_CENTIMETER 0.394

#define CENTIMETERS_PER_INCH 1 / INCHES_PER_CENTIMETER

 

#define QUARTS_PER_LITER 1.057

#define LITERS_PER_QUART 1 / QUARTS_PER_LITER

 

#define OUNCES_PER_GRAM 0.035

#define GRAMS_PER_OUNCE 1 / OUNCES_PER_GRAM

Suppose you entered the previous definitions into a separate file on the system called metric.h. Any program that subsequently needed to use any of the definitions contained in the metric.h file could then do so by simply issuing the preprocessor directive

#include “metric.h”

This statement must appear before any of the defines contained in metric.h are refer- enced and is typically placed at the beginning of the source file. The preprocessor looks for the specified file on the system and effectively copies the contents of the file into the program at the precise point that the #include statement appears. So, any statements inside the file are treated just as if they had been directly typed into the program at that point.

The double quotation marks around the include filename instruct the preprocessor to look for the specified file in one or more file directories (typically first in the same directory that contains the source file, but the actual places the preprocessor searches are system dependent). If the file isn’t located, the preprocessor automatically searches other system directories as described  next.

Enclosing the filename within the characters < and > instead, as in

#include <stdio.h>

causes the preprocessor to look for the include file in the special system include file directory or directories. Once again, these directories are system dependent. On Unix systems (including Mac OS X systems), the system include file directory is /usr/include, so the standard header file stdio.h can be found in

/usr/include/stdio.h.

To see how include files are used in an actual program example, type the six defines given previously into a file called metric.h. Then type in and run Program 13.3.

Program 13.3   Using the #include Statement

/* Program to illustrate the use of the #include statement

Note: This program assumes that definitions are set up in a file called metric.h                             */

#include <stdio.h>

#include “metric.h”

int main (void)

{

float liters, gallons;

printf (“*** Liters to Gallons ***\n\n”);

printf (“Enter the number of liters: “);

scanf (“%f”, &liters);

gallons = liters * QUARTS_PER_LITER / 4.0;

printf (“%g liters = %g gallons\n”, liters, gallons);

return 0;

}

Program 13.3   Output

*** Liters to Gallons ***

Enter the number of liters: 55.75

55.75 liters = 14.73 gallons.

The preceding example is a rather simple one because it only shows a single defined value (QUARTS_PER_LITER) being referenced from the included file metric.h. Nevertheless, the point is well made: After the definitions have been entered into metric.h, they can be used in any program that uses an appropriate #include statement.

One of the nicest things about the include file capability is that it enables you to cen- tralize your definitions, thus ensuring that all programs reference the same value. Furthermore, errors discovered in one of the values contained in the include file need only be corrected in that one spot, thus eliminating the need to correct each and every program that uses the value. Any program that references the incorrect value simply needs to be recompiled and does not have to be edited.

You can actually put anything you want in an include file—not just #define state- ments, as might have been implied. Using include files to centralize commonly used pre- processor definitions, structure definitions, prototype declarations, and global variable declarations is good programming technique.

One last point to be made about include files in this chapter: Include files can be nested. That is, an include file can itself include another file, and so on.

1. System  Include Files

It was noted that the include file <stddef.h> contains a define for NULL and is often used for testing to see whether a pointer has a null value. Earlier in this chapter, it was also noted that the header file <math.h> contains the definition M_PI, which is set to an approximation for the value of p.

The <stdio.h> header file contains information about the I/O  routines contained in the standard I/O  library. This header file is described in more detail in Chapter 16, “Input and Output Operations in C.”You should include this file whenever you use any I/O  library routine in your program.

Two other useful system include files are <limits.h> and <float.h>. The first file, <limits.h>, contains system-dependent values that specify the sizes of various character and integer data types. For instance, the maximum size of an int is defined by the name INT_MAX inside this file. The maximum size of an unsigned long int is defined by ULONG_MAX, and so on.

The <float.h> header file gives information about floating-point data types. For example, FLT_MAX specifies the maximum floating-point number, and FLT_DIG specifies the number of decimal digits of precision for a float type.

Other system include files contain prototype declarations for various functions stored inside the system library. For example, the include file <string.h> contains prototype declarations for the library routines that perform character string operations, such as copying, comparing, and concatenating.

For more details on these header files, consult Appendix B.

Source: Kochan Stephen G. (2004), Programming in C: A Complete Introduction to the C Programming Language, Sams; Subsequent edition.

Leave a Reply

Your email address will not be published. Required fields are marked *