# define usage in C + +

Source: Internet
Author: User
#define is a macro definition command provided in the C language. Its main purpose is to provide programmers with a certain degree of convenience in programming and to improve the operating efficiency of the program to a certain extent. However, students often cannot understand the command while learning. In essence, there is always some confusion here. When you use this command incorrectly during programming, the program runs inconsistently with the intended purpose, or when you read the program written by others, you misunderstand the results of the operation. This is very difficult for C language unfavorable.
1 #define command analysis
1.1 The concept of #define
The #define command is a macro definition command in C language. It is used to define an identifier as a string. The identifier is called the macro name, and the defined string is called the replacement text.
This 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 list>) <macro body>
Example: #define A (x) x
After an identifier is defined by a macro, the identifier is a macro name. At this time, the macro name appears in the program. Before the program is compiled, the macro name is replaced with the defined string. This is called macro replacement. Compilation is performed after the replacement.
1.2 When Macro Replacement Occurs
In order to truly understand the role of #define, let's take a look at the processing of C language source programs. When we compile the written source program in an integrated development environment such as Turbo C, we actually go through several processes of preprocessing, compilation, assembly, and linking, as shown in Figure 1.
Source program

Preprocessor

Modified source program

translater

Assembler

Assembler

Relocatable target program

Connector

Executable target program

Figure 1 C language compilation process

The preprocessor generates the output of the compiler, which implements the following functions:
(1) File contains
You can expand #include in the source program to the body of the file, that is, find and expand the included .h file to where #include is located.
(2) Conditional compilation
The preprocessor includes or excludes a part of the source program according to the #if and #ifdef compilation commands and the following conditions, and generally converts the excluded statements into blank lines.
(3) Macro expansion
The preprocessor expands the references to macros that appear in the source program files into the corresponding macro definitions, which is the function of #define described in this article, which is done by the preprocessor.
The source program processed by the preprocessor is all different from the previous source program. The work performed at this stage is only pure replacement and expansion, without any calculation function, so as long as you can really understand this when learning #define command, This will not cause misunderstanding and misuse of this command.

2 #define common problems in use
2.1 Problems in the use of simple macro definitions
In the use of simple macro definitions, when the string represented by the replacement text is an expression, it is easy to cause misunderstanding and misuse. For example:
Example 1 #define N 2 + 2
void main ()
{
int a = N * N;
printf ("% d", a);
}
(1) Problems: In this program, there is a macro definition command. The string represented by macro N is 2 + 2. There is a use of macro N in the program. When students read this program, the problems that tend to arise are first. Solve N as 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 large deviation?
(2) Problem analysis: As described in Section 1, the macro expansion is completed in the preprocessing stage. At this stage, the replacement text is only regarded as a string, and no calculation will occur. The expansion is performed in the macro N. Where it appears, it simply uses the string 2 + 2 instead of N, and does not add any symbols, so the result of the expansion of the program is a = 2 + 2 * 2 + 2, after calculation = 8, this is the macro replacement In essence, how to write a program to complete the operation with a result of 16?
(3) Solution: Write the macro definition as follows
#define N (2 + 2)
This can be replaced with (2 + 2) * (2 + 2) = 16
2.2 Problems with macro definitions with parameters
It is easy to cause misunderstandings in the use of parameterized macro definitions. For example, we need to make a macro replacement that can square any number. This requires the use of parameters in order to replace the parameters in the macro definition with actual parameters in the program. It is easy for general students to write the following form:
#define area (x) x * x
This is very easy to cause problems in use, see the following program
void main ()
{
int y = area (2 + 2);
printf ("% d", y);
}
Theoretically, the parameter given is 2 + 2, and the result should be 4 * 4 = 16, but it is wrong, because the actual result of the program is 8, it still fails to follow the rule of pure simple replacement, and it is calculated first. Again, in this program, 2 + 2 is the parameter in the area macro. It should be used to replace x in the macro definition, that is, 2 + 2 * 2 + 2 = 8. Then, if you follow the solution in (1) and enclose 2 + 2, that is, enclose x in the macro body, is it OK? #define area (x) (x) * (x), for area (2 + 2), replace with (2 + 2) * (2 + 2) = 16, which can be solved, but for area (2 + 2) / What about area (2 + 2)? Some students give the result as soon as they see this question, because the numerator and denominator are the same, and they are wrong. They still forget to follow the rule of replacing and calculating again. This question After the replacement, it will become (2 + 2) * (2 + 2) / (2 + 2) * (2 + 2), which is 4 * 4/4 * 4. According to the rule of multiplication and division, the result is 16/4 * 4 = 4 * 4 = 16, what should I do? The solution is to add a parenthesis to the entire macro body, that is, #define area (x) ((x) * (x)). Don't think this is unnecessary. Without it, it will not work.
To be able to really use the macro definition, when reading other people's programs, you must remember to replace all the use of macros in the program with the strings it represents. Do not add any other symbols on your own initiative. After performing the corresponding calculations, you will not write the wrong running results. If you use your own macro replacement, when using simple macro definitions, when there is more than one symbol in the string, the parentheses are given priority. If it is a macro definition with parameters, you must give each Arguments are enclosed in parentheses, and one parenthesis is enclosed in the entire body of the macro. Seeing this, I can't help but ask, the definition of macros is so troublesome, so error-prone, can you abandon it? Let's take a look at the benefits of using macros in C.
3 Advantages of Macro Definition
(1) Convenient program modification
Use simple macros to define a macro that can be used instead of a constant that is often used in a program. This way, when changing the constant, you don't need to modify the entire program, you can only modify the string defined by the macro, and when the constant is longer, we can It is more convenient to write programs with shorter, meaningful identifiers. The constant change we are talking about is not changed during the running of the program, but it is modified during the programming. For a familiar example, the pi is a commonly used value in mathematics. Sometimes we use 3.14 to express it, sometimes Will use 3.1415926, etc., this depends on the accuracy required for the calculation. If we need to use it multiple times in a program, we need to determine a value that does not change in this run, but maybe later we find the accuracy represented by the program There are changes, you need to change its value, which requires modifying all relevant values in the program, which will cause us some inconvenience, but if you use a macro definition and use an identifier instead, only modify the macro when modifying Just define it, and you can reduce the number of times of 3.1415926 as long as you enter it. We can define #define pi 3.1415926 in this way, which reduces the input and is easy to modify. Why not?
(2) Improve the operating efficiency of the program
The use of macros with parameters can complete the function of the function call, while reducing system overhead and improving operating efficiency. As stated in the C language, the use of functions can make the program more modular, easy to organize, and reusable, but when a function call occurs, the scene of the calling function needs to be retained so that the sub-function can return to continue execution after the execution, It is also necessary to restore the scene where the function is called after the sub-function is executed. This requires a certain amount of time. If the sub-function performs more operations, this conversion time overhead can be ignored, but if the sub-function has fewer functions, it may even Only a little operation is completed, such as the operation of a multiplication statement, this part of the conversion overhead is relatively large, but the use of macro definition with parameters will not occur, because it is macro expansion in the preprocessing stage, No conversion is required at execution time, ie locally. Macro definitions can perform simple operations, but complex operations are still performed by function calls, and the target code space occupied by macro definitions is relatively large. Therefore, it is necessary to decide whether to use the macro definition according to the specific situation when using it.
4 Conclusion
This article analyzes the problems that occur when using the macro definition #define in C language, and analyzes the processing of #define from the perspective of the C source program processing process, and also explains its advantages. As long as you can understand the rules of macro expansion and master the use of macro definitions, the source program is replaced in the preprocessing stage, but the macro names appearing in the program are replaced with corresponding strings, so that you can fully enjoy on the basis of correct use Convenience and efficiency brought by the use of macro definitions
two.
Recently, I looked at com related materials. When I saw CCmdTarget implementing 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 \

Originally this macro definition was easy to understand, but there is an X ## here. I really haven't seen this usage. I don't know what it means.
After asking a few friends, I didn't know.

do you know?

Maybe you do n’t know ~ Hehe, in the end, I still found relevant information, interpreted this definition, and by the way, I knew two other less commonly used definitions

#define Conn (x, y) x ## y
#define ToChar (x) # @ x
#define ToString (x) #x

What does x ## y mean? Indicates that x is connected to y, for example:
int n = Conn (123,456); the result is n = 123456;
char * str = Conn ("asdf", "adf") The result is str = "asdfadf";
How is it amazing

Looking at # @ x again, it is actually a single quote for x, and the result is a const char. for example:
char a = ToChar (1); the result is a = '1';
Make 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 in constant: P

Finally take a look at #x, I guess you also understand, he is double quotes for x
char * str = ToString (123132); becomes 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 ("12", ToString (Dec (3,1));
What will happen? Hehe hehe

three.
#define xxx () {}
Supported by Standard C
#define xxx () (())
The newly added functions of GCC are mainly to prevent problems with macro expansion. The default expansion is to add a ;;


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 used as the return value of the macro function.
operation result:
1,2,3,6

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.