Pre-processing of C language -------- macro definition

Source: Internet
Author: User

1 Overview
Used preprocessing commands starting. For example, include the command # include and macro definition command # define. In the source program, these commands are placed outside the function, and are generally placed before the source file. They are called preprocessing.


Preprocessing refers to the work done before the first scanning (lexical scanning and syntax analysis) of compilation. Preprocessing is an important function of C language, which is completed by the Preprocessing Program. When a source file is compiled, the system will automatically reference the Preprocessing Program to process the preprocessing part of the source program. After the processing is completed, the system will automatically compile the source program.

The C language provides a variety of preprocessing functions, such as macro definition, file inclusion, and Conditional compilation. Properly use the pre-processing function to compile programs for reading, modifying, porting and debugging, and also facilitates modular program design.

2. macro definition: (replacing ideas)

In the C language source program, an identifier is allowed to represent a string, which is called a "macro ". The identifier defined as "macro" is called "macro name ". During compilation and preprocessing, all the "macro names" in the program are replaced by the strings in the macro definition. This is called "macro replacement" or "macro expansion ".

Macro definition is completed by macro definition commands in the source program. Macro replacement is automatically completed by the Preprocessing Program. In C, macros are classified into two types: parameters and no parameters.


2.1

No macro Parameter definition: The macro name without parameters is not included.

The general format is: # define identifier string

"#" Indicates that this is a preprocessing command. All operations starting with "#" are pre-processing commands. "Define" is a macro-defined command. "Identifier" is the macro name defined. A string can be a constant, expression, or format string.

For example:

# 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 );
}
In the above example, the macro is defined first, and the M expression (y * y + 3 * y) is defined. Macro calls are made in s = 3 * M + 4 * M + 5 * M. After the macro is expanded during preprocessing, the statement becomes: s = 3 * (y * y + 3 * y) + 4 (y * y + 3 * y) + 5 (y * y + 3 * y); note that there must be no fewer parentheses on both sides of the macro definition expression (y * y + 3 * y. Otherwise, an error occurs.
After the definition is as follows: # difine M y * y + 3 * y, the following statement is obtained during macro expansion: s = 3 * y + 3 * y + 4 * y + 3 * y + 5 * y + 3 * y; this is equivalent; 3y required 2 + 3y + 4y required 2 + 3y + 5y required 2 + 3y. Of course, the calculation result is incorrect.


Note:

1. A macro is defined to represent a string with a macro name. During macro expansion, the macro name is replaced by the macro name. This is just a simple replacement. The string can contain any character, which can be a constant, it can also be an expression, which is not checked by the Preprocessing Program. If any error occurs, it can only be found when the source program that has been expanded by a macro is compiled.

2 macro definition is not a description or statement. Do not add any extra points at the end of the row. if you add a semicolon, replace it with a semicolon.

3. The macro definition must be written outside the function, and its scope is the macro definition command to end with the source program. To terminate its scope, use the # undef command, for example: # define PI 3.14159
Main ()
{
......
}
# Undef PIPI Scope
F1 ()
... Indicates that PI is valid only in the main function and is invalid in f1.
4. If the macro name is enclosed in quotation marks in the source program, the Preprocessing Program will not replace the macro name.
# Derefined OK 100
Main ()
{
Printf ("OK ");
Printf ("\ n ");
}
In the preceding example, the macro name "OK" is defined to indicate 100, but the "OK" in the printf statement is enclosed in quotation marks, so macro replacement is not performed. The running result of the program is: OK, which means "OK" is treated as a string.

5. macro definitions allow nesting. You can use defined macro names in macro-defined strings. During macro expansion, preprocessing programs are used for replacement. Example: # define PI 3.1415926
# Define s pi * y/* PI is the defined macro name */pair statement: printf ("% f", s); after the macro replacement, it becomes: printf ("% f", 3.1415926 * y );

6. The macro name is used to be represented in uppercase letters, so as to distinguish it from variables. However, lower-case letters are also allowed.

7. The macro definition can be used to indicate the data type for easy writing. For example, # define STU struct stu can be used as a variable description in the program: STU body [5], * p; # define INTEGER int can be used as an INTEGER variable description in the program: INTEGER a, B; note the difference between the data type defined by macro and the data specifier defined by typedef. Macro definition is only a simple string replacement, which is completed in preprocessing, while typedef is processed during compilation. It is not a simple replacement, but a new name for the type specifier. The named identifier provides a description of the type. See the following example: # define PIN1 int * typedef (int *) PIN2; the two are similar in form, but they are different in actual use. The following uses PIN1 and PIN2 to illustrate the differences between variables: PIN1 a and B; after the macro replacement, it becomes int * a, B; it indicates that a is a pointer variable pointing to an integer, B is an integer variable. However, PIN2 a, B; indicates that both a and B are pointer variables pointing to integer types. Because PIN2 is a type specifier. This example shows that although the macro definition can also represent the data type, it is a character after all.
Replacement. Be careful when using it to avoid errors.

8. The macro definition of "output format" can reduce writing troubles. This method is used in case 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 );
}

2.2 macro definition with Parameters

The C language allows macros with parameters. In macro definition, parameters are called formal parameters, and in macro calls, parameters are called actual parameters. For macros with parameters, not only macro expansion is required during the call, but also real parameters must be used to replace the form parameters.

The general format of macro with parameters is: # define macro name (form parameter table) string contains various form parameters in the string. The macro with parameters is called in the following form: macro name (real parameter table );
For example:
# Define M (y) y * y + 3 * y/* macro definition */
:
K = M (5);/* macro call */
: In macro calls, the real parameter 5 is used to replace the form parameter y. The statement after the macro is expanded by preprocessing
K = 5*5 + 3*5
# Define MAX (a, B) (a> B )? A: B
Main (){
Int x, y, max;
Printf ("input two numbers :");
Scanf ("% d", & x, & y );
Max = MAX (x, y );
Printf ("max = % d \ n", max );
}
The first line of the above example program is defined with a macro parameter. The macro name MAX is used to represent the conditional expression (a> B )? A: B. The parameters a and B appear in the condition expression. Line 7 of the program max = MAX (x,
Y) for macro calls, real parameters x, y, will replace the form parameters a, B. After macro expansion, the statement is: max = (x> y )? X: y is used to calculate the large numbers in x and y. The macro definition with parameters must be described as follows:

1. In the macro definition with parameters, there cannot be spaces between the macro name and the form parameter table.
For example, set: # define MAX (a, B) (a> B )? A: B: # define MAX (a, B) (a> B )? A: B will be considered as a non-parameter macro definition. The macro name MAX represents the string (a, B) (a> B )? A: B.
Macro expansion, macro call statement: max = MAX (x, y); will be changed to: max = (a, B) (a> B )? A: B (x, y); this is obviously incorrect.

2. In the macro definition with parameters, the formal parameters do not allocate memory units, so you do not need to define the type. The real parameters in macro calls have specific values. Use them

This parameter must be a type description. This is different from the situation in the function. In a function, the form parameter and the real parameter are two different quantities and each has its own scope. when calling the function, you must assign the real parameter value to the form parameter for "value transfer ". In the macro with parameters, there is only a replacement of symbols, and there is no value transfer problem.

3. The form parameter in the macro definition is the identifier, and the real parameter in the macro call can be an expression.
# Define SQ (y) * (y)
Main (){
Int a, sq;
Printf ("input a number :");
Scanf ("% d", & );
Sq = SQ (a + 1 );
Printf ("sq = % d \ n", sq );
}
In the preceding example, the first behavior macro is defined, and the form parameter is y. In macro calls of the seventh row of the program, the real parameter is a + 1, which is an expression. During macro expansion, a + 1 is used to replace y, and (y) * (y) is used to replace SQ, obtain the following statement: sq = (a + 1) * (a + 1); this is different from the function call, when calling a function, evaluate the value of the real parameter expression and then assign it to the form parameter. In macro substitution, the real parameter expressions are replaced directly without calculation.

4. In macro definition, the form parameters in the string are usually enclosed in parentheses to avoid errors. In the macro definition in the preceding example, y in the (y) * (y) expression is enclosed in parentheses, so the result is correct. If parentheses are removed, change the program to the following format:
# Define SQ (y) y * y
Main (){
Int a, sq;
Printf ("input a number :");
Scanf ("% d", & );
Sq = SQ (a + 1 );
Printf ("sq = % d \ n", sq );
}
Running result: input a number: 3
If sq = 7, enter 3, but the result is different. Where is the problem? This is because replacement is only for symbol replacement and not for other processing. After the macro replacement, the following statement is obtained: sq = a + 1 * a + 1; because a is 3, the sq value is 7. This is obviously contrary to the meaning of the question, so the brackets on both sides of the parameter cannot be small. Even if parentheses are not enough on both sides of the parameter, please refer to the following program:
# Define SQ (y) * (y)
Main (){
Int a, sq;
Printf ("input a number :");
Scanf ("% d", & );
Sq = 160/SQ (a + 1 );
Printf ("sq = % d \ n", sq );
}
Compared with limit, this program only changes the macro call statement to sq = 160/SQ (a + 1). If the input value of this program is still 3, the expected result is 10. However, the actual running result is as follows: input a number: 3 sq = 160. Why does this happen? The macro call statement for analysis is changed to: sq = 160/(a + 1) * (a + 1) After the macro replacement; When a is 3, because the "/" and "*" operators have the same priority and conciseness, 160/(3 + 1) gets 40 first, and 40*(3 + 1) gets 160 last. To get the correct answer, the entire string in the macro definition should be added with parentheses. The program is modified as follows:
# Define SQ (y) * (y ))
Main (){
Int a, sq;
Printf ("input a number :");
Scanf ("% d", & );
Sq = 160/SQ (a + 1 );
Printf ("sq = % d \ n", sq );
}
As described above, the macro definition should not only be enclosed by parentheses on both sides of the parameter, but also the entire string.

5. macros with parameters are similar to functions with parameters, but they are essentially different. Apart from the points mentioned above, the results of processing the same expression using a function or a macro 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 ))
Main (){
Int I = 1;
While (I <= 5)
Printf ("% d \ n", SQ (I ++ ));
}
In the preceding example, the function name is SQ, the parameter is Y, and the function body expression is (y) * (y )). In Example 9.6, the macro name is SQ, the form parameter is y, and the string expression is (y) * (y )). The two examples are the same. In Example 9.6, the function call is SQ (I ++), and the macro call in example 9.7 is SQ (I ++). The real parameters are the same. The output results are very different. The analysis is as follows: In example 9.6, the function call transmits the real parameter I value to the form parameter y and then increases by 1. Then output the function value. Therefore, it takes 5 cycles. Output 1 ~ The square value of 5. In Example 9.7, the macro is used for replacement only. SQ (I ++) is replaced by (I ++) * (I ++ )). In the first loop, Because I is equal to 1, the calculation process is: the first I initial value in the expression is 1, and then I auto-increment 1 is changed to 2, therefore, the first 2nd I initial values in the expression are 2 and the result of the two-phase multiplication is 2. Then, the I value is increased by 1 and 3. In the second loop, the I value has an initial value of 3. Therefore, in the expression, the first I is 3, the last I is 4, the product is 12, And then I increases from 1 to 5. Enter the third loop. Because the I value is already 5, this will be the last loop. The value of the calculated expression is 5*6 or 30. The I value is increased from 1 to 6, and the cycle condition is no longer met. From the above analysis, we can see that function calls and macro calls are similar in form and are completely different in nature.

6. macro definitions can also be used to define multiple statements. During macro calls, these statements are substituted into the source program. Let's 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 macro definition of the program. The macro name SSSV is used to represent four value assignment statements, and the four parameters are the four left variables with the four value assignment operators respectively. During macro calls, expand the four statements and use real parameters instead of form parameters. The calculation result is sent to the real parameter.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.