The so-called pretreatment refers to the work procedure before the first pass scan (lexical scanning and grammar analysis) is performed. Prerequisites are an important feature of C language that is done by the pre-processing program. When compiling a source file, the system will automatically reference the preprocessor to the pre-process part of the source program, and the processing is automatically entered into the source program.
The C language provides a variety of preprocessing functions, such as macro definitions, files, conditional compilation, and more. Programs prepared reasonably using programs to read, modify, transplant, and debugging, and also benefit modular programming. This chapter introduces several common pretreatment features.
Macro definition
One identifier is allowed to represent a string in the C language source program, called "macro". The identifier defined as "macro" is called "macro name". When compiling pretreatment, all the "macro names" that appear in the program are replaced by the string in the macro definition, which is called "macro replacement" or "macro".
Macro definition is done by the macro definition command in the source program. The macro change is automated by the pre-processing program. In the C language, "macro" is divided into parameters and no parameters. The definitions and calls of these two "macros are discussed below.
No unfair macro
There is no parameters after the macro name without enhancement. The general form of its definition is: #define identifier string "#" indicates that this is a preprocessing command. Everyone starts with "#" is the pretreatment command. "Define" is a macro definition command. "Identifier" is the macro name defined. "String" can be constant, expressions, formatters, etc. The definition of symbol constant described above is a no-array-free definition. In addition, the expression that repeatedly used in the program is often macro definition. For example: # define m (Y * Y 3 * Y) Defines the M expression (Y * Y 3 * Y). When writing the source program, all (Y * Y 3 * Y) can be replaced by M, while the source program is compiled, the pre-processing program will be made by the pre-processing program, ie (Y * Y 3 * Y) Expression to replace all macro name M and then compile.
#define m (Y * Y 3 * Y)
MAIN () {
Int S, Y;
Printf ("INPUT A NUMBER:");
Scanf ("% d", & y);
S = 3 * m 4 * m 5 * m;
Printf ("s =% d / n", s);
}
The macro definition is first performed in the above case, define the M expression (Y * Y 3 * Y), in S = 3 * m 4 * m 5 * m for macro call. After pretreatment, the statement becomes: s = 3 * (Y * Y 3 * Y) 4 (Y * Y 3 * Y) 5 (Y * Y 3 * Y); It should be noted that the brackets in the macro definition (Y * Y 3 * Y) cannot be less. Otherwise an error will occur.
After the following definition: #difine M Y * Y 3 * Y will get the following statement: s = 3 * y * y 3 * Y 4 * Y * Y 3 * Y 5 * Y * Y 3 * Y; this is equivalent to; 3Y2 3y 4Y2 3y 5y2 3y; obviously does not match the original question. The calculation result is of course wrong. Therefore, you must pay attention when making a macro definition. There should be no errors after the macro change. For macro definitions, the following points are also described:
1. Macro definition is to indicate a string with a macro name, replacing the macro name at the macro show, which is just a simple substitution, and the string can contain any characters, which can be constant, or It is an expression that the pre-processing program does not check it. If there is an error, it can only be found when compiling the source program that has been opened by the macro.
2. Macro definition is not an explanation or statement, do not have a semicolon at the end of the row, such as plus semicolons, even replacement together.
3. Macro definition must be written outside of the function, and its scope functions as the macro definition command to the source program end. To terminate its scope, you can use # undef commands, for example: # define pi 3.14159main ()
{
......
}
# UNDEF PIPI's scope
F1 ()
.... Indicates that PI is only valid in the main function, which is invalid in F1.
4. Macro name In the source program, if the quotation is enclosed, the pre-processing program does not make a macro change.
#define ok 100
Main ()
{
Printf ("ok");
Printf ("/ n");
}
The macro name OK representation 100 is defined in the above example, but in the printf statement, it is enclosed in the quotation, so it does not make a macro change. The result of the program is: OK This means that "OK" is handled as a string.
5. Macro definition allows nested, which can be used in the macro defined string. Switched by the pretreatment program layer by the macro show. For example: #define pi 3.1415926
#define s pi * y * Y / * Pi is a defined macro name * / 对 statement: Printf ("% f", s); in the macro change becomes: Printf ("% f", 3.1415926 * y * Y);
6. The habit is expressed in uppercase letters in order to distinguish between variables. However, lowercase letters are also allowed.
7. The macro definition indicates the data type and makes the writing easily. For example: #define STU STRUCT STU Available in the program: STU Body [5], * P; #define integer int in the program to use Integer to make an integer variable description: Integer A, B; should pay attention to use macro Define the difference between the data type and define the data specifier with typedef. Macro definition is just a simple character string replacement, which is done in preprocessing, and TypeDef is processed at compile, it is not a simple substitution, but rename the type specifier. The named identifier has the function of type definition description. Please see the example below: #DEfine Pin1 INT * TYPEDEF (int *) PIN2; seeing these two in the form, but in actual use. When the variable is used in PIN1, PIN2 can be seen when the variables can be seen: PIN1 A, B; turn into int * a, b after macro generation; representing A means a pointer variable to the integer, and B is integer variable . : PIN2 A, B; represents A, B are all pointer variables to integer. Because Pin2 is a type of specifier. As can be seen from this example, although the macro definition can also represent the data type, it is made by characters after all.
Change. Be careful in use to avoid errors.
8. Make the "Output Format" macro definition, you can reduce writing trouble. This method is used in Example 9.3.
#define p printf
#define D "% D / N"
#define f "% f / N"
MAIN () {
INT A = 5, C = 8, E = 11;
Float B = 3.8, D = 9.7, f = 21.08;
P (d f, a, b);
P (d f, c, d);
P (d f, e, f);
}
With macro
C language allows macros with parameters. The parameters in the macro definition are called the formal parameters, and the parameters in the macro call are called actual parameters. Macro with parameters, in the call, not only the macro is displayed, but also use the active parameters to change the shape.
A general form of a macro definition is: #define macro name (Distake) string contains individual ginseng in the string. General forms with ginseng macro calls are: macro name (real parametric table);
E.g:
#define m (y) Y * Y 3 * Y / * macro definition * /
:
K = m (5); / * macro adjustment * /
: When the macro is called, use the real parameters 5 to replace the shape Y, the statement after the pre-processed macro
To: k = 5 * 5 3 * 5
#DEFINE MAX (A, B) (a> b)? A: B
MAIN () {
INT X, Y, MAX;
Printf ("INPUT TWO NUMBERS:");
Scanf ("% D% D", & x, & y);
MAX = max (x, y);
Printf ("max =% D / N", max);
}
The first line of the above program is defined by the envelope macro, with a macro name MAX indicates conditional expression (A> B)? A: B, the methano A, B appear in the conditional expression. Procedure seventh row Max = max (x,
Y) For macro, real parameters x, y, will be changed to the shapes A, B. After the macro show this statement is: max = (x> y) x: y; used to calculate the large number of x, y. There is a problem with the macro definition with the parameters, it is necessary to explain:
1. In the belt macro definition, there is no space between the macro name and the mediated reference.
For example, #define max (a, b) (a> b)? A: B is written as: #define max (a, b) (A> b)? A: B will be considered a macro definition, macro Name Max represents strings (A, B) (a> b)? A: B.
Macro show, macro call statement: max = max (x, y); becomes: max = (a, b) (a> b)? A: B (x, y); this is obviously wrong.
2. In the belt macro definition, the formal parameters do not assign the memory cell, so it is not necessary to define the type. In the macro, the real value is specifically valued. To use them to change the resort, therefore must be described. This is different from the situation in the function. In the function, the meticulum and the argument are two different amounts, each has their own scope, and the real gate value is given to the intersection, and "value delivery" is performed. And in the belt macro, it is just a symbolic change, there is no problem that the value is transmitted.
3. The shape parameter is an identifier in the macro definition, and the real parameters in the macro call can be an expression.
#define sq (y) * (y)
MAIN () {
INT A, SQ;
Printf ("INPUT A NUMBER:");
Scanf ("% d", & a);
SQ = SQ (A 1);
Printf ("SQ =% D / N", SQ);
}
The first behavior macro defined in the above example is Y. The seventh row macro modulus is a 1, which is an expression. When the macro shows, use A 1 to change Y, then use (Y) * (y) to change SQ, get the following statement: sq = (A 1) * (A 1); this is different from the call to the function, and the value of the real parameter expression is given to the ginseng when the function is called. In the macro changing, the real-argument expressions are not calculated directly to change.
4. In the macro definition, the guanmens within the string usually enclose with parenthesis to avoid errors. In the macro definition in the above example, Y, * (Y) expression is enclosed in parentheses, so the result is correct. If you go to parentheses, change the program to the following form:
#define sq (y) y * y
MAIN () {
INT A, SQ;
Printf ("INPUT A NUMBER:");
Scanf ("% d", & a);
SQ = SQ (A 1);
Printf ("SQ =% D / N", SQ);
}
Run results: Input a Number: 3
SQ = 7 is also input 3, but the result is not the same. Where is the problem? This is due to the generation of only the symbols and do not do other processing. The following statement will be obtained after the macro change: SQ = a 1 * a 1; since A is 3, the value of SQ is 7. This is clearly related to the meaning of the title, so parentheses in both sides of the parameter cannot be less. Even if the argument is bracker, it is not enough, please see the following procedure: #define sq (y) * (y)
MAIN () {
INT A, SQ;
Printf ("INPUT A NUMBER:");
Scanf ("% d", & a);
SQ = 160 / Sq (A 1);
Printf ("SQ =% D / N", SQ);
}
This program is changed by the previous example, only the macro call statement is changed to: SQ = 160 / Sq (A 1); if the program is still 3, if the input value is still 3, the desired result is 10. However, the actual operation is as follows: Input a number: 3 SQ = 160 Why is this result? Analyze macro modulus statement, change to: SQ = 160 / (1) * (A 1) after macro change ); when A is 3, since "/" and "*" operator priority and combination are the same, it is 160 / (3 1) to obtain 40, and then 40 * (3 1) finally has 160. In order to get the correct answer, the entire string of the macro should be plugged in, the program is modified as follows.
#define sq (y) ((y) * (y))
MAIN () {
INT A, SQ;
Printf ("INPUT A NUMBER:");
Scanf ("% d", & a);
SQ = 160 / Sq (A 1);
Printf ("SQ =% D / N", SQ);
}
The above discussion description, but the macro definition should be plugged in both sides of the parameter, but also thickered throughout the string.
5. The macro with the belt is very similar, but there is an essential difference, in addition to the above, the result of function processing with the same expression and the use of macros may be different. MAIN () {
INT i = 1;
While (i <= 5)
Printf ("% d / n", SQ (i ));
}
SQ (int y)
{
Return ((y) * (y));
} #define sq (y) ((y) * (y))
MAIN () {
INT i = 1;
While (i <= 5)
Printf ("% d / n", SQ (i ));
}
In the above example, the function name is SQ, the shape is Y, the function body expression is ((y) * (y)). In Example 9.6 macular macro names SQ, the metallin is also Y, the string expression is (Y) * (Y)). Two cases are the same. Example 9.6 The function call is SQ (i ), the macro modulation of Example 9.7 is SQ (i ), and the active parameters are also the same. From the output result, it is very different. The analysis is as follows: In Example 9.6, the function call is to increase the solid parameter I value from Y. Then output the function value. Therefore, it is necessary to circulate 5 times. Output 1 to 5 square values. In Example 9.7, the macro is called only to change. SQ (i ) is replaced ((i ) * (i )). In the first cycle, since i is equal to 1, the calculation process is: the previous value of the previous I is 1, and then I has increased from 1 to 2, so the second I initial value in the expression is 2, The results of the two multiplication are also 2, and then the I value increases from 1 to 3. In the second cycle, the I value has an initial value of 3, so the previous I is 3, and the latter I is 4, and the product is 12, and then I will increase from 1 to 5. Enter the third cycle, since the I value has been 5, this will be the last cycle. The value of the calculation expression is 5 * 6 equal to 30. The I value has increased from 1 to 6, no longer satisfying the cycle condition, stopping the cycle. From the above analysis, it can be seen that both of the function calls and macro modes are similar in form and is essentially completely different. 6. Macro definition can also be used to define multiple statements. When macro calls, the statements are replaced to the source program. Look at the example below.
#define SSSV (S1, S2, S3, V) S1 = L * W; S2 = L * h; S3 = W * h; v = W * l * h;
MAIN () {
INT L = 3, W = 4, H = 5, SA, Sb, SC, VV;
SSSV (SA, SB, SC, VV);
Printf ("SA =% D / NSB =% D / NSC =% D / NVV =% D / N", SA, SB, SC, VV);
}
The first behavior of the program is macro definition, and the four assignment statements are represented by macro name SSSV, and the 4 type ginseng is 4 assigned variables. When the macro is called, 4 statements are expanded and replaced with the active parameters. Make the calculation results into the argument.
File contains
The file contains another important feature of the C predecessor. The file contains the general form of the command line to: #include "file name" in front We have multiple times with this command contains the header file of the prominent function. E.g:
#include "stdio.h"
#include "math.h"
The function of the file contains the command to insert the specified file into the command line position, replacing the command line, connect the specified file and the current source file file into a source file. In programming, the file contains is useful. A large program can be divided into multiple modules, which are programmed separately from multiple programmers. Some common symbol constants or macro definitions can be used separately, and can be used in the beginning of other files that contain the file with the command. This way, avoiding the public quantities in each file, saving time, and reduces errors.
The following points are to explain the following:
1. The file name containing the command can be enclosed with a double quotes or enclose with a sharp bracket. For example, the following writing methods are permissible: #include "stdio.h" #include
Conditional compilation
The pretreatment program provides conditional compilation. Different program parts can be compiled by different conditions, thus producing different target code files. This is useful for programs and commissioning. There are three forms, which are described below:
1. The first form:
#ifDef identifier
Block 1
#ELSE
Block 2
#ENDIF
Its function is to compile the block 1 if the identifier has been defined by the #define command; otherwise the block 2 is compiled. If there is no block 2 (it is empty), the #else in this format can be written as:
#ifDef identifier
Block #ENDIF
#define Num OK
MAIN () {
Struct stu
{
Int Num;
Char * name;
CHAR SEX;
Float score;
} * Ps;
PS = (struct stu *) Malloc (Struct Stu);
PS-> Num = 102;
PS-> name = "zhang ping";
PS-> sex = 'm';
PS-> score = 62.5;
#ifdef Num
Printf ("Number =% D / NSCORE =% F / N", PS-> Num, PS-> score;
#ELSE
Printf ("Name =% S / NSEX =% C / N", PS-> Name, PS-> SEX);
#ENDIF
Free (ps);
}
Since the conditional compiled pre-processing command is inserted in the 16th line of the program, it is necessary to compile the PrintF statement based on whether NUM is defined. And in the first line of the program has made macro definitions for NUM, therefore responds to the first PrintF statement, the result is output, and the number and grade are output. In the first line macro definition of the program, define NUM represents the string OK, which can also be any string, no string, write as: #define NUM also has the same meaning. Only the first line of the cancel process will be compiled the second PrintF statement. The reader can trial.
2. Second form:
#ifndef identifier
Block 1
#ELSE
Block 2
#ENDIF
The difference in the first form is to change "IFDEF" to "IFNDEF". Its function is to compile the block 1 if the identifier is not defined by the #define command, otherwise the block 2 is compiled. This is opposite to the first form of functionality.
3. Third form:
#IF constant expression
Block 1
#ELSE
Block 2
#ENDIF
Its function is that if the value of a constant expression is true (non-0), the block segment 1 is compiled, otherwise the block 2 is compiled. Therefore, the program can complete different functions under different conditions.
#define r 1
MAIN () {
Float C, R, S; Printf ("INPUT A NUMBER:");
Scanf ("% f", & c);
#if r
R = 3.14159 * c * c;
Printf ("Area of Round IS:% F / N", R);
#ELSE
S = C * C;
Printf ("Area of Square IS:% F / N", S);
#ENDIF
}
In this example, the third form of condition is compiled. In the first line macro definition of the program, the definition R is 1, so when the condition is compiled, the value of the constant expression is true, so the circular area is calculated and output. The conditions described above can of course also be implemented with conditional statements. However, the conditional statement will be compiled, and the generated target code program will be long, and the conditional compile is compiled, and only the block 1 or block 2 is compiled according to the condition, and the generated target program is shorter. If the program segment selection is very long, it is necessary to use the method compiled.
chapter summary
1. Pre-processing functions are a unique function of C language, which is done by the pre-processing program before formally compiling the source program. The programmer calls these features in the program with the preprocessing command.
2. Macro definition is to represent a string with an identifier, which can be constant, variables, or expressions. This string will be replaced with this string in the macro.
3. Macro definition can be used with parameters, and the macro is used to change the parameters. Instead of "value transfer".
4. In order to avoid an error while the macro change occurs, the string in the macro definition should be plugged in parentheses, and the form parameters appearing in the string should also be added.
5. The file contains an important feature of the pre-processed, which can be used to connect multiple source files into a source file to compile, and the result will generate a target file.
6. Condition Compilation Allows only program segments that meet the conditions in the source program, so that the generated target programs are shorter, thereby reducing the overhead of memory and improving the efficiency of the program.
7. Use the preprocessing features to make the program's modification, reading, transplanting, and debugging, making it easy to implement modular programming.