These macros are for conditional compilation. In general, all lines in the source program are compiled. However, sometimes it is desirable to compile a part of the content only if certain conditions are met, that is, to specify the conditions for the compilation of some content, which is "conditional compilation". Sometimes, you want to compile a set of statements when a condition is met, and then compile another set of statements when the condition is not met.
The most common form of conditional compilation commands is:
#ifdef identifiers
Procedure Section 1
#else
Procedure Section 2
#endif
It does this: when the identifier is already defined (typically defined with the # define command), the program Segment 1 is compiled, or the program fragment 2 is compiled.
The #else part can also be not, namely:
#ifdef
Procedure Section 1
#denif
The "program segment" Here can be a statement group, or it can be a command line. This kind of conditional compilation can improve the generality of C source program. If a C source program is running on a different computer system, there are some differences between the different computers. For example, we have a data type that should be represented in the Windows platform using the long type, whereas float is used on other platforms, which often requires the necessary modifications to the source program, which reduces the generality of the program. Can be compiled with the following conditions:
#ifdef WINDOWS
#define MYTYPE Long
#else
#define MYTYPE Float
#endif
If you are compiling a program on Windows, you can add it at the beginning of the program
#define WINDOWS
This compiles the following command line:
#define MYTYPE Long
If the following command line appears before this set of conditional compilation commands:
#define WINDOWS 0
The MyType in the pre-compiled program are replaced with float. In this way, the source program can be used for different types of computer systems without having to make any modifications. Of course, the above introduction is only a simple situation, can be based on this idea to design other conditional compilation.
For example, when you are debugging a program, you often want to output some of the required information, and no longer output it when debugging is complete. You can insert the following conditional compilation segments in the source program:
#ifdef DEBUG
Print ("Device_open (%p) \ n", file);
#endif
If you have the following command line in front of it:
#define DEBUG
The value of the file pointer is output when the program runs to debug the analysis. Simply remove the Define command line after debugging. Some people may feel that without conditional compilation can also achieve this purpose, that is, in debugging, add a batch of printf statements, after debugging one after the printf statement deleted. Indeed, this is possible. However, when you add more than one printf statement when debugging, the amount of work that is modified is significant. With conditional compilation, you do not have to one by one to revise the printf statement, just delete the previous "#define DEBUG" command, then all the conditional compilation with DEBUG identifier to make the printf statement does not work, that is, the role of unified control, like a "switch".
It is sometimes used in the following form:
#ifndef identifiers
Procedure Section 1
#else
Procedure Section 2
#endif
Just the first line is different from the first: Change "ifdef" to "ifndef". Its function is: If the identifier is not defined, compile the program segment 1, or compile the program segment 2. This form is contrary to the effect of the first form.
The above two forms of use are similar, depending on the need to choose one, depending on the convenience.
There is also a form of an expression that is followed by # If, not a simple identifier:
#if an expression
Procedure Section 1
#else
Procedure Section 2
#endif
It does this by compiling program segment 1 when the specified expression value is true (not 0), or by compiling program segment 2. A certain condition can be given beforehand to enable the program to perform different functions under different conditions.
For example: Enter a line of alphabetic characters, set conditional compilation as needed, to make the letters all uppercase, or all lowercase.
#define LETTER 1
Main ()
{
Char str[20]= "C Language", C;
int i= "0";
while ((C=str[i])! = ' + ') {
i++;
#if Letter
if (c>= ' a ' &&c<= ' z ') c= "c-32";
#else
if (c>= ' A ' &&c<= ' Z ') c= "C" +32;
#endif
printf ("%c", c);
}
}
The result of the operation is: C LANGUAGE
Now define letter 1, so that when the preprocessing condition compiles the command, because letter is true (not 0), the first if statement is compiled, and the run-time causes lowercase letters to be capitalized. If you change the first line of the program to:
#define LETTER 0
When preprocessing, the second if statement is compiled to make uppercase letters lowercase (uppercase letters with the corresponding lowercase ASCII code difference of 32). At this point the operation is:
C language
Some people will ask: without conditional compilation command and directly with the IF statement can also meet the requirements of the conditional compilation command What is the advantage? It is true that this problem can be handled completely without conditional compilation, but the target program is long (because all statements are compiled), and conditional compilation reduces the length of the target by reducing the compiled statement. When the conditional compilation segment is relatively long, the length of the target program can be greatly reduced.
On the magical application of #ifdef in software development
The author is engaged in the development and maintenance of an application software in the UNIX environment, the users are distributed throughout the country, the basic functions required by each user are the same, but in some functions to change with the demand, and constantly upgrade, to realize the upgrade of users throughout the country is very difficult, And we just use e-mail to send patches to the user, these patches are in a set of software based on continuous modification and expansion of the written, and by different logo files into different modules, although the program volume is expanding, but does not affect the functionality of old users, which is mainly due to the C program's # ifdef/#else/#endif的作用.
We mainly use the following methods, assuming that we have defined #ifdef Debug and #ifdef TEST in the program header:
1. Use the #ifdef/#endif将某程序功能模块包括进去 to provide this functionality to a user.
In the program header definition #ifdef HNLD:
#ifdef HNLD
Include "N166_HN.C"
#endif
If you are not allowed to provide this functionality to other users, add a hnld to the header before compiling.
2. Precede each sub-program with a tag to track the operation of the program.
#ifdef DEBUG
printf ("Now's in Hunan!");
#endif
3. Avoid hardware limitations. Sometimes some specific application environment hardware is different, but limited to the condition, the local lack of such equipment, and then bypass the hardware, directly write the expected results. The specific approach is:
#ifndef TEST
I=dial ();
Program debugging run-time bypass this statement
#else
i=0;
#endif
After debugging passes, the definition of test is masked and recompiled, which can be sent to the user for use.
# ifdef #ifndef and other usage (turn)
The #ifndef of the first piece, this is a very important thing. For example, you have two C files, and these two C files include the same header file. At compile time, these two C files are compiled into a running file together, so the problem comes with a lot of conflicting statements.
or the contents of the head file in #ifndef and #endif. Regardless of whether your header file will be referenced by multiple files, you should add this. The general format is this:
#ifndef < identity >
#define < identity >
......
......
#endif
< identity > can theoretically be freely named, but the "identity" of each header file should be unique. The naming convention for an identity is usually the header file name all uppercase, underlined, and the "." in the file name. Also becomes underlined, such as: stdio.h
#ifndef _stdio_h_
#define _stdio_h_
......
#endif
2. Define the problem of variables in #ifndef (generally not defined in #ifndef).
#ifndef AAA
#define AAA
...
int i;
...
#endif
There's a variable definition inside.
When I link in VC, I repeat the error of definition, and compile successfully in C.
Conclusion:
(1). When you first use the. cpp file for this header to generate. obj, int i defines the inside when another one uses this. cpp again [separately] generates. obj, int i is also defined and then two obj by another. CPP is included in this head, are concatenated together, duplicate definitions will appear.
(2). After changing the source program file extension to. c, the VC compiles the source program according to the C language syntax instead of C + +. In C, if you encounter more than one int I, you automatically think that one is a definition and the other is a declaration.
(3). C and C + + language connection results are different, it is possible (guess) that when compiling, the C + + language will be the global
The variable is strongly signed by default, so there is a connection error. C language is based on whether or not the initial strength of the judgment. Reference
Workaround:
(1). Change the source program file extension to. c.
(2). Recommended Solution:
only extern int i is declared in. h; defined in. cpp
<x.h>
#ifndef __x_h__
#define __x_h__
extern int i;
#endif//__x_h__
<x.c>
int i;
Note the problem:
(1). Variables are generally not defined in the. h file.
Reproduced
The refinement of conditional compilation #ifdef