UMBC CMSC201, Computer Science I, Fall 1994
Sections 0101, 0102 and Honors
Thursday November 3, 1994
Assigned Reading: 9.2 - 9.3
Handouts (available on-line): none
Topics Covered:
- We are running a bit behind the posted syllabus. We
will continue developing our random number library. We want
to allow our client to set the range of numbers that
GetRandomNumber() would produce. Instead of passing,
extra parameters to GetRandomNumber() we will use
a new feature of C called global variables. We traced
through a program that
illustrates the lexical scoping of global and local variables
in C.
- Then we wrote a new version of our
program which has a SetRandomRange function.
The output of the program is
still the same as the previous version.
- We broke up our program into three pieces:
the header file,
the implementation of
the functions, and the main
program. These programs can be compiled separately, and
we can put the implemented functions in a library.
See sample run.
- It turns out that the rand() function that we
used is not very good, because the lower digits of the
generated numbers are predictable. Since we used the
modulo operator to reduce the range of the random number,
this means the random numbers we generated may be quite
predictable. Again, we consulted the
manual pages of a different
random number generator. According to the manual the
random() function produces numbers where every digit
appears to be random.
- We incorporated the random() and srandom()
functions into a new
implementation of our random number library. This new
library can be linked to our main program without changing or
recompiling the main program because the interface between
these two parts remains the same. (See
sample run.)
- We moved on to explain what the preprocessor directive
#ifndef
really means. We looked at a
program where the
constant MARKER was defined; and a
program where the
constant was not defined. The compiled programs run differently,
but it is important to note that in each case the C preprocessor
stripped a printf statement from the file before passing
the file to the C compiler.
- The purpose of the C preprocessor is to take care of the
preprocessor directives, such as
#include, #define and #ifndef,
before the "real" C compiler looks at the file. The preprocessor
usually strips the comments from the source file and replaces
every occurrence of the constants with their definitions.
We looked at a sample program
and the output from the
preprocessor.
- We also looked at what happens when a
program includes a
header file.
The output from the preprocessor
has a copy of the header file in the middle of the main program.
- In our second example,
the main program includes both the header.h file and
a second header file.
The second header file also includes header.h, so the
output from the preprocessor
contains two copies of header.h. This is bad because
the global variable global_variable is initialized twice,
which would result in a syntax error.
- The solution to this problem is to realize that we can
use the #ifndef directive to make sure that the
same header file we not be given to the C compiler twice.
The C preprocessor will remove one of the copies.
For example, in this program
the constant MARKER is defined, so the first printf
statement is not part of the
output from the preprocessor.
In the second program, the
constant MARKER is not defined, so the second printf
statement is not part of the
output from the preprocessor.
- Thus, we can write the new header files:
new_header.h and
new_header2.h.
When new_header.h is read the first time, the constant
_new_header_h is not defined, so all of the file is
included. Also, the constant _new_header_h is defined when
the file
new_header.h is read the first time. If new_header.h
is included a second time, the constant _new_header_h would be
defined, so the body of the file would be stripped by the #ifndef
directive. As a result, when we give our new
main program to the C
preprocessor, the output from
the preprocessor only has one copy of the body of
new_header.h.
Last Modified: September 7, 1994
Richard Chang, chang@gl.umbc.edu