The #define command defines a string substitution. If you write |
#define BIG 512
you have instructed the precompiler to substitute the string 512 wherever it sees the string BIG. But this is not a string in the C++ sense. The characters 512 are substituted in your source code wherever the token BIG is seen. A token is a string of characters that can be used wherever a string or constant or other set of letters might be used. Therefore, if you write
#define BIG 512 int myArray[BIG];
the intermediate file produced by the precompiler will look like this:
int myArray[512];
Note that the #define statement is gone. Precompiler statements are all removed from the intermediate file; they do not appear in the final source code at all.
One way to use #define is as a substitute for constants. This is almost never a good idea, however, because #define merely makes a string substitution and does no type checking. There are tremendous advantages to using the const keyword rather than #define.
A second way to use #define is simply to declare that a particular character string is defined. Therefore, you could write
#define BIG
Later, you can test whether BIG has been defined and take action accordingly. The precompiler commands to test whether a string has been defined are #ifdef (to see whether the string has been defined) and #ifndef (to test whether it has not been defined). Both of these must be followed by the command #endif before the block ends (before the next closing brace).
#ifdef evaluates to true if the string it tests has been defined already. Therefore, you can write this:
#ifdef DEBUG cout << "Debug defined"; #endif
When the precompiler reads the #ifdef, it checks a table it has built to see if you've defined DEBUG. If so, the #ifdef evaluates to true, and everything to the next #else or #endif is written into the intermediate file for compiling. If it evaluates to false, nothing between #ifdef DEBUG and the next #else or #endif will be written into the intermediate file; it will be as if it was never in the source code in the first place.
Note that #ifndef is the logical reverse of #ifdef. #ifndef evaluates to true if the string has not been defined up to that point in the file.
As you might imagine, the term #else can be inserted between either #ifdef or #ifndef and the closing #endif. Listing 21.1 illustrates how all these terms are used.
Checking on the definitions of DemoVersion, DOS_VERSION and WINDOWS_VERSION... DemoVersion defined DOS_VERSION defined as: 5 WINDOWS_VERSION was not defined. Done.
Line 15 tests DOS_VERSION to see if it is not defined.
Because DOS_VERSION is defined, this test fails and line 18 is compiled, rather than line 16. Here the string 5 is substituted for the word DOS_VERSION, and this is seen by the compiler as
cout << "DOS_VERSION defined as: " << 5 << endl;
Note that the first word, DOS_VERSION, is not substituted because it is in a quoted string. The second DOS_VERSION is substituted. This causes the compiler to see 5, as if you had typed 5 there.
Finally, on line 22, the precompiler tests for WINDOWS_VERSION. Because you did not define WINDOWS_VERSION, the test fails and line 25 is compiled rather than line 23.
3.145.204.201