Figure 3-13
To undefine a symbol, you can use the #undef
preprocessor directive, like this:
#undef DEBUG
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
...
If you recompile the program now, the debugging statement will be omitted.
Another popular way of using the #define
preprocessor directive is to omit the definition of the symbol and inject it during compilation time. For example, if you remove the #define
preprocessor directive from the program, you can define it using the /define
compiler option:
1. In Visual Studio 2008 command prompt, compile the program using:
csc Program.cs /define:DEBUG
2. Run the program by issuing the command:
Program.exe
The output is identical to what you saw in Figure 3-13 — the debugging statement prints out the intermediate results.
If you now recompile the program by defining another symbol (other than DEBUG), you will realize that the debugging output does not appear (see Figure 3-14).
Figure 3-14
#if, #else, #elif, and #endif
As you saw in the preceding section, the #if
and #endif
preprocessor directives defines a block of code to include for compilation if a specified symbol is defined. You can also use the #else and #elif preprocessor directives to create compound conditional directives.
Using the previous example, you can add the #else
and #elif
preprocessor directives as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestDefine {
class Program {
static void Main(string[] args) {
Console.Write("Please enter a number: ");
int num = int.Parse(Console.ReadLine());
int sum = 0;
for (int i = 1; i <= num; i++) {
//---sum up all odd numbers---
if (i % 2 == 1) {
sum += i;
#if DEBUG
Console.WriteLine("i={0}, sum={1}", i, sum);
#elif NORMAL
Console.WriteLine("sum={0}", sum);
#else
Console.WriteLine(".");
#endif
}
}
Console.WriteLine(
"Sum of all odd numbers from 1 to {0} is {1}",
num, sum);
Console.ReadLine();
}
}
}
Figure 3-15 shows the different output when different symbols are defined. The top screen shows the output when the DEBUG symbol is defined. The middle screen shows the output when the NORMAL symbol is defined. The bottom screen shows the output when no symbol is defined.
Figure 3-15
The #if
preprocessor directive can also test for multiple conditions using the logical operators. Here are some examples:
#if (DEBUG || NORMAL) //---either DEBUG or NORMAL is defined---
#if (DEBUG && NORMAL) //---both DEBUG and NORMAL are defined---
#if (!DEBUG && NORMAL) //---DEBUG is not defined AND NORMAL is defined---
The #warning
preprocessor directive lets you generate a warning from a specific location of your code. The following example shows how you can use it to display warning messages during compilation time.
for (int i = 1; i <= num; i++) {
//---sum up all odd numbers---
if (i % 2 == 1) {
sum += i;
#if DEBUG
#warning Debugging mode is on
Console.WriteLine("i={0}, sum={1}", i, sum);
#elif NORMAL
#warning Normal mode is on
Console.WriteLine("sum={0}", sum);
#else
#warning Default mode is on
Console.WriteLine(".");
#endif
}
}
Figure 3-16 shows the output when the DEBUG
symbol is defined using the /define
compiler option.
Figure 3-16
The #error
preprocessor directive lets you generate an error. Consider the following example:
for (int i = 1; i <= num; i++) {
//---sum up all odd numbers---
if (i % 2 == 1) {
sum += i;
#if DEBUG
#warning Debugging mode is on
Console.WriteLine("i={0}, sum={1}", i, sum);
#elif NORMAL
#error This mode is obsolete.
Console.WriteLine("sum={0}", sum);
#else
#warning Default mode is on
Console.WriteLine(".");
#endif
}
}
Here, if the NORMAL
symbol is defined, an error message is shown and the statement defined within the conditional directive is ignored. Figure 3-17 shows that when you define the NORMAL
symbol, the error message is displayed and the compilation is aborted.
Figure 3-17
The #line
preprocessor directive lets you modify the compiler's line number and (optionally) the file name output for errors and warnings.
The #line
preprocessor directive is injected in the following example. The highlighted code indicates statements that will cause the debugger to issue warning messages:
1. using System;
2. using System.Collections.Generic;
3. using System.Linq;
4. using System.Text;
5.
6. namespace TestDefine
7. {
8. class Program
9. {
10. static void Main(string[] args)
11. {
12. #line 25
13. int i; //---treated as line 25---
14. char c; //---treated as line 26---
15. Console.WriteLine("Line 1"); //---treated as line 27---
16. #line hidden //---treated as line 28---
17. Console.WriteLine("Line 2"); //---treated as line 29---
18. Console.WriteLine("Line 3"); //---treated as line 30---
19. #line default
20. double d; //---treated as line 20---
21. Console.WriteLine("Line 4"); //---treated as line 21---
Читать дальше