C Tutor chapter 6
Chapter 6 - Defines and Macros
DEFINES AND MACROS ARE AIDS TO CLEAR PROGRAMMING
Load and display the file named DEFINE.C for your first
look at some defines and macros. Notice the first four
lines of the program each starting with the word "#define".
This is the way all defines and macros are defined. Before
the actual compilation starts, the compiler goes through a
preprocessor pass to resolve all of the defines. In the
present case, it will find every place in the program where
the combination "START" is found and it will simply replace
it with the 0 since that is the definition. The compiler
itself will never see the word "START", so as far as the
compiler is concerned, the zeros were always there. It
should be clear to you by now that putting the word "START"
in your program instead of the numeral 0 is only a
convenience to you and actually acts like a comment since
the word "START" helps you to understand what the zero is
used for.
In the case of a very small program, such as that
before you, it doesn't really matter what you use. If,
however, you had a 2000 line program before you with 27
references to the START, it would be a completely different
matter. If you wanted to change all of the STARTs in the
program to a new number, it would be simple to change the
one #define, but difficult to find and change all of the
references to it manually, and possibly disastrous if you
missed one or two of the references.
In the same manner, the preprocessor will find all
occurrences of the word "ENDING" and change them to 9, then
the compiler will operate on the changed file with no
knowledge that "ENDING" ever existed.
It is a fairly common practice in C programming to use
all capital letters for a symbolic constant such as "START"
and "ENDING" and use all lower case letters for variable
names. You can use any method you choose since it is mostly
a matter of personal taste.
IS THIS REALLY USEFUL?
When we get to the chapters discussing input and
output, we will need an indicator to tell us when we reach
the end-of-file of an input file. Since different compilers
use different numerical values for this, although most use
either a zero or a minus 1, we will write the program with a
"define" to define the EOF used by our particular compiler.
If at some later date, we change to a new compiler, it is a
simple matter to change this one "define" to fix the entire
program. End-of-line is another indicator that is not
Page 39
Chapter 6 - Defines and Macros
universal. This will make more sense when we get to the
chapters on input and output.
WHAT IS A MACRO?
A macro is nothing more than another define, but since
it is capable of at least appearing to perform some logical
decisions or some math functions, it has a unique name.
Consider the third line of the program on your screen for an
example of a macro. In this case, anytime the preprocessor
finds the word "MAX" followed by a group in parentheses, it
expects to find two terms in the parentheses and will do a
replacement of the terms into the second definition. Thus
the first term will replace every "A" in the second
definition and the second term will replace every "B" in the
second definition. When line 12 of the program is reached,
"index" will be substituted for every "A", and "count" will
be substituted for every "B". Remembering the cryptic
construct we studied a couple of chapters ago will reveal
that "mx" will receive the maximum value of "index" or
"count". In like manner, the "MIN" macro will result in
"mn" receiving the minimum value of "index" or "count". The
results are then printed out. There are a lot of seemingly
extra parentheses in the macro definition but they are not
extra, they are essential. We will discuss the extra
parentheses in our next program.
Compile and run DEFINE.C.
LETS LOOK AT A WRONG MACRO
Load the file named MACRO.C and display it on your
screen for a better look at a macro and its use. The first
line defines a macro named "WRONG" that appears to get the
cube of "A", and indeed it does in some cases, but it fails
miserably in others. The second macro named "CUBE" actually
does get the cube in all cases.
Consider the program itself where the CUBE of i+offset
is calculated. If i is 1, which it is the first time
through, then we will be looking for the cube of 1+5 = 6,
which will result in 216. When using "CUBE", we group the
values like this, (1+5)*(1+5)*(1+5) = 6*6*6 = 216. However,
when we use WRONG, we group them as 1+5*1+5*1+5 = 1+5+5+5 =
16 which is a wrong answer. The parentheses are therefore
required to properly group the variables together. It
should be clear to you that either "CUBE" or "WRONG" would
arrive at a correct answer for a single term replacement
such as we did in the last program. The correct values of
the cube and the square of the numbers are printed out as
well as the wrong values for your inspection.
Page 40
Chapter 6 - Defines and Macros
The remainder of the program is simple and will be left
to your inspection and understanding.
PROGRAMMING EXERCISE
1. Write a program to count from 7 to -5 by counting down.
Use #define statements to define the limits. (Hint, you
will need to use a decrementing variable in the third
part of the "for" loop control.
Page 41
DEFINES AND MACROS ARE AIDS TO CLEAR PROGRAMMING
Load and display the file named DEFINE.C for your first
look at some defines and macros. Notice the first four
lines of the program each starting with the word "#define".
This is the way all defines and macros are defined. Before
the actual compilation starts, the compiler goes through a
preprocessor pass to resolve all of the defines. In the
present case, it will find every place in the program where
the combination "START" is found and it will simply replace
it with the 0 since that is the definition. The compiler
itself will never see the word "START", so as far as the
compiler is concerned, the zeros were always there. It
should be clear to you by now that putting the word "START"
in your program instead of the numeral 0 is only a
convenience to you and actually acts like a comment since
the word "START" helps you to understand what the zero is
used for.
In the case of a very small program, such as that
before you, it doesn't really matter what you use. If,
however, you had a 2000 line program before you with 27
references to the START, it would be a completely different
matter. If you wanted to change all of the STARTs in the
program to a new number, it would be simple to change the
one #define, but difficult to find and change all of the
references to it manually, and possibly disastrous if you
missed one or two of the references.
In the same manner, the preprocessor will find all
occurrences of the word "ENDING" and change them to 9, then
the compiler will operate on the changed file with no
knowledge that "ENDING" ever existed.
It is a fairly common practice in C programming to use
all capital letters for a symbolic constant such as "START"
and "ENDING" and use all lower case letters for variable
names. You can use any method you choose since it is mostly
a matter of personal taste.
IS THIS REALLY USEFUL?
When we get to the chapters discussing input and
output, we will need an indicator to tell us when we reach
the end-of-file of an input file. Since different compilers
use different numerical values for this, although most use
either a zero or a minus 1, we will write the program with a
"define" to define the EOF used by our particular compiler.
If at some later date, we change to a new compiler, it is a
simple matter to change this one "define" to fix the entire
program. End-of-line is another indicator that is not
Page 39
Chapter 6 - Defines and Macros
universal. This will make more sense when we get to the
chapters on input and output.
WHAT IS A MACRO?
A macro is nothing more than another define, but since
it is capable of at least appearing to perform some logical
decisions or some math functions, it has a unique name.
Consider the third line of the program on your screen for an
example of a macro. In this case, anytime the preprocessor
finds the word "MAX" followed by a group in parentheses, it
expects to find two terms in the parentheses and will do a
replacement of the terms into the second definition. Thus
the first term will replace every "A" in the second
definition and the second term will replace every "B" in the
second definition. When line 12 of the program is reached,
"index" will be substituted for every "A", and "count" will
be substituted for every "B". Remembering the cryptic
construct we studied a couple of chapters ago will reveal
that "mx" will receive the maximum value of "index" or
"count". In like manner, the "MIN" macro will result in
"mn" receiving the minimum value of "index" or "count". The
results are then printed out. There are a lot of seemingly
extra parentheses in the macro definition but they are not
extra, they are essential. We will discuss the extra
parentheses in our next program.
Compile and run DEFINE.C.
LETS LOOK AT A WRONG MACRO
Load the file named MACRO.C and display it on your
screen for a better look at a macro and its use. The first
line defines a macro named "WRONG" that appears to get the
cube of "A", and indeed it does in some cases, but it fails
miserably in others. The second macro named "CUBE" actually
does get the cube in all cases.
Consider the program itself where the CUBE of i+offset
is calculated. If i is 1, which it is the first time
through, then we will be looking for the cube of 1+5 = 6,
which will result in 216. When using "CUBE", we group the
values like this, (1+5)*(1+5)*(1+5) = 6*6*6 = 216. However,
when we use WRONG, we group them as 1+5*1+5*1+5 = 1+5+5+5 =
16 which is a wrong answer. The parentheses are therefore
required to properly group the variables together. It
should be clear to you that either "CUBE" or "WRONG" would
arrive at a correct answer for a single term replacement
such as we did in the last program. The correct values of
the cube and the square of the numbers are printed out as
well as the wrong values for your inspection.
Page 40
Chapter 6 - Defines and Macros
The remainder of the program is simple and will be left
to your inspection and understanding.
PROGRAMMING EXERCISE
1. Write a program to count from 7 to -5 by counting down.
Use #define statements to define the limits. (Hint, you
will need to use a decrementing variable in the third
part of the "for" loop control.
Page 41
Comments
Post a Comment