Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of C language preprocessing

2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article will explain in detail the example analysis of C language preprocessing. The editor thinks it is very practical, so I share it for you as a reference. I hope you can get something after reading this article.

One, the predefined symbol _ _ FILE__ / / the source file for compilation _ _ LINE__ / / the current line number of the file _ _ DATE__ / / the date on which the file was compiled _ _ TIME__ / / the time when the file was compiled _ _ STDC__ / / if the compiler follows ANSI C, its value is 1, otherwise int main () {printf ("% s\ n", _ _ FILE__) is not defined Printf ("% d\ n", _ _ LINE__); printf ("% s\ n", _ _ DATE__); printf ("% s\ n", _ _ TIME__); / / printf ("% d\ n", _ _ STDC__) / / because VS does not support ANSI C, in fact _ _ STDC__ is not defined / / gcc is supported / / gcc supports C language syntax very well return 0;}

These predefined symbols are built into the language, with examples as follows

Int main () {printf ("file:%s line:%d\ n", _ _ FILE__, _ _ LINE__); return 0;}

Second, # define1,#define defines the identifier # define name stuff#define MAX 100#define reg register / / as the keyword register, creating a short name # define STR "HEHE" int main () {int a = 3; int b = 20; if (a = = 4) b = MAX; else b =-a; register int num = 100 Reg int num2 = 200; int m = MAX; printf ("% d\ n", MAX); printf ("% d\ n", m); printf ("% s\ n", STR); return 0;}

# define MAX 1000 int main () {int x = 1; int max; if (x = MAX;//) {max = MAX;// replaced here by MAX 1000 politics; syntax error} else {max = 0;} printf ("% d", max); return 0;} 2 define macro

The # define mechanism includes a provision that allows parameters to be replaced into text, which is often referred to as a macro or define macro.

Here is how macros are declared:

# define name (parament-list) stuff where parament-list is a comma-separated symbol table that may appear in stuff.

If there is any space between the two, the parameter list is interpreted as part of the stuff.

# define SQUARE (x) x * x

This macro takes a parameter xreply 5. 0.

SQUARE (5)

How will the program be expressed, as follows

5 * 5int a = 5ash printf ("% d\ n", SQUARE (a + 1))

Looking at the code above, what do you think the result is?

When replacing text, the parameter x is replaced with a + 1, so the statement actually becomes: printf ("% d\ n", a + 1 * a + 1).

Add two parentheses to the macro definition and the problem is easily solved:

# define SQUARE (x) (x) * (x)

This preprocessing produces the desired effect:

Printf ("% d\ n", (a + 1) * (a + 1)); # define SQUARE (X) ((X) * (X)) int main () {int a = 5; int ret = SQUARE (axi5); / / int ret = ((a) * (a)); printf ("% d\ n", ret); return 0;}

There is also a macro definition:

# define DOUBLE (x) (x) + (x)

We use parentheses in the definition to avoid the previous problem, but this macro may have a new error.

Int a = 5; printf ("% d\ n", 10 * DOUBLE (a))

It seems to print 100, but in fact it is 55. After we found the replacement:

Printf ("% d\ n", 10 * (5) + (5))

The solution to this problem is to add a pair of parentheses on both sides of the macro definition expression.

# define DOUBLE (x) ((x) + (x)) # define DOUBLE (X) ((X) + (X)) int main () {int ret = 10 * DOUBLE (2); / / int ret = 10 * 2 + 2; printf ("% d\ n", ret); return 0;}

Tip: so macro definitions used to evaluate numeric expressions should be parenthesized in this way to avoid unexpected interactions between operators in parameters or adjacent operators when using macros.

3. Substitute define replacement rules

When you call a macro, first check the parameters to see if they contain any symbols defined by # define. If so, they are replaced first.

The replacement text is then inserted into the location of the original text in the program. For macros, parameter names are replaced by their values.

Finally, scan the result file again to see if it contains any symbols defined by # define. If so, repeat the above process.

Note:

Other variables defined by # define can appear in macro parameters and # define definitions. But for macros, there can be no recursion.

When the preprocessor searches for symbols defined by # define, the contents of the string constant are not searched.

# define PRINT (n) printf ("the value of" # n "is% d\ n", n) int main () {int a = 10; PRINT (a); int b = 20; PRINT (b); return 0;}

Connect a string with # define

# define PRINT (FORMAT, VALUE) printf ("the value is" FORMAT "\ n", VALUE); PRINT ("% d", 10); # define PRINT (n) printf ("the value of" # n "is% d\ n", n) int main () {int a = 10; printf ("the value of an is% d\ n", a); int b = 20; printf ("the value of b is% d\ n", b) Printf ("hello world\ n"); printf ("hello"world\ n"); return 0;}

III, the role of # 1, concept

# define ADD_TO_SUM (num, value) sum##num + = value; ADD_TO_SUM (5,10); / / the function is to add 10.#define CAT (XMagi Y) Xerox int main () {int class103 = 100; printf ("% d\ n", CAT (class, 103)); printf ("% d\ n", CAT (1,2)); return 0;}

2. Macro parameters with side effects

When a macro parameter appears more than once in the definition of a macro, if the parameter has side effects, you may be at risk when using the macro, leading to unpredictable consequences. The side effect is the permanent effect that occurs when the expression is evaluated. For example:

Xbirthday 1 / with no side effects / with side effects /

The MAX macro can demonstrate the problems caused by parameters that have side effects.

Int main () {int a = 10; int b = a + 1; return b = a + 1. What return b gets is 11, but if a changes, this expression is return 0 with side effects.} int Max (int x, int y) {return x > y? X: y;} int main () {int a = 5; int b = 8; / / int m = MAX (averse, baked +); / / int m = ((axed +) > (baked +)? (averse +): (baked +)); / / the argument to the function is int m = Max (averse% d\ n ", baked +); printf (" masked% d\ n ", m); / 8 printf (" axed% d\ n ", a); / 6 printf (" baked% d\ n ", b); / 9 return 0;}

/ / implementation of macros-1#define MAX (XMagol Y) ((X) > (Y)? (X): (y) int Max (int x, int y) {return x > y? X: y;} int main () {int a = 5; int b = 8; / / parameters of the macro are not calculated to be replaced directly / / and then participate in the operation int m = Max (averse% d\ n); printf ("masking% d\ n", m); / / 8 printf ("aversion% d\ n", a); / / 6 printf ("baked% d\ n", b) / / 9 return 0

3, comparison between macros and functions

Macros are usually used to perform simple operations. For example, find the larger of the two numbers.

# define MAX (a, b) ((a) > (b)? (a): (B)

The code used to call and return from the function may take more time than it actually takes to perform this small calculation. So the macro function is better in terms of program size and speed.

More importantly, the parameters of the function must be declared as a specific type. So functions can only be used on expressions of the right type. On the contrary, how can this macro be compared with the types that can be used for shaping, long shaping, floating point, and so on. Macros are type-independent.

The disadvantages of Macro

Each time you use a macro, a copy of the code defined by the macro is inserted into the program. Unless macros are short, it is possible to significantly increase the length of the program.

Macros cannot be debugged.

Macros are not rigorous enough because they are type-independent.

Macros may cause problems with operator precedence, making programs prone to errors.

Attribute # define defines the length of the macro function code each time the macro code is used, the macro code is inserted into the program. Except for very small macros, the length of the program increases dramatically. The function code appears in only one place. Every time you use this function, the same code in that place is called faster and there is extra overhead for function calls and returns, so relatively slow operators first macro parameters are evaluated in the context of all surrounding expressions, unless parentheses are added, otherwise the priority of adjacent operators may have unpredictable consequences Therefore, it is recommended that the macro should write more parentheses when the function parameter is evaluated only once when the function is called, and its result value is passed to the function. The result of the evaluation of the expression is easier to predict. Parameter parameters with side effects may be replaced to multiple locations in the macro body, so parameter evaluation with side effects can produce unpredictable results. The parameter of a parameter type macro is independent of the type, and can be used for any parameter type as long as the operation on the parameter is legal. The parameters of the function are related to the type, and if the type of the parameter is different, different functions are needed. Even if they perform different tasks, debug macros are inconvenient for debugging, recursive macros that can be debugged sentence by statement, functions that cannot be recursive, naming conventions.

So language itself can't help us distinguish between the two. Then one of our usual habits is:

1,#undef

This instruction is used to remove a macro definition.

# undef NAME / / if an existing name needs to be redefined, its old name must first be removed.

Command line definition

Many C compilers provide the ability to define symbols on the command line. Used to start the compilation process. For example, this feature is useful when we want to compile different versions of a program based on the same source file. Suppose an array of a certain length is declared in a program, if the machine memory is limited, we need a very small array, but another machine memory is uppercase, we need an array that can be capitalized. )

# define MAX 100 int main () {int m = MAX; # undef MAX int n = MAX;//err return 0;} # define M 500 int main () {# if Manners 100 printf ("\ n"); # elif Manners 200 printf ("hehe\ n"); # else printf ("heihei\ n"); # endif return 0;}

2, the file contains

We already know that the # include directive causes another file to be compiled. Just as it actually appears in the # include instruction. The replacement is simple: the preprocessor deletes the instruction and replaces it with the contents of the containing file. If such a source file is contained 10 times, it will actually be compiled 10 times.

How the header file is included:

# include "filename"

The path to the standard header file for the VS environment:

C:\ Program Files (x86)\ Microsoft Visual Studio 9.0\ VC\ include

The library file contains

# include's article on "sample Analysis of C language preprocessing" ends here. I hope the above content can be helpful to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report