You are on page 1of 13

F

Preprocessor
Hold thou the good; dene it well.
Alfred, Lord Tennyson

I have found you an argument;


but I am not obliged to nd
you an understanding.
Samuel Johnson

OBJECTIVES
In this chapter you will learn:

A good symbol is the best


argument, and is a missionary
to persuade thousands.
Ralph Waldo Emerson

Conditions are
fundamentally sound.
Herbert Hoover [December
1929]

To use #include for developing large programs.


To use #define to create macros and macros with
arguments.
To understand conditional compilation.
To display error messages during conditional
compilation.
To use assertions to test if the values of expressions are
correct.

The partisan, when he is


engaged in a dispute, cares
nothing about the rights of
the question, but is anxious
only to convince his hearers
of his own assertions.
Plato

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Outline

Chapter F Preprocessor
F.1
F.2
F.3
F.4
F.5
F.6
F.7
F.8
F.9
F.10

Introduction
The #include Preprocessor Directive
The #define Preprocessor Directive: Symbolic Constants
The #define Preprocessor Directive: Macros
Conditional Compilation
The #error and #pragma Preprocessor Directives
The # and ## Operators
Predefined Symbolic Constants
Assertions
Wrap-Up

Summary | Terminology | Self-Review Exercises | Answers to Self-Review Exercises | Exercises

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Instructors Manual

Instructors Manual
F.1

Fill in the blanks in each of the following:


a) Every preprocessor directive must begin with
.
ANS: #.
b) The conditional compilation construct may be extended to test for multiple cases by using the
and the
directives.
ANS: #elif, #else.
directive creates macros and symbolic constants.
c) The
ANS: #define.
d) Only
characters may appear before a preprocessor directive on a line.
ANS: white space.

e) The

ANS: #undef.

f) The

defined(name)

directive discards symbolic constant and macro names.


and
and #if

ANS: #ifdef, #ifndef.

g)

directives are provided as shorthand notation for #if

!defined(name).

enables the programmer to control the execution of preprocessor directives


and the compilation of program code.

ANS: Conditional compilation.

h) The
macro prints a message and terminates program execution if the value
of the expression the macro evaluates is 0.

ANS: assert.

i) The

directive inserts a file in another file.

j) The

operator concatenates its two arguments.

k) The

operator converts its operand to a string.

ANS: #include.

ANS: ##.
ANS: #.

l) The character
indicates that the replacement text for a symbolic constant
or macro continues on the next line.

ANS: \.

F.2

Write a program to print the values of the predefined symbolic constants


__FILE__, __DATE__ and __TIME__ listed in Fig. F.1.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// exF_02.cpp
// Self-review exercise F.2 solution.
#include <iostream>
using std::cout;
using std::endl;
int main()
{
cout <<
<<
<<
<<
<<

"__LINE__ = " <<


"__FILE__ = " <<
"__DATE__ = " <<
"__TIME__ = " <<
"__cplusplus = "

__LINE__ << endl


__FILE__ << endl
__DATE__ << endl
__TIME__ << endl
<< __cplusplus << endl;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

__LINE__,

4
16
17
18

Appendix F Preprocessor

return 0;
}

// end main

__LINE__ = 10
__FILE__ = c:\cpphtp5_examples\appF\exF_02.cpp
__DATE__ = Jul 17 2002
__TIME__ = 09:55:58
__cplusplus = 199711

F.3

Write a preprocessor directive to accomplish each of the following:


a) Define symbolic constant YES to have the value 1.
ANS: #define YES 1

b) Define symbolic constant NO to have the value 0.


ANS: #define NO 0

c) Include the header file common.h. The header is found in the same directory as the file
being compiled.
ANS: #include "common.h"

d) If symbolic constant
#ifdef.

TRUE

is defined, undefine it, and redefine it as 1. Do not use

ANS: #if defined(TRUE)


#undef TRUE
#define TRUE 1
#endif

e) If symbolic constant TRUE is defined, undefine it, and redefine it as 1. Use the #ifdef
preprocessor directive.
ANS: #ifdef TRUE
#undef TRUE
#define TRUE 1
#endif

f) If symbolic constant ACTIVE is not equal to 0, define symbolic constant INACTIVE as 0.


Otherwise, define INACTIVE as 1.
ANS: #if ACTIVE
#define INACTIVE 0
#else
#define INACTIVE 1
#endif

g) Define macro CUBE_VOLUME that computes the volume of a cube (takes one argument).
ANS: #define CUBE_VOLUME( x )

( ( x ) * ( x ) * ( x ) )

Solutions
F.4
Write a program that defines a macro with one argument to compute the volume of a
sphere. The program should compute the volume for spheres of radii from 1 to 10 and print the
results in tabular format. The formula for the volume of a sphere is
( 4.0 / 3 ) * * r3

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
where is 3.14159.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

// Exercise F.4 Solution: exF_04.cpp


// Defining a macro for computing the volume of a sphere.
#include <iostream>
using std::cout;
using std::fixed;
using std::showpoint;
#include <iomanip>
using std::setw;
using std::setprecision;
#define PI 3.14159 // constant representing Pi
// define macro for sphere volume
#define SPHEREVOLUME( r ) ( 4.0 / 3.0 * PI * ( r ) * ( r ) * ( r ) )
int main()
{
// print header
cout << setw( 10 ) << "Radius" << setw( 10 ) << "Volume\n";
cout << fixed << showpoint; // set output formats
// display volumes of spheres with radii 1-10
// using macro SPHEREVOLUME to calculate volumes
for ( int i = 1; i <= 10; i++ )
cout << setw( 10 ) << i << setw( 10 ) << setprecision( 3 )
<< SPHEREVOLUME( i ) << '\n';
return 0;
} // end main
Radius
1
2
3
4
5
6
7
8
9
10

F.5

Volume
4.189
33.510
113.097
268.082
523.598
904.778
1436.754
2144.659
3053.625
4188.787

Write a program that produces the following output:

The sum of x and y is 13

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Appendix F Preprocessor

The program should define macro SUM with two arguments, x and y, and use SUM to produce the output.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

// Exercise F.5 Solution: exF_05.cpp


// Defining macro to produce the sum of two values.
#include <iostream>
using std::cout;
using std::endl;
#define SUM( x, y ) ( ( x ) + ( y ) ) // macro to add two values
int main()
{
// display sum of x and y using macro SUM
cout << "The sum of x and y is " << SUM( 6, 7 ) << endl;
return 0;
} // end main

The sum of x and y is 13

F.6
Write a program that uses macro MINIMUM2 to determine the smaller of two numeric values.
Input the values from the keyboard.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

// Exercise F.6 Solution: exF_06.cpp


// Defining macro to determine the smaller of two numeric values.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::fixed;
using std::showpoint;
#include <iomanip>
using std::setprecision;
// macro to determine smallest of two values
#define MINIMUM2( X, Y ) ( ( X ) < ( Y ) ? ( X ) : ( Y ) )
int main()
{
int a;
int b;
double c;
double d;
// ask user for and store two integer values
cout << "Enter two integers: ";
cin >> a >> b;
// use macro MINIMUM to determine and display smallest integer entered

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
28
29
30
31
32
33
34
35
36
37
38
39
40

cout << "The minimum of " << a << " and " << b << " is "
<< MINIMUM2( a, b ) << "\n\n";
// ask user for and store two double values
cout << "Enter two doubles: ";
cin >> c >> d;
// use macro MINIMUM to determine and display smallest double entered
cout << fixed << showpoint;
cout << "The minimum of " << setprecision( 2 ) << c << " and " << d
<< " is " << MINIMUM2( c, d ) << '\n';
return 0;
} // end main

Enter two integers: 8 22


The minimum of 8 and 22 is 8
Enter two doubles: 73.46 22.22
The minimum of 73.46 and 22.22 is 22.22

F.7
Write a program that uses macro MINIMUM3 to determine the smallest of three numeric values. Macro MINIMUM3 should use macro MINIMUM2 defined in Exercise F.6 to determine the smallest
number. Input the values from the keyboard.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

// Exercise F.7 Solution: exF_07.cpp


// Using macros MINIMUM3 and MINIMUM2.
#include <iostream>
using std::cin;
using std::cout;
using std::fixed;
using std::showpoint;
#include <iomanip>
using std::setprecision;
// macro to determine smallest of two values
#define MINIMUM2( X, Y ) ( ( X ) < ( Y ) ? ( X ) : ( Y ) )
// macro that uses MINIMUM2 to determine smallest of three values
#define MINIMUM3( U, V, W ) ( MINIMUM2( W, MINIMUM2( U, V ) ) )
int main()
{
// integers used for comparison
int a;
int b;
int c;
// doubles used for comparison
double d;
double e;

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

8
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

Appendix F Preprocessor

double f;
// ask user for and store three integer values
cout << "Enter three integers: ";
cin >> a >> b >> c;
// use macro MINIMUM3 to determine smallest of three integers input
cout << "The minimum of " << a << ", " << b << ", and " << c
<< " is " << MINIMUM3( a, b, c ) << "\n\nEnter three doubles: ";
// store user input doubles
cin >> d >> e >> f;
// use macro MINIMUM3 to determine smallest of three doubles input
cout << fixed << showpoint;
cout << "The minimum of " << setprecision( 2 ) << d << ", "
<< e << ", and " << f << " is " << MINIMUM3( d, e, f ) << '\n';
return 0;
} // end main

Enter three integers: 44 2 55


The minimum of 44, 2, and 55 is 2
Enter three doubles: 9.5 7.3 3.22
The minimum of 9.50, 7.30, and 3.22 is 3.22

F.8

Write a program that uses macro PRINT to print a string value.


ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

// Exercise F.8 Solution: exF_08.cpp


// Using macro PRINT to print a string value.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#define PRINT( s ) cout << ( s ) // macro that prints its argument
#define SIZE 20 // size of string
int main()
{
char text[ SIZE ]; // create character array to hold user input string
PRINT( "Enter a string: " ); // ask user for and store string
cin >> text;
// use macro to output string entered by user
PRINT( "The string entered was: " );
PRINT( text );
PRINT( endl );
return 0;
} // end main

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions

Enter a string: HELLO


The string entered was: HELLO

F.9
Write a program that uses macro PRINTARRAY to print an array of integers. The macro
should receive the array and the number of elements in the array as arguments.
ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

// Exercise F.9 Solution: exF_09.cpp


// Using macro PRINTARRAY to print an array of integers.
#include <iostream>
using std::cout;
using std::endl;
#include <iomanip>
using std::setw;
// macro that prints an array of values
#define PRINTARRAY( A, N ) for ( int i = 0; i < ( N ); i++ ) \
cout << setw( 3 ) << A[ i ]
#define SIZE 10 // size of array
int main()
{
// declare and initialize array to be printed
int b[ SIZE ] = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
cout << "The array values are:\n";
PRINTARRAY( b, SIZE ); // print the array
cout << endl;
return 0;
} // end main

The array values are:


2 4 6 8 10 12 14 16 18 20

F.10 Write a program that uses macro SUMARRAY to sum the values in a numeric array. The macro
should receive the array and the number of elements in the array as arguments.
ANS:

1
2
3
4
5
6
7
8
9

// Exercise F.10 Solution: exF_10.cpp


// Using macro SUMARRAY to sum the values in a numeric array.
#include <iostream>
using std::cout;
using std::endl;
// macro that adds values of a numeric array
#define SUMMARRAY( A, S ) for ( int c = 0; c < S; c++ )
sum += A[ c ];

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

10
10
11
12
13
14
15
16
17
18
19
20
21
22

Appendix F Preprocessor

#define SIZE 10 // size of array


int main()
{
// declare and initialize array whose values will be added
int array[ SIZE ] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sum = 0; // sum of elements of array
// use macro SUMARRAY to add elements of array
SUMMARRAY( array, SIZE );
cout << "Sum is " << sum << endl;
return 0;
} // end main

Sum is 55

F.11

Rewrite the solutions to Exercise F.4 to Exercise F.10 as inline functions.


ANS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

// Exercise F.11 Solution: exF_11.cpp


// NOTE: Exercises F.9 and F.10 cannot be expanded inline because they
// require the use of for repetition statements.
#include <iostream>
using std::cout;
using std::endl;
using std::fixed;
using std::showpoint;
#include <iomanip>
using std::setw;
using std::setprecision;
#define PI 3.14159 // const representing main
#define SIZE 10
// function to calculate volume of a sphere
inline double sphereVolume( int r )
{
// calculate volume
return 4.0 / 3.0 * PI * ( r ) * ( r ) * ( r );
} // end function sphereVolume
// function to add two elements
inline int sum( int x, int y )
{
return x + y; // return sum of two integers
} // end function sum
// function to determine minimum of two integers
inline int minimum2( int x, int y )
{
return x < y ? x : y; // return smallest of two integers

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

} // end function minimum2


// function to determine minimum of three integers
inline int minimum3( int x, int y, int z )
{
return minimum2( z, minimum2( x, y ) ); // return smallest int
} // end function minimum3
// function to print a string
inline void print( char const * const cPtr )
{
cout << cPtr; // display string
} // end function print
// function to display array elements
inline void printArray( int a[], int size )
{
// display array elements
for ( int i = 0; i < size; i++ )
cout << setw( 3 ) << a[ i ];
} // end function printArray
// function to add elements of array
inline int sumArray( int a[], int size )
{
int sum = 0;
for ( int c = 0; c < size; c++ )
sum += a[ c ];
return sum; // return sum of elements
} // end function sumArray
int main()
{
// print header
cout << "Function sphereVolume as an inline function:\n"
<< setw( 10 ) << "Radius" << setw( 10 ) << "Volume\n";
cout << fixed << showpoint;
// calculate volumes of spheres using inline function sphereVolume
for ( int i = 1; i <= 10; i++ )
cout << setw( 10 ) << i << setw( 10 ) << setprecision( 3 )
<< sphereVolume( i ) << '\n';
int x = 6;
int y = 7;
// calculate sum of x and y using inline function sum
cout << "\nFunction sum as an inline function:\n"
<< "The sum of x and y is " << sum( x, y ) << '\n';
// determine minimum of x and y using inline function minimum2

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

11

12

Appendix F Preprocessor

88
cout << "\nFunction minimum2 as an inline function:\n"
89
<< "The minimum of " << x << " and " << y << " is "
90
<< minimum2( x, y ) << '\n';
91
92
int z = 4;
93
94
// determine minimum of x, y and z using inline function minimum3
95
cout << "\nFunction minimum3 as an inline function:\n"
96
<< "The minimum of " << x << ", " << y << " and " << z << " is "
97
<< minimum3( x, y, z ) << '\n';
98
99
// display string s using inline function print
100
char s[] = "string..."; // string to be printed
101
cout << "\nFunction print as an inline function:\n"
102
<< "The output of print is: ";
103
print( s );
104
cout << endl;
105
106
// array to display and add up elements
107
int b[ SIZE ] = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
108
cout << "\nThe array contains elements ";
109
printArray( b, SIZE ); // display elements of array
110
cout << endl;
111
cout << "\nThe sum of the elements in the array is " // sum elements
112
<< sumArray( b, SIZE ) << endl;
113
return 0;
114 } // end main

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.

Solutions

13

Function sphereVolume as an inline function:


Radius
Volume
1
4.189
2
33.510
3
113.097
4
268.082
5
523.598
6
904.778
7 1436.754
8 2144.659
9 3053.625
10 4188.787
Function sum as an inline function:
The sum of x and y is 13
Function minimum2 as an inline function:
The minimum of 6 and 7 is 6
Function minimum3 as an inline function:
The minimum of 6, 7 and 4 is 4
Function print as an inline function:
The output of print is: string...
The array contains elements

8 10 12 14 16 18 20

The sum of the elements in the array is 110

F.12 For each of the following macros, identify the possible problems (if any) when the preprocessor expands the macros:
a) #define SQR( x ) x * x

ANS: The macro arguments are not enclosed in parentheses in the replacement text. Errors

will occur, for instance, when an expression such as z /


z / y * z / y does not provide the square of z / y.

y are entered. The expression

b) #define SQR( x ) ( x * x )

ANS: Now the entire replacement text is placed in parentheses, but the individual argu-

ments are not. The same problem can occur as in the previous part.

c) #define SQR( x ) ( x ) * ( x )
ANS: When SQR( x ) is used in an expression

such as 12 / SQR( 2 ). There is no set of


parentheses around the entire replacement text, which results in 12 / ( 2 ) * ( 2 ), or
12, whereas the answer should be 12 / ( ( 2 ) * ( 2 ) ), or 3.

d) #define SQR( x ) ( ( x ) * ( x ) )

ANS: No problems.

2006 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved.