#define是C语言中提供的宏定义命令, the main purpose is to provide programmers with certain convenience in programming, and to a certain extent, improve the efficiency of the program, but students often do not understand the nature of the command in learning, always create some confusion here, in the programming of the misuse of the command, To make the program run inconsistent with the intended purpose, or to read the program written by others, the results of the operation to understand the error, which is bad for C language learning.
1 #define命令剖析
1.1 #define的概念
#define命令是C语言中的一个宏定义命令, which is used to define an identifier as a string, which is called the macro name, and the defined string is called the replacement text.
The command has two formats: one is a simple macro definition and the other is 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 body >
Example: #define A (x) x
When an identifier is defined by a macro, the identifier is a macro name. ThenThe macro name appears in the program, before the program is compiled, the macro name is replaced with the defined string, which is called the macro substitution, the substitution is not compiled, and the macro substitution is a simple replacement.
1.2 Macro Replacement when the time comes
In order to really understand the role of # define, let's look at the process of C language source program. When we compile a well-written source program in an integrated development environment such as TURBOC, we actually undergo several processes of preprocessing, compiling, assembling, and connecting, as shown in Figure 1.
source Program
Preprocessor
Modified source Program
Compiler
Assembler Program
Assembler Series
Relocatable Target Program
Connector
Executable Target Program
Figure 1 Compilation process for C language
Where the preprocessor produces the output of the compiler, it implements the following functions:
(1) The file contains
You can extend the # include in the source program to the body of the file, i.e. locate and expand the contained. h file to the location of # include.
(2) Conditional compilation
The preprocessor includes a part of the source program in or out of the compilation commands, such as # if and #ifdef, and usually converts the excluded statement to a blank line.
(3) Macro expansion
The preprocessor expands the macro reference that appears in the source program file into the corresponding macro definition, which is what this article describes as the function of # define, which is done by the preprocessor.
The source program processed by the preprocessor differs from the previous source program, where the work performed is purely a substitution and unwinding, without any computational function, so as long as you can really understand this when learning the # define command, it will not cause misunderstanding and misuse of this command.
2 #define使用中的常见问题解析
2.1 Simple macros define problems that occur in use
In the use of simple macro definitions, it is easy to misunderstand and misuse when the replacement text represents a string that is an expression. The following example:
Example 1 #define N
void Main ()
{
int a=n*n;
printf ("%d", a);
}
(1) The problem: there is a macro definition command in this program, macro n represents the string is the use of the macro N, in the program, the general students in the reading of the program, the problem is prone to solve the N is 2+2=4, and then in the program to calculate a when using multiplication, that is, n*n=4*4=16, In fact, the result of the problem is 8, why the result has such a large deviation?
(2) Problem resolution: As described in section 1, macro expansion is done in the preprocessing phase, this phase of the replacement text is just as a string, and there will be no calculation occurs, when the macro n appears in the expansion is simply the use of the string to replace N, does not add any symbols, So the result of the program is a=2+2*2+2, after the calculation = 8, which is the essence of macro substitution, how to write a program to complete the result of 16 of the operation?
(3) Workaround: The macro definition is written in the following form
#define N (+)
This will be replaced by (=16) * (* * *)
2.2 Problems with the macro definition with parameters
In the use of macro definitions with parameters, it is very easy to cause misunderstanding. For example, we need to make a macro substitution to find the square of any number, which requires the use of parameters to replace the parameters in the macro definition with actual parameters in the program. General students are easily written in the following form:
#define AREA (x) x*x
This is very easy to use in the problem, see the following program
void Main ()
{
int Y=area (+);
printf ("%d", y);
}
Supposedly given the parameter is the 4*4=16, the result should be the results of a, but wrong, because the actual result of the program is 8, is still not able to follow the pure simple replacement of the rules, but also the first calculation and replace, in this program, is the area macro is the parameter, it should be replaced by the macro definition of x, That is replaced by 2+2*2+2=8. What if we follow the solution in (1) and enclose it in the X-ray of the macro body? #define AREA (x) (x) * (x), for area (*./area), replaced by (+/-(+) * (+) * (*) = 16, can be resolved, but for the area (* * * * * *), and some students see this problem immediately give results, Because the numerator denominator, again wrong, or forget to follow the first substitution of the rules, this problem will change to (* * +) * (* * +) * (* * * *) (4*4/4*4) is the multiplication operation rules, the result is 16/4*4=4*4=16, that should be how? The workaround is to add a parenthesis to the entire macro body, that is, the # define area (x) (x) * (x)), do not feel that this is not necessary, without it, is not possible.
If you want to be able to really use a good macro definition, then in the reading of other people's programs, it is important to remember to use the macro in the program to replace all of the characters it represents the string, do not take the liberty to add any other symbols, fully expanded after the corresponding calculation, will not write wrong running results.If you are programming with macro substitution, when using a simple macro definition, when there is more than one symbol in the string, the parentheses show precedence, and if it is a macro definition with parameters, enclose each parameter in the macro body with parentheses over the entire macro body. See here, can't help but ask, with macro definition so troublesome, so error-prone, can abandon it, let us look at the C language with the benefits of macro definition.
3 Benefits of macro definition
(1) Modification of the convenience program
Using simple macros to define available macros instead of a constant used in the program, so that when the constant changes, not the whole program to modify, only the macro definition of the string can be, and when the constant is longer, we can use a shorter meaningful identifier to write the program, which is more convenient. What we call a constant change is not a change in the course of a program, but a modification during programming, a familiar example of which Pi Pi is a commonly used value in mathematics, Sometimes we will use 3.14来 to say, sometimes also use 3.1415926, which depends on the accuracy of the calculation, if we make a program to use it multiple times, then we need to determine a numeric value, in this operation does not change, but perhaps later found that the accuracy of the program has changed, need to change its value, which need to modify the program all Related values, this will bring us some inconvenience, but if you use a macro definition, using an identifier instead, then modify the macro definition only, you can also reduce the input 3.1415926 such a long number of times, we can define #define pi3.1415926, not only reduce the input and easy to modify, why not?
(2) Improve the operation efficiency of the program
using a macro with parameters to define functions that can accomplish function calls can reduce system overhead and improve operational efficiency. As mentioned in the C language, the use of functions can make the program more modular, easy to organize, and reusable, but in the event of a function call, you need to retain the calling function of the field, so that the completion of the execution of the child function can return to continue execution, as well as the child function after the completion of the call function to restore the scene, If the child function performs more operations, this conversion time overhead can be ignored, but if the function of the child function is relatively small, or even a single point of operation, such as the operation of a multiplication statement, this part of the conversion cost is relatively large, but the use of parameters with the macro definition will not occur this problem, Because it is a macro expansion during the preprocessing phase, it does not need to be converted at execution time, which is executed locally. A macro definition can do simple things, but a complex operation is still done by a function call, and the macro definition occupies a relatively large target code space. So when you use it, you decide whether to use a macro definition, depending on the situation.
4 Conclusion
This paper analyzes the problem that the macro definition # # is easy to appear in the C language, and analyses the processing of # define from the point of view of C source program processing, and expounds its merits. As long as you can understand the rules of macro expansion, master the use of macro definition, is in the preprocessing phase of the source program to replace, just use the corresponding string to replace the macro name appearing in the program, so that the correct use on the basis of the full enjoyment of the use of macro definition to bring convenience and efficiency
Two.
Recently read the COM related information, see CCmdTarget Implement COM interface, read the definition of some macros, in the Afxdisp.h header file
#define Begin_interface_part (Localclass, baseclass) \
Class x# #localClass: Public baseclass \
Originally this macro definition is easy to understand, but there is a x## here, I really have not seen this usage, do not know what it is intended.
Later asked a few friends also do not know.
You know what?
Perhaps you do not know ~ hehe, at last I still found the relevant information, interpretation of this define, but also by the way to know the other two less commonly used define
#define CONN (x, y) x# #y
#define TOCHAR (x) #@x
#define TOSTRING (x) #x
x# #y表示什么? Represents x connection Y, for example:
int n = Conn (123,456); The result is n=123456;
char* str = Conn ("asdf", "ADF") result is str = "ASDFADF";
It's amazing, isn't it?
To see #@x, in fact, is to add single quotation marks to x, the result is a const char. For example,
char a = ToChar (1); The result is a= ' 1 ';
Do a cross-border test char a = TOCHAR (123); The result is a= ' 3 ';
But if your parameter exceeds four characters, the compiler will give you an error! Error C2015:too many characters inconstant:p
Finally look at #x, and you know, he's giving X double quotes.
char* str = ToString (123132); str= "123132";
Finally leave a few small experiments for everyone to test:
#define DEC (x, y) (X-y)
int n = Dec (A (123,1), 1230);
n = Conn (123, Conn (123,332));
char* str = A ("n", ToString (Dec (3,1));
What would be the result? Hey Hey hehe ~
Three.
#define XXX () {}
Supported by standard C
#define XXX () ({})
GCC new features, mainly to prevent macro expansion problems, the default expansion is to add one;
CODE: #define A (A,b,c) ({a=1;b+=1;c=3;a+b+c;})
#include <stdio.h>
int main ()
{
int A;
int b=1;
int C;
int D;
D=a (A,B,C);
printf ("%d,%d,%d,%d\n", a,b,c,d);
return 0;
}
Indicates that the macro function also has a return value, and the return value of the last expression is the return value of the macro function.
Operation Result:
1,2,3,6
C + + #define用法详解