当前位置:网站首页>In depth analysis - Pretreatment
In depth analysis - Pretreatment
2022-07-29 02:29:00 【Shilipo Xiaobai】
List of articles
Depth analysis : data
Depth analysis : recursive
Depth analysis : Structure
Depth analysis : Dynamic memory management
Depth analysis : File operations
Depth analysis : Preprocessing
List of articles
Preface
C The preprocessor looks at the program before it executes ( So it is called preprocessor ). This article will focus on C Preprocessor of language , Deep profiling preprocessing instructions .
One 、 Predefined symbols
Symbol | effect |
---|---|
FILE | Source files to compile |
LINE | The current line number of the file |
DATE | The date the file was compiled |
TIME | When the file was compiled |
STDC | If the compiler follows ANSI C, Its value is 1, Otherwise, it is not defined |
These predefined symbols are built into the language
printf("file:%s line:%d\n", __FILE__, __LINE__);
Two 、 predefined
1. #define Define identifier
1. Grammatical structure
#define name stuff
2. Call mode
call | effect |
---|---|
#define MAX 1000 | Define a global constant MAX, The size is 1000 |
#define reg register | by register This keyword , Create a short name |
#define do_forever for( ; ; ) | Replace an implementation with a more vivid symbol |
#define CASE break; case | Writing case Automatically put break write |
3. matters needing attention
stay define When defining identifiers Don't suggest add
;
#define MAX 100;
#define MIN 10;
int ret = MAX * MIN;
because #define The definition is to replace it into the code during preprocessing , Something will go wrong at this moment . So strong Don't suggest When defining the identifier, add ;
2. #define Defining macro
1. Grammatical structure
#define name( parament-list ) stuff
#define The mechanism includes a provision , Allow parameters to be replaced with text , This implementation is often called a macro (macro) Or define macro (define macro)
2. Invoke the sample
#define SQUARE(x) x * x
The ginseng | Replace | result |
---|---|---|
SQUARE( 5 ); | 5 * 5 | 25 |
SQUARE( 5 + 1 ) | 5 + 1 * 5 + 1 | 11 |
SQUARE( 5 + 2 + 1 ) | 5 + 2 + 1 * 5 + 2 + 1 | 15 |
#define SQUARE(x) (x) * (x)
The ginseng | Replace | result |
---|---|---|
SQUARE( 5 ); | ( 5 ) * ( 5 ) | 25 |
SQUARE( 5 + 1 ) | ( 5 + 1 ) * ( 5 + 1 ) | 36 |
SQUARE( 5 + 2 + 1 ) | ( 5 + 2 + 1 ) * ( 5 + 2 + 1 ) | 64 |
#define SQUARE(x) (x) + (x)
The ginseng | Replace | result |
---|---|---|
2 * SQUARE( 5 ); | 2 * ( 5 ) + ( 5 ) | 15 |
2 * SQUARE( 5 + 1 ) | 2 * ( 5 + 1 ) + ( 5 + 1 ) | 18 |
2 * SQUARE( 5 + 2 + 1 ) | 2 * ( 5 + 2 + 1 ) + ( 5 + 2 + 1 ) | 24 |
#define SQUARE(x) ((x) + (x))
The ginseng | Replace | result |
---|---|---|
2 * SQUARE( 5 ); | 2 * ( ( 5 ) + ( 5 ) ) | 20 |
2 * SQUARE( 5 + 1 ) | 2 * ( ( 5 + 1 ) + ( 5 + 1 ) ) | 24 |
2 * SQUARE( 5 + 2 + 1 ) | 2 * ( ( 5 + 2 + 1 ) + ( 5 + 2 + 1 ) ) | 32 |
3. matters needing attention
So the macro definitions used to evaluate numeric expressions should be bracketed in this way , Avoid using macros due to operators or... In parameters Unexpected interactions between adjacent operators
3. #define Usage rule
1. Replacement rules
Extend... In a program #define When defining symbols and macros , There are several steps involved :
- When calling a macro , First, check the parameters , See if it contains any information from #define Defined symbols . If it is , They are replaced first .
- The replacement text is then inserted into the program at the location of the original text . For macros , Parameter names are replaced by their values .
- Last , Scan the result file again , See if it contains any information from #define Defined symbols . If it is , Repeat the above process .
2. Naming conventions
Generally speaking, the syntax of function macro is very similar . So language itself can't help us distinguish the two . Well, one of our usual habits is : Capitalize all macro names Do not capitalize all function names
3. matters needing attention
Use... In the program #define When defining symbols and macros , We need to pay attention to :
- Macro parameters and #define Other... Can appear in the definition #define Variables defined . But for macros , No recursion .
- When the preprocessor searches #define When defining symbols , The contents of string constants are not searched .
3、 ... and 、 Macro and function comparison
1. The advantages of macros
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))
Advantages of macros over functions :
- The code used to call and return from the function may take more time than actually performing this small computation . So the macro ratio function in the program In terms of scale and speed .
- More importantly, the parameters of a function must be declared as specific types . So functions can only be used on expressions of the right type . On the contrary, how can this macro To be suitable for shaping 、 Long integer 、 Floating point type can be used for > To compare the types of . Macros are type independent .
2. The disadvantages of macros
The disadvantages of macros over functions :
- Every time you use a macro , A macro defined code will be inserted into the program . Unless the macro is short , Otherwise, the length of the program may be greatly increased .
- Macros cannot be debugged .
- Macro is type independent , It's not rigorous enough .
- Macros can cause operator priority problems , It is easy for Cheng to make mistakes .
- Macros can sometimes do things that functions can't do .
3. Detailed comparison table
Belong to sex | #define Defining macro | function |
---|---|---|
Code length | Every time I use it , Macro code is inserted into the program . Except for very small macros outside , The length of the program will increase significantly | Function code only appears in one place ; Each time When using this function , Call the same... In that place A code |
Execution speed | faster | There is an extra cost of calling and returning functions , So it's relatively slow |
Operator priority | Macro parameters are evaluated in the context of all surrounding expressions , Unless added Upper bracket , Otherwise, the priority of adjacent operators may produce unpredictable post fruit , Therefore, it is recommended that macros be written with more parentheses . | Function parameters are evaluated only once when the function is called Time , Its result value is passed to the function . expression The evaluation result of is easier to predict . |
Parameters with side effects | Parameters may be replaced at multiple locations in the macro body , So ginseng with side effects Number evaluation may produce unpredictable results . | Function parameters are evaluated only once when passing parameters , The result is easier to control . |
Parameter type | Macro parameters are type independent , As long as the operation on parameters is legal , It can To be used for any parameter type . | The arguments to the function are type dependent , If you take part in The types of numbers are different , You need different functions , Even if they perform different tasks . |
debugging | Macros are inconvenient to debug | Functions can be debugged statement by statement |
recursive | Macros cannot be recursive | Functions can be recursive |
Four 、 Command line definition
many C Our compiler provides a capability , Allows symbols to be defined on the command line . Used to start the compilation process . for example : When we want to... According to the same source file When compiling different versions of a program , This feature is useful .( Suppose an array of a certain length is declared in a program , If Machine memory is limited , We need a very small array , But the other machine's memory is uppercase , We need an array that can be capitalized .)
#include <stdio.h>
int main() {
int array[ARRAY_SIZE];
int i = 0;
for (i = 0; i < ARRAY_SIZE; i++) {
array[i] = i;
}
for (i = 0; i < ARRAY_SIZE; i++) {
printf("%d ", array[i]);
}
printf("\n");
return 0;
}
Compile instructions :
gcc -D ARRAY_SIZE=10 programe.c
5、 ... and 、 Conditional compilation
When compiling a program, if we want to translate a statement ( A set of statements ) It's convenient to compile or discard . Because we have conditional compilation instructions .
Debugging code , It's a pity , Reservation is in the way , So we can selectively compile .
#include <stdio.h>
#define __DEBUG__
int main() {
int i = 0;
int arr[10] = {
0};
for (i = 0; i < 10; i++) {
arr[i] = i;
#ifdef __DEBUG__
printf("%d\n", arr[i]);// To see if the array assignment is successful .
#endif //__DEBUG__ }
return 0;
}
}
Common conditional compilation instructions
1. Single branch
#if Constant expression
//...
#endif // Constant expressions are evaluated by the preprocessor .
2. Multiple branches
#if Constant expression
//...
#elif Constant expression
//...
#else
//...
#endif
3. Judge whether it is defined
#if defined(symbol)
#ifdef symbol
#if !defined(symbol)
#ifndef symbol
4. Nested instruction
#if defined(OS_UNIX)
#ifdef OPTION1
unix_version_option1();
#endif
#ifdef OPTION2
unix_version_option2();
#endif
#elif defined(OS_MSDOS)
#ifdef OPTION2
msdos_version_option2();
#endif
#endif
summary
C One of the important attachments of language is C The preprocessor .C The preprocessor follows the preprocessor instructions , Adjust the source code before compiling it . It provides more and more convenient ways to write programs , yes C A very important part of language .
边栏推荐
- 响应式织梦模板家装建材类网站
- QT learning notes -37.qregex and regular expressions
- 即时通讯场景下安全合规的实践和经验
- MQTT例程
- 0728~面试题梳理
- After 4 years of testing experience, I finally entered Alibaba. Two months later, I chose to resign naked
- Responsive Zhimeng template decoration design website
- 详解JS的四种异步解决方案:回调函数、Promise、Generator、async/await
- How to guarantee password security? How does the secure browser manage passwords?
- When I look at the source code, what am I thinking?
猜你喜欢
裂开了,一次连接池参数导致的雪崩问题
Talk about 11 tips for interface performance optimization
How to guarantee password security? How does the secure browser manage passwords?
When I look at the source code, what am I thinking?
Time pit in MySQL driver
如果非要在多线程中使用 ArrayList 会发生什么?
第3章业务功能开发(线索备注的删除和修改)
密码安全如何保障?安全浏览器如何管理密码?
详解JS的四种异步解决方案:回调函数、Promise、Generator、async/await
Talk about the implementation principle of feign
随机推荐
Day 14: continued day 13 label related knowledge
How awesome is the architecture of "12306"?
发布融资需求1.29亿元,大科城项目路演持续浇灌科创“好苗子”
如果时间不够,无法进行充分的测试怎么办?
Quanzhi t3/a40i industrial core board, 4-core [email protected] The localization rate reaches 100%
工程经济学知识点总结
Keil5 open the engineering prompt not found device solution
Never pass a request to an asynchronous thread. There is a hole
一文搞懂 Redis 架构演化之路
Day 15 (VLAN related knowledge)
快速掌握Nodejs安装以及入门
响应式织梦模板户外露营类网站
6年测试经验,教大家测试~如何把控项目
How to customize a new tab in Duoyu security browser?
详解异步任务:任务的状态及生命周期管理
如果非要在多线程中使用 ArrayList 会发生什么?
KBxxxxxx不一定是补丁,也可能是某个问题解决方案的描述
time_wait和close_wait产生原因
redis为什么快,消息队列,单线程
连PostgreSQL问题:expected authentication request from server, but received v