
                       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 lines 2 through  5
        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.   Note
        that  if  the string is found in a string constant or  in  a
        comment, it will not be changed.

            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 "START", it would be a  completely  different
        matter.  If you wanted to change all of the "START"s 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.


                                  Page 41









                       Chapter 6 - Defines and Macros


        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.   In  most C compilers, the EOF is defined  in  the
        STDIO.H file.  You can observe this for yourself by  listing
        this file.

                              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 line 4 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 13 of the program is  reached,
        "index" will be substituted for every "A", and "count"  will
        be substituted for every "B".  Once again, it must be stated
        that  string  constants and comments will not  be  affected.
        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 second
        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


                                  Page 42









                       Chapter 6 - Defines and Macros


        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.

             In line 5 we define "ADD_WRONG" according to the  above
        rules  but  we still have a problem when we try to  use  the
        macro in line 23 and 24.  In line 24 when we say we want the
        program  to calculate 5*ADD_WRONG(i) with i = 1, we get  the
        result  5*1 + 1 which evaluates to 5 + 1 or 6, and  this  is
        most  assuredly not what we had in mind.  We  really  wanted
        the result to be 5*(1 + 1) = 5*2 = 10 which is the answer we
        get  when we use the macro named "ADD_RIGHT(i)",  because of
        the extra parentheses in the definition given in line 6.   A
        lttle time spent studying the program and the result will be
        worth your effort in understanding how to use macro's.

             In   order   to  prevent  the  above   problems,   most
        experienced  C programmers include parentheses  around  each
        variable  in a macro and additional parentheses  around  the
        entire expression.

             The remainder of the program is simple and will be left
        to your inspection and understanding.

                      WHAT IS AN ENUMERATION VARIABLE?

             Load  and  display  the program  named  ENUM.C  for  an
        example  of  how to use the "enum" type  variable.   Line  4
        contains the first "enum" type variable named "result" which
        is a variable which can take on any of the values  contained
        within  the parentheses.  Actually the variable "result"  is
        an "int" type variable but can be assigned any of the values
        defined for it.  The names within the parentheses are  "int"
        type  constants and can be used anywhere it is legal to  use
        an "int" type constant.  The constant "win" is assigned  the
        vallue of 0, "tie" the value 1, "bye" the value 2, etc.

             In  use,  the variable "result" is used just  like  any
        "int"  variable would be used as can be seen by its  use  in
        the program.  The "enum" type of variable is intended to  be
        used  by you, the programmer, as a coding aid since you  can
        use  a  constant named "mon" for control  structures  rather
        than  the meaningless (at least to you) value of 1.   Notice
        that  "days" is assigned the values of days of the  week  in
        the remainder of the program.  If you were to use a "switch"
        statement,  it  would  be much more meaningful  to  use  the
        labels "sun", "mon", etc, rather than the more awkward 0, 1,
        2, etc.


                                  Page 43









                       Chapter 6 - Defines and Macros




        PROGRAMMING EXERCISES

        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.

        2.   Add some printf statements in MACRO.C to see the result
             of the erroneous and correct addition macros.










































                                  Page 44
