Define is a pre-processing command in C language. It is used for macro definition, which can improve the readability of the source code and provide convenience for programming.
Pre-processing commands start with "#", for example, include commands # include and macro-defined commands # define. Usually put in front of the source file, which is called preprocessing.
Preprocessing refers to the work done before 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 definition of a macro allows an identifier to represent a string in the C or C ++ language source program. It 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 or C ++, "macros" are divided into two types: parameter and no parameter.
A non-parameter macro is a non-parameter macro without parameters. The general format of its definition is: # define the identifier string "identifier" is the defined macro name. A string can be a constant, expression, or format string.
For example, # define PI 3.14 is used to specify the identifier PI to replace the constant 3. 14. when compiling the source program, PI can be used in all the places where 3.14 is used. When compiling the source program, macro replacement will be performed by the Preprocessing Program first, replace all macro name PI with 3.14, and then compile.
Macro is defined to represent a string with the macro name. When the macro is expanded, it replaces the macro name with the macro name. This is just a simple replacement. The string can be a constant or an expression, the Preprocessing Program does not perform any checks on it. If any error occurs, it can only be found when the source program that has been expanded by a macro is compiled.
Macro definition is not a description or statement (it is a pre-processing command). You do not need to add a number at the end of the row. if you add a semicolon, you can replace it with a semicolon.
The following example shows a non-parameter Macro Substitution constant: # define PI 3.14 # include <stdio. h> int main ()
{Float r = 1.0; float area = PI * r; printf ("The area of the circle is % f", area); return 0 ;} another example of replacing a string with a non-argument macro is: # define M (y * y + 3 * y)
# Include <stdio. h> int main ()
{Int s, y; printf ("input a number:"); scanf ("% d", & y ); s = 3 * M + 4 * M + 5 * M; printf ("s = % d \ n", s); return 0 ;} # define M (y * y + 3 * y) defines the M expression (y * y + 3 * y ). During source program compilation, all (y * y + 3 * y) values can be replaced by M. During source program compilation, macro replacement is performed by the Preprocessing Program first, replace all macro names M with the (y * y + 3 * y) expression, and then compile.
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 expression (y * y + 3 * y) in macro definition. Otherwise, an error occurs.
Macros with parameters are defined in C language. macros with parameters are allowed. 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 macro with parameters is defined in the following format: # define macro name (form parameter table) string contains various form parameters in the string.
Macro calls with parameters generally take the form of macro names (real parameter tables)
For example: # define M (y) y * y + 3 * y ......
K = M (5 );......
In macro calls, the real parameter 5 is used to replace the form parameter y. After the pre-processing macro is expanded, the statement k = 5*5 + 3*5 is used as an example: # define MAX (a, B) (a> B )? A: B # include <stdio. h> int main ()
{Int x, y, max; printf ("input two numbers:"); scanf ("% d", & x, & y); max = MAX (x, y); printf ("max = % d \ n", max); return 0;} the first line of the preceding program is defined with a macro parameter, use the macro name MAX to represent the conditional expression (a> B )? A: B. The parameters a and B appear in the condition expression. The seventh line of the program, max = MAX (x, y), is macro call. Real parameters x, y, replace the representative 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.
For macro definitions with parameters, the following problems need to be explained: 1. In macro definitions with parameters, there cannot be spaces between macro names and parameter tables.
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. When the macro is expanded, the 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. 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)
# Include <stdio. h> int main ()
{Int a, sq; printf ("input a number:"); scanf ("% d", & a); sq = SQ (a + 1 ); printf ("sq = % d \ n", sq); return 0;} First behavior macro definition in the above example, 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.
3. 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 and the result is correct. If you remove the parentheses, change the program to the following format: # define SQ (y) y * y # include <stdio. h> int main ()
{Int a, sq; printf ("input a number:"); scanf ("% d", & a); sq = SQ (a + 1 ); printf ("sq = % d \ n", sq); return 0;} the running result is: input a number: 3 sq = 7 (the expected result is 16 ).
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. Sometimes, even if brackets are not enough on both sides of the parameter, see the following program: # define SQ (y) * (y)
# Include <stdio. h> int main ()
{Int a, sq; printf ("input a number:"); scanf ("% d", & a); sq = 160/SQ (a + 1 ); printf ("sq = % d \ n", sq); return 0;} compared with the macro, this program only changes the macro call statement: 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 associativity, 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 enclosed by parentheses. The program is modified as follows: # define SQ (y) * (y ))
# Include <stdio. h> int main ()
{Int a, sq; printf ("input a number:"); scanf ("% d", & a); sq = 160/SQ (a + 1 ); printf ("sq = % d \ n", sq); return 0;} for macro definition, the insurance method should not only be enclosed by brackets on both sides of the parameter, brackets should also be added to the entire string.
4. macros with parameters are similar to those with parameters, but they are essentially different. Processing the same expression using a function may be different from processing the two using macros.
The following is an example for comparison: Use the function: # include <stdio. h> int SQ (int); int main ()
{Int I = 1; while (I <= 5)
Printf ("% d \ n", SQ (I ++); return 0;} int SQ (int y)
{Return (y) * (y);} Use macro: # define SQ (y) * (y ))
# Include <stdio. h> int main ()
{Int I = 1; while (I <= 5)
Printf ("% d \ n", SQ (I ++); return 0;} in the example of using a function, the function name is SQ and the parameter is Y, the function body expression is (y) * (y )). In the macro example, the macro name is SQ, the form parameter is y, and the string expression is (y) * (y )). The two examples have the same surface. The function call is SQ (I ++), the macro call is SQ (I ++), and the real parameters are the same. However, the output results are very different. The analysis is as follows: In the example of using a function, the function call transmits the real parameter I value to the form parameter y and then increases by 1. Then, the output function value is output. Therefore, it takes 5 cycles. Output 1 ~ The square value of 5. In the example of using macros, only macro calls are used for replacement. 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 to 3. in the second loop, the I value already 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 equal to 30. I, and then increases from 1 to 6. The loop condition is no longer met and the loop is stopped. From the above analysis, we can see that function calls and macro calls are similar in form and are completely different in nature.
"\", "#", "# @" And "#" are used to resume the row when # define is used, "#" is used to convert a parameter to a string, which is to add double quotation marks to the parameter. "#" Is used to connect the first and second parameters and convert them into a string. "# @" is to enclose the parameters with single quotation marks. The following example makes it easy for you to understand.
# Define Conn (x, y) x # y # define ToChar (a) # @ a # define ToString (x) # x
Int n = Conn (123,456); the result is n = 123456; char * str = Conn ("asdf", "adf") the result is str = "asdfadf "; char a = ToChar (1); the result is a = '1'; char * str = ToString (123132); it becomes str = "123132"; why does it need "#"? what are the three operators "# @" and? The reason is as follows: if the macro name is enclosed in quotation marks in the source program, the Preprocessing Program will not replace the macro name. As follows: # define OK 100 # include <stdio. h> int main ()
{Printf ("OK"); printf ("\ n"); return 0;} in the previous example, the macro name "OK" is defined to indicate 100, but the "OK" is enclosed by quotation marks in the printf statement, therefore, macro replacement is not performed. The running result of the program is: OK, which means "OK" is treated as a string.
Similarly, if the macro name is enclosed in single quotes in the source program, the Preprocessing Program will not replace the macro name.
Macro-defined nested macro definitions allow nesting. You can use defined macro names in macro-defined strings. During macro expansion, preprocessing programs are used for replacement. For example: # define PI 3.1415926 # define s pi * y pair statement: printf ("% f", s); after the macro replacement, it becomes: printf ("% f ", 3.1415926 * y). In conclusion, use a macro to replace a constant that is frequently used in the program. In this way, you do not need to modify the entire program, but only modify the macro-defined string, and when the constant is relatively long, we can use a short meaningful identifier to write the program, which is more convenient. For example, we are familiar with the fact that the circumference rate π is a commonly used value in mathematics. Sometimes we use 3.14 for representation and sometimes 3.1415926 for representation, this depends on the accuracy required by the calculation. If we need to use it multiple times in a program, we need to determine a value which will not change during this operation, however, we may later find that the precision of the program has changed and the value needs to be changed. This requires modifying all the values in the program, which may cause some inconvenience, but if we use macro definition, instead of using an identifier, you can only modify the macro definition when you modify it. You can also reduce the number of long numbers such as 3.1415926 input multiple times. We can define this as # define pi 3.1415926, it reduces input and facilitates modification. Why not?
In addition, using macro definitions with parameters can complete the function call function, reduce system overhead, and improve operation efficiency. As mentioned in C language, the use of functions can make the program more modular, easy to organize, and reusable. However, in the case of function calls, the field of function calls must be retained, so that after the sub-function is executed, it can return and continue execution. It also takes some time to restore the called function after the sub-function is executed, if the sub-function executes a large number of operations, the overhead of the conversion time can be ignored. However, if the sub-function does not have many functions, or even only one operation, such as a multiplication statement, this part of the conversion overhead is relatively large, but the macro definition with parameters will not have this problem, because it is expanded in the pre-processing stage, no conversion is required during execution, that is, it is executed locally. Macro definition can complete simple operations, but complex operations must be completed by function calls, and the macro definition occupies a large space for the target code. Therefore, you must determine whether to use macro definitions based on specific conditions.