Using #define

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.

Using #define for Constants

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.

Using #define for Tests

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.

The #else Precompiler Command

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.

Listing 21.1. Using #define
 0:  #define DemoVersion
 1:  #define DOS_VERSION 5
 2:  #include <iostream>
 3:
 4:  int main()
 5:  {
 6:      std::cout << "Checking on the definitions of DemoVersion,"
 7:          << "DOS_VERSION and WINDOWS_VERSION...
";
 8:
 9:  #ifdef DemoVersion
10:      std::cout << "DemoVersion defined.
";
11:  #else // DemoVersion
12:      std::cout << "DemoVersion not defined.
";
13:  #endif // DemoVersion
14:
15:  #ifndef DOS_VERSION
16:      std::cout << "DOS_VERSION not defined!
";
17:  #else // DOS_VERSION
18:      std::cout << "DOS_VERSION defined as: "
19:          << DOS_VERSION << std::endl;
20:  #endif // DOS_VERSION
21:
22:  #ifdef WINDOWS_VERSION
23:      std::cout << "WINDOWS_VERSION defined!
";
24:  #else // WINDOWS_VERSION
25:      std::cout << "WINDOWS_VERSION was not defined.
";
26:  #endif // WINDOWS_VERSION
27:
28:      std::cout << "Done.
";
29:      return 0;
30:  }


Checking on the definitions of DemoVersion, DOS_VERSION and WINDOWS_VERSION...
DemoVersion defined
DOS_VERSION defined as: 5
WINDOWS_VERSION was not defined.
Done.
						

On lines 0 and 1, DemoVersion and DOS_VERSION are defined, with DOS_VERSION defined with the string 5. On line 9, the existence of DemoVersion is tested by the precompiler, and because DemoVersion is defined, albeit with no value, the test is true and the string on line 10 is printed.


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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.204.201