Week 4 – Pre-processor
Directive
Course Lecturer:
Muhammad Shamsu Usman
([email protected]
)
Department of Computer Science, FUD -
2024/2025
Defines preprocessor directives
Introduces the #include preprocessor directive
Introduces the #define preprocessor directive
Provides examples of both
the C++ compiler routes your programs
through a preprocessor before it compiles
them.
The preprocessor can be called a “pre-
compiler” because it preprocesses and
prepares your source code for compiling before
your compiler receives it.
Because this preprocess is so important to C+
+, you should familiarize yourself with it before
learning more specialized commands in the
language.
Regular C++ commands do not affect the
preprocessor.
You must supply special non-C++ commands,
called preprocessor directives, to control the
preprocessor.
These directives enable you, for example, to
modify your source code before the code reaches
the compiler.
Preprocessor directives are commands that
you supply to the preprocessor.
Allpreprocessor directives begin with a
pound sign (#).
Never put a semicolon at the end of
preprocessor directives, because they are
preprocessor commands and not C++
commands.
Preprocessor directives typically begin in the
first column of your source program.
They can begin in any column, of code, but you
should try to be consistent with the standard
practice and start them in the first column
wherever they appear.
program below contains three preprocessor
directives.
// C++ program that demonstrates preprocessor
directives.
#include <iostream>
#define AGE 28
#define MESSAGE “Hello, world”
main()
{
int i = 10, age; // i is assigned a value at
declaration
// age is still UNDEFINED
age = 5; // Defines the variable, age, as five.
i = i * AGE; // AGE is not the same as the variable,
age.
cout << i << “ “ << age << “ “ << AGE << “\n”;
cout << MESSAGE; // Prints “Hello world”.
return 0;
}
Preprocessor directives cause your
C++ preprocessor to change your
source code, but these changes last
only as long as the compilation.
When you look at your source code
again, the preprocessor is finished
with your file and its changes are no
longer in the file.
Your preprocessor does not in any
way compile your program or change
your actual C++ commands.
The #include Directive
The #include preprocessor directive merges a
disk file into your source program.
Remember that a preprocessor directive does
nothing more than a word processing
command does to your program
Word processors also are capable of file
merging.
The format of the #include preprocessor
directive follows:
#include <filename>
or
#include “filename”
Inthe #include directive, the filename
must be an ASCII text file (as your
source file must be) located somewhere
on a disk.
To better illustrate this rule, it might
help to leave C++ for just a moment.
The following example shows the contents
of two files on disk.
One is called OUTSIDE and the other is
called INSIDE.
These are the contents of the OUTSIDE file:
Now is the time for all good men
#include <INSIDE>
to come to the aid of their country.
The INSIDE file contains the following:
A quick brown fox jumped
over the lazy dog.
Assume you can run the OUTSIDE file
through the C++ preprocessor, which finds
the #include directive and replaces it with
the entire file called INSIDE.
In other words, the C++ preprocessor
directive merges the INSIDE file into the
OUTSIDE file—at the #include location—and
OUTSIDE expands to include the merged
text.
After the preprocessing ends, OUTSIDE looks
like this:
Now is the time for all good men
A quick brown fox jumped
over the lazy dog.
to come to the aid of their country.
The INSIDE file remains on disk in its original
form.
Only the file containing the #include directive
is changed.
This change is only temporary; that is,
UTSIDE is expanded by the included file only
for as long as it takes to compile the program.
A few real-life examples might help,
because the OUTSIDE and INSIDE files are
not C++ programs.
You might want to include a file containing
common code that you frequently use.
Suppose you print your name and address
quite often.
You can type the following few lines of code
in every program that prints your name and
address:
cout << “Sadiya Abdu\n”;
cout << “Apartment 217\n”;
cout << “No. 23 Godiya miyetti, takur\n”;
cout << “Dutse Jigawa, Jigawa State\n”;
cout << “ Nigeria\n”;
Instead of having to retype the same five
lines again and again, you type them once
and save them in a file called MYADD.C.
From then on, you only have to type the
single line:
#include <myadd.c>
You usually can use angled brackets, <>, or
double quotation marks, “ ”, around the
included filename with the same results.
The angled brackets tell the preprocessor to
look for the include file in a default include
directory, set up by your compiler.
The double quotation marks tell the
preprocessor first to look for the include file in
the directory where the source code is stored,
and then, to look for it in the system’s include
directory.
Most of the time, you do see angled brackets
around the included filename.
If you want to include sections of code in
other programs, be sure to store that code in
the system’s include directory (if you use
angled brackets).
Even though #include works well for
inserted source code, there are other ways
to include common source code that are
more efficient.
This source code #include example serves well
to explain what the #include preprocessor
directive does.
Despite this fact, #include seldom is used to
include source code text, but is more often
used to include special system files called
header files.
These system files help C++ interpret the
many built-in functions that you use.
Your C++ compiler comes with its own header
files.
When you (or your system administrator)
installed your C++ compiler, these header files
were automatically stored on your hard drive in
the system’s include directory.
Their filenames always end in .h to differentiate
them from regular C++ source code.
The most common header file is named
iostream
This file gives your C++ compiler needed
information about the built-in cout and cin
operators, as well as other useful built-in
routines that perform input and output.
The name “iostream” stands for input/output
stream header.
At this point, you don’t have to understand
the iostream file.
You only have to place this file before main()
in every program you write.
It is rare that a C++ program does not need
the iostream.h file.
Even when the file is not needed, including it
does no harm.
Your programs can work without iostream.h
as long as they do not use an input or output
operator defined there.
Nevertheless, your programs are more
accurate and hidden errors come to the
surface much faster if you include this file.
you may see strcpy() function. Its header file is
called string.h.
Therefore, if you write a program that contains
strcpy(), include its matching header file at the
same time you include <iostream>.
These appear on separate lines, such as:
#include <iostream>
#include <string.h>
The order of your include files does not matter
as long as you include the files before the
functions that need them.
Most C++ programmers include all their
needed header files before main().
These header files are simply text files. If you
like, find a header file such as stdio.h on your
hard drive and look at it.
The file might seem complex at this point, but
there is nothing “hidden” about it.
Don’t change the header file in any way while
looking at it. If you do, you might have to
reload your compiler to restore the file.
The following program is short. It includes the
name-andaddress printing routine described
earlier. After printing the name and address, it
ends.
// Illustrates the #include preprocessor directives.
#include <iostream.h>
main()
{
#include “myadd.c”
return 0;
}
The double quotation marks are used
because the file called MYADD.C is stored in
the same directory as the source file.
Remember that if you type this program into
your computer and then compile your
program, the MYADD.C file is included only as
long as it takes to compile the program.
Your compiler does not see this file. Your
compiler acts as if you have typed the
following:
#include <iostream>
main()
{
cout << “Sadiya Abdu\n”;
cout << “Apartment 217\n”;
cout << “No. 23 Godiya miyetti, takur\
n”;
cout << “Dutse Jigawa, Jigawa State\n”;
cout << “ Nigeria\n”;
}
2. The following program copies a message
into a character array and prints it to the
screen. Because the cout and strcpy() built-in
functions are used, both of their header files
are included.
#include <iostream.h>
#include <string.h>
main()
{
char message[20];
strcpy(message, “This is fun!”);
cout << message;
}
The #define preprocessor directive is used in
C++ programming, although not nearly as
frequently as it is in C.
Due to the const keyword (in C++) that
enables you to define variables as constants,
#define is not used as much in C++.
Nevertheless, #define is useful for
compatibility to C programs you are
converting to C++.
The #define directive might seem strange at
first, but it is similar to a search-and-replace
command on a word processor.
The format of #define follows:
#define ARGUMENT1 argument2
where ARGUMENT1 is a single word
containing no spaces.
Use the same naming rules for the #define
statement’s first argument as for variables
For the first argument, it is traditional to use
uppercase letters—one of the only uses of
uppercase in the entire C++ language.
At least one space separates ARGUMENT1
from argument2.
The argument2 can be any character, word,
or phrase; it also can contain spaces or
anything else you can type on the keyboard.
Because #define is a preprocessor directive
and not a C++ command, do not put a
semicolon at the end of its expression.
The #define preprocessor directive replaces
the occurrence of ARGUMENT1 everywhere in
your program with the contents of argument2.
In most cases, the #define directive should go
before main() (along with any #include
directives).
Look at the following #define directive:
Define the AGELIMIT literal to 21.
#define AGELIMIT 21
If your program includes one or more
occurrences of the term AGELIMIT, the
preprocessor replaces every one of them with
the number 21.
#define enables you easily to define and
change literals, the replaced arguments of the
#define directive are sometimes called defined
literals.
You can define any type of literal, including
string literals. The following program contains
a defined string literal that replaces a string in
two places.
#include <iostream>
#define MYNAME “Phil Ward”
main()
{
char name[]=MYNAME;
cout << “My name is “ << name << “\n”;
//Prints the array.
cout << “My name is “ << MYNAME << “\n”;
// Prints the defined literal.
return 0;
}
The first argument of #define is in uppercase to
distinguish it from variable names in the
program.
Variables are usually typed in lowercase.
Although your preprocessor and compiler will not
confuse the two, other users who look at your
program can more quickly scan through and tell
which items are defined literals and which are
not.
They will know when they see an uppercase
word (if you follow the recommended standard
for this first #define argument) to look at the top
The fact that defined literals are not variables
is even more clear in the following program.
This program prints five values.
Try to guess what those five values are before
you look at the answer following the program.
// Illustrates that #define literals are not variables.
#include <iostream>
#define X1 b+c
#define X2 X1 + X1
#define X3 X2 * c + X1 - d
#define X4 2 * X1 + 3 * X2 + 4 * X3
main()
{
int b = 2; // Declares and initializes four variables.
int c = 3;
int d = 4;
int e = X4;
// Prints the values.
cout << e << “, “ << X1 << “, “ << X2;
cout << “, “ << X3 << “, “ << X4 << “\n”;
return 0;
}