home *** CD-ROM | disk | FTP | other *** search
- .NH
- Scope Rules: Who Knows About What
- .PP
- A complete C program need not be compiled all at once;
- the source text of the program may be kept in several files,
- and previously compiled routines may be loaded from libraries.
- How do we arrange that data gets passed from one
- routine to another?
- We have already seen how to use function arguments and values,
- so let us talk about external data.
- Warning: the words
- .ul
- declaration
- and
- .ul
- definition
- are used precisely in this section;
- don't treat them as the same thing.
- .PP
- A major shortcut exists for making
- .UL extern
- declarations.
- If the definition of a variable appears
- .ul
- before
- its use in some function,
- no
- .UL extern
- declaration is needed within the function.
- Thus, if a file contains
- .E1
- f1( ) { \*.\*.\*. }
- .SP
- int foo;
- .SP
- f2( ) { \*.\*.\*. foo = 1; \*.\*.\*. }
- .SP
- f3( ) { \*.\*.\*. if ( foo ) \*.\*.\*. }
- .E2
- no declaration of
- .UL foo
- is needed in either
- .UL f2
- or or
- .UL f3,
- because the external definition of
- .UL foo
- appears before them.
- But if
- .UL f1
- wants to use
- .UL foo,
- it has to contain the declaration
- .E1
- f1( ) {
- extern int foo;
- \*.\*.\*.
- }
- .E2
- .PP
- This is true also of any function that exists
- on another file _
- if it wants
- .UL foo
- it has to use an
- .UL extern
- declaration
- for it.
- (If somewhere there is an
- .UL extern
- declaration for something,
- there must also eventually be an external definition of it,
- or you'll get an ``undefined symbol'' message.)
- .PP
- There are some hidden pitfalls in external declarations
- and definitions if you use multiple source files.
- To avoid them,
- first,
- define and initialize each external variable only once in the entire set of files:
- .E1
- int foo 0;
- .E2
- You can get away with multiple external definitions on
- .UC UNIX,
- but not on
- .UC GCOS,
- so don't ask for trouble.
- Multiple initializations are illegal everywhere.
- Second,
- at the beginning of any file that contains functions needing a variable
- whose definition is in some other file,
- put in an
- .UL extern
- declaration,
- outside of any function:
- .E1
- extern int foo;
- .SP
- f1( ) { \*.\*.\*. }
- etc\*.
- .E2
- .PP
- The
- .UL #include
- compiler control line,
- to be discussed shortly,
- lets you make a single copy of the external declarations
- for a program and then stick them into each of the source files
- making up the program.
- .NH
- #define, #include
- .PP
- C provides a very limited macro facility.
- You can say
- .E1
- #define name something
- .E2
- and thereafter anywhere ``name'' appears as a token,
- ``something'' will be substituted.
- This is particularly useful in parametering the sizes of arrays:
- .E1
- #define ARRAYSIZE 100
- int arr[ARRAYSIZE];
- \*.\*.\*.
- while( i\*+ < ARRAYSIZE )\*.\*.\*.
- .E2
- (now we can alter the entire program by changing only the
- .UL define)
- or in setting up mysterious constants:
- .E1
- #define SET 01
- #define INTERRUPT 02 /\** interrupt bit \**/
- #define ENABLED 04
- \*.\*.\*.
- if( x & (SET | INTERRUPT | ENABLED) ) \*.\*.\*.
- .E2
- Now we have meaningful words instead of mysterious constants.
- (The mysterious operators `&' (AND)
- and `\(or' (OR)
- will be covered in the next section.)
- It's an excellent practice to write programs
- without any literal constants except in
- .UL #define
- statements.
- .PP
- There are several warnings about
- .UL #define\*.
- First, there's no semicolon at the end of a
- .UL #define;
- all the text from the name to the end of the line
- (except for comments)
- is taken to be the ``something''.
- When it's put into the text, blanks are placed around it.
- Good style typically makes the name in the
- .UL #define
- upper case _
- this makes parameters more visible.
- Definitions affect things only after they occur,
- and only within the file in which they occur.
- Defines can't be nested.
- Last, if there is a
- .UL #define
- in a file,
- then the first character of the file
- .ul
- must
- be a `#',
- to signal the preprocessor that definitions exist.
- .WS
- .PP
- The other control word known to C is
- .UL #include\*.
- To include one file in your source at compilation time, say
- .E1
- #include "filename"
- .E2
- This is useful for putting a lot of heavily used data definitions and
- .UL #define
- statements at the beginning of a file to be compiled.
- As with
- .UL #define,
- the first line of a file containing a
- .UL #include
- has to begin with a `#'.
- And
- .UL #include
- can't be nested _
- an included file can't contain another
- .UL #include\*.
-