Define usage in C Language

Source: Internet
Author: User

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.

Macro definition

In the C or 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 or C ++, "macros" are divided into two types: parameter and no parameter.

No macro Parameter Definition

A macro without parameters is defined as follows:

# Define identifier string

"Identifier" is the macro name defined. A string can be a constant, expression, or format string.

For example:

# Define PI 3.14

It 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 is an example of non-parametric Macro Substitution constant:

# Define PI 3.14
# Include <stdio. h>

Int main ()
{
Float r = 1.0;
Float area = pI * r * R;
Printf ("the area of the circle is % F", area );
Return 0;
}

Another example of replacing a string with a non-argument macro is as follows:

# 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.

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 macro with parameters is defined as follows:

# Define macro name (parameter table) String

Each parameter is included in the string.

Macro calls with parameters are generally in the following format:

Macro name (real parameter table)

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. The statement after the macro expansion is:

K = 5*5 + 3*5

For 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;

}

In the first line of the above example program, the macro definition with parameters is carried out, and the conditional expression (A> B) is represented by the Max macro name )? 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. The arguments X and Y are replaced with the form parameters A and 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. 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", & );
Sq = SQ (a + 1 );
Printf ("sq = % d \ n", SQ );
Return 0;

}

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.

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 parentheses are removed, 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", & );
Sq = SQ (a + 1 );
Printf ("sq = % d \ n", SQ );
Return 0;
}

Running result: 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 the brackets on both sides of the parameter are not enough, please refer to the following program:

# Define Sq (y) * (y)
# Include <stdio. h>

Int main ()
{
Int A, SQ;
Printf ("input a number :");
Scanf ("% d", & );
Sq = 160/Sq (a + 1 );
Printf ("sq = % d \ n", SQ );
Return 0;

}

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 ))
# Include <stdio. h>

Int main ()
{
Int A, SQ;
Printf ("input a number :");
Scanf ("% d", & );
Sq = 160/Sq (a + 1 );
Printf ("sq = % d \ n", SQ );
Return 0;
}

As described above, for macro definitions, the insurance practice should be not only to add brackets on both sides of the parameter, but also to apply brackets on 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 of comparison:

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 macros:

# 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, the parameter is Y, and 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 is to pass the real parameter I value to the form parameter Y and then increase by 1. Then output the function value. 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 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.

 

"\","#","#@"And "##"

When # define is used for definition, the slash ("\") is used to continue the line, and "#" is used to convert the parameter into 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) # @

# Define tostring (x) # x

 

Int n = conn (123,456); the result is n = 123456;

Char * STR = conn ("ASDF", "ADF") returns STR = "asdfadf ";

Char A = tochar (1); the result is a = '1 ';

Char * STR = tostring (123132); then STR = "123132 ";

Why do we need the "#", "# @", and "#" operators? 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:

# Derefined OK 100

# Include <stdio. h>

Int main ()

{
Printf ("OK ");
Printf ("\ n ");
Return 0;
}

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.

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 nesting

Macro definition allows 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

Statement: printf ("% F", S );

After the macro replacement, it becomes: printf ("% F", 3.1415926 * y );

Conclusion

Use a macro to replace a constant that is frequently used in the program. When this constant changes, you do not need to modify the entire program, but only modify the macro-defined string. When the constant is too long, we can use short and meaningful identifiers to write programs, 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.

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.