# Define is a macro definition Command provided in C language. Its main purpose is to provide programmers with some convenience in programming and improve the program running efficiency to a certain extent, however, students often cannot
Understanding the essence of this command always creates some confusion here. This command is misused during programming to make the program run differently from the expected purpose, or when reading a program written by someone else, an error occurred while interpreting the running results.
C language learning is unfavorable.
1 # define command profiling
1.1 # define concept
# The define command is a macro definition command in C language. It is used to define an identifier as a string. This identifier is called a macro name and the defined string is called a replacement text.
The command has two formats: A simple macro definition and a macro definition with parameters.
(1) simple macro definition:
# Define <macro name> <string>
Example: # define PI 3.1415926
(2) macro definition with Parameters
# Define <macro name> (<parameter table>) <macro>
Example: # define a (x) x
After an identifier is defined by a macro, It is a macro name. In this case, the macro name appears in the program. Before the program is compiled, replace the macro name with the defined string, which is called macro replacement, macro replacement is a simple replacement.
1.2 timing of macro replacement
To truly understand the role of # define, let's take a look at the processing process of the C language source program. When we compile the compiled source program in an integrated development environment such as Turbo C, the process of preprocessing, compilation, compilation, and connection is actually completed, as shown in figure 1.
Source program
Pre-processor
Modified source program
Compiler
Assembler
Assembler
Relocated Target Program
Connector
Executable Target Program
Figure 1 C language compilation process
The pre-processor generates the compiler output, which implements the following functions:
(1) File Inclusion
You can extend # include in the source program to the file body, that is, find and expand the contained. h file to the position where # include is located.
(2) Conditional compilation
Based on the # If and # ifdef compiling commands and their post-condition, the Preprocessor includes or excludes some part of the source program. Generally, the excluded statements are converted into empty rows.
(3) macro expansion
The pre-processor expands the macro reference in the source program file into the corresponding macro definition, that is, the # define function described in this article, which is completed by the pre-processor.
The source program processed by the pre-processor is different from the previous source program. In this stage, the work is purely replaced and expanded, and there is no computing function, so long as you can really understand the # define command, this command will not cause misunderstanding and misuse.
2 # define FAQs
2.1 problems with simple macro definition
In the use of a simple macro definition, it is easy to misunderstand and misuse when the string represented by the text is replaced by an expression. For example:
Example 1 # define N 2 + 2
Void main ()
{
Int A = N * N;
Printf ("% d", );
}
(1)
Problem: There is a macro definition command in this program. Macro n represents a string of 2 + 2, which is used for macro N in the program. when reading this program, the easy problem is to first solve N
2 + 2 = 4, and then use multiplication when calculating a in the program, that is, N * n = 4*4 = 16. In fact, the result of this question is 8, why is there such a big deviation?
(2) Problem Analysis: As described in section 1, macro expansion is completed in the pre-processing phase. In this phase, the replacement text is only considered as a string, and no computation occurs, where macro n appears during expansion
Simply use string 2 + 2 to replace N without adding any symbols. Therefore, after the program is expanded, the result is a = 2 + 2*2 + 2, after calculation = 8, this is the essence of macro replacement. How to write programs?
What if the result is 16?
(3) solution: Write the macro definition in the following format:
# Define N (2 + 2)
This can be replaced with (2 + 2) * (2 + 2) = 16
2.2 problems with macro definition with Parameters
It is easy to misunderstand the use of macro definitions with parameters. For example, we need a macro to replace the square of any number, which requires parameters to replace the macro-defined parameters with actual parameters in the program. Generally, students are easy to write as follows:
# Define area (x) x * x
This is very prone to problems in use, see the following program
Void main ()
{
Int y = Area (2 + 2 );
Printf ("% d", y );
}
The parameter is 2 + 2. The result should be 4*4 = 16, but it is incorrect because the actual result of this program is 8, it still fails to follow purely simple replacement rules, and is replaced by calculation first.
In this program, 2 + 2 is the parameter in the area macro. It should replace X in the macro definition, that is, 2 + 2*2 + 2 = 8. If you follow the solution in (1), set 2 + 2
Is it okay to include X in a macro? # Define area (X)
(X) * (x). For area (2 + 2), replace it with (2 + 2) * (2 + 2) = 16, which can be solved, but what about area (2 + 2)/area (2 + 2 )?
As soon as some students see this question, they will give the result. Because the denominator of the numerator is the same and it is wrong, they still forget to follow the rule of replacing and then calculating. After this question is replaced, it will become
(2 + 2) * (2 + 2)/(2 + 2) * (2 + 2) 4*4/4*4 according to the multiplication and division calculation rules, the result is 16/4*4 = 4*4 = 16. What should I do? The solution is
Add a bracket on the macro, that is, # define area (x) * (x). Don't think this is unnecessary. It won't work without it.
To truly use macro definitions, remember to replace all macro usage in the program with the strings it represents when reading other programs, do not add any other symbols on your own.
After the calculation is started, the running results are not written incorrectly. If the macro is replaced by a self-programmed macro, when the simple macro definition is used, when there are more than one symbol in the string, brackets are added to indicate the priority.
To define a macro with parameters, you must add brackets to each parameter in the macro and add a bracket to the entire macro. You can't help but ask if macro definition is so troublesome and error-prone,
Let's take a look at the benefits of macro definition in C language.
3. Advantages of macro definition
(1) convenient program modification
Use a simple macro definition to replace a constant that is frequently used in the program. In this way, when changing the constant, 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 short and meaningful identifiers to write programs, which is more convenient. The constant change we mentioned is not a change during program running, but a change during programming. For example, we are familiar with it.
Sub-, 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 for calculation, if we compile a program
To use it multiple times, you need to determine a value which will not change during this operation. However, you may find that the precision of the program has changed and you need to change its value,
This requires modifying all the values in the program, which may cause some inconvenience. However, if you use a macro definition instead of an identifier, you only need to modify the macro definition, you can also reduce input.
We can define the value 3.1415926 as long as multiple times # define pi
3.1415926, which reduces input and facilitates modification. Why not?
(2) Improve program running efficiency
You can use a macro definition with parameters to call a function, and reduce system startup.
Sales to improve operation efficiency. As mentioned in C language, the use of functions can make the program more modular, easy to organize, and reusable. However, when a function call occurs, you need to keep the field of the called function so that the sub-
After the function execution is complete, it can return to continue the execution. It also takes some time to resume the calling of the function after the sub-function is executed. If there are many sub-function operations, this conversion time overhead can be ignored
However, if a sub-function has fewer functions or even only one operation, such as a multiplication statement, the conversion overhead is relatively large, however, if you use a macro definition with parameters, this question will not appear.
Because it is expanded in the pre-processing stage, and does not need to be converted during execution, that is, it is executed locally. Macro definition can complete simple operations, but complex operations must be completed by function calls, and macro definition
The space occupied by the target code is relatively large. Therefore, you must determine whether to use macro definitions based on specific conditions.
4 Conclusion
In this paper, the macro definition # define in C language is parsed to solve problems that may occur during use, and the # define processing is analyzed from the perspective of the C source program processing process, it also carries out its advantages
. As long as you can understand the macro expansion rules and master the use of macro definition, the source program is replaced in the pre-processing phase, but the macro name in the program is replaced with the corresponding string, in this way, you can use
And fully enjoy the convenience and efficiency brought by the use of macro definition.
II.
I recently read the com-related documents. When I saw that csf-target implemented the COM interface, I read some macro definitions in the afxdisp. h header file.
# Define begin_interface_part (localclass, baseclass )/
Class X # localclass: Public baseclass/
This macro definition is easy to understand, but here is an extra X #. I have never seen such a definition, and I don't know what it means.
I asked a few friends, but I didn't know either.
Do you know?
Maybe you don't know ~ Well, I finally found the relevant materials, explained the define, and also met the other two less commonly used define
# Define conn (x, y) x # Y
# Define tochar (x) # @ x
# Define tostring (x) # x
X ## what does y mean? X connects to Y, for example:
Int n = conn (123,456); the result is n = 123456;
Char * STR = conn ("ASDF", "ADF") returns STR = "asdfadf ";
How about it? It's amazing.
Let's take a look at # @ X. In fact, a single quotation mark is added to X, and the returned result is a const char. For example:
Char A = tochar (1); the result is a = '1 ';
Make an out-of-bounds test char a = tochar (123); the result is a = '3 ';
However, if your parameter contains more than four characters, the compiler reports an error! Error c2015: Too character characters in constant: P
Finally, let's take a look at # X. You may also understand that it adds double quotation marks to X.
Char * STR = tostring (123132); then STR = "123132 ";
Finally, let's leave a few small tests for everyone to test:
# Define Dec (x, y) (x-y)
Int n = Dec (A (1230 );
N = conn (123, Conn (123,332 ));
Char * STR = a ("12", tostring (Dec (3, 1 ));
What will happen? Hey hey ~
III.
# Define XXX (){}
Supported by standard C
# Define XXX ()({})
The new features of GCC are mainly used to prevent macro expansion problems. By default, one feature is added during expansion, which is prone to problems.
Code: # define a (A, B, C) ({A = 1; B + = 1; C = 3; A + B + C ;})
# Include <stdio. h>
Int main ()
{
Int;
Int B = 1;
Int C;
Int D;
D = a (A, B, C );
Printf ("% d, % d/N", A, B, C, D );
Return 0;
}
It indicates that the macro function still has a return value. the return value of the last sub-statement is used as the return value of the macro function.
Running result:
1, 2, 3, 6