当前位置:网站首页>Program environment and preprocessing (Part 2): define, undef, command line compilation, conditional compilation, file inclusion (super full collation, recommended collection!!!
Program environment and preprocessing (Part 2): define, undef, command line compilation, conditional compilation, file inclusion (super full collation, recommended collection!!!
2022-07-27 05:36:00 【vpurple__】

Catalog
1.2.1 #define Define identifier
1.2.3 #define Replacement rules
1.2.5 Macro parameters with side effects
1.2.6 Macro and function comparison
1.6.1 How header files are included :
1、 Pretreatment details
1.1 Predefined symbols
These predefined symbols are Language built in Of .
__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
The code is shown as follows :
purpose : It can be found in the administrator log file , Record relevant information .

1.2 #define
1.2.1 #define Define identifier
grammar : #define name stuff
Be careful : stay define Don't add a semicolon to the last side of the definition .
With #define print printf("hello\n") For example :

// Define a number
#define MAX 1000
// by register This keyword , Create a short name
#define reg register// Replace an implementation with a more vivid symbol
#define do_forever for(;;)
// Writing case Automatically put break write .
#define CASE break;case
// If you define stuff Too long , It can be divided into several lines , Except for the last line , Add a... After each line The backslash ( Line continuation operator ).
// Line continuation operator , Equivalent to using backslash \ Escape carriage return , Make enter not enter , So as to achieve the effect of one line of code .
#define DEBUG_PRINT printf("file:%s\tline:%d\t \
date:%s\ttime:%s\n" , \
__FILE__,__LINE__ , \
__DATE__,__TIME__ )
Macros have parameters , pure #define The definition has no parameters
1.2.2 #define Defining macro
#define The mechanism includes a provision , Allow parameters to be replaced with text , This implementation is often called a macro (macro) Or the definition macro (define macro).
Here's how the macro is declared :
#define name( parament-list ) stuff
name yes Macro name ,parament-list yes parameter list ,stuff It's the text , That is to say Macrobody , The content of the macro .
Among them parament-list It's a list of symbols separated by commas , They may appear in stuff in .
Be careful : The left parenthesis of the argument list must be the same as name Next door neighbor . If there is any gap between the two , The parameter list will be interpreted as stuff Part of .

It's easy to get wrong : Macro parameters are not entered after calculation, but directly replaced .

Optimize the code shown above as follows :

Add up :

advice : Try not to be stingy with parentheses when writing macros , Otherwise, it is easy to cause the calculation order of operators in parameters and expressions in macro content , Not up to our expected order of operations .
1.2.3 #define Replacement rules
Extend... In a program #define When defining symbols and macros , There are several steps involved .
1. 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 .
2. 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 .
3. Last , Scan the result file again , See if it contains any information from #define Defined symbols . If it is , Just repeat Describe the process .

Be careful :
1. Macro parameters and #define Other... Can appear in the definition #define Defined symbols . But for macro , No recursion .
2. When the preprocessor searches #define When defining symbols , The contents of string constants are not searched .
1.2.4 # and ##
# effect
First of all, add a small point :
Strings have the characteristics of automatic connection .

Use # , Change a macro parameter into the corresponding string .

## effect
## You can combine the symbols on both sides of it into one symbol .
It allows macro definitions to create identifiers from detached pieces of text .
notes : Such a connection must produce a legal identifier . Otherwise the result is undefined .

1.2.5 Macro parameters with side effects
When macro parameters appear more than once in the macro definition , If the parameter has side effects , Then there may be danger when using this macro , The result is unpredictable .
The side effect is the permanent effect of expression evaluation .
n = x + 1; // No side effects
n = x ++; // With side effects ( Here, the side effect refers to that after the program finishes this line, it will not only n assignment , Will also be right x Self increasing )
for example :

1.2.6 Macro and function comparison
Macros are usually used to perform simple operations . For example, find the larger of the two numbers .
The advantages of macro
1. The code used to call and return from the function may take more time than actually performing this small computation . therefore Macros are better than functions in terms of program size and speed .
2. Macros are type independent .
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 be applied to shaping 、 Long integer 、 Floating point type, etc be used for > To compare the types of .
The disadvantages of macro :
1. 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 .
2. Macros can't be debugged . When performing debugging operations , Macros have been replaced beyond recognition during preprocessing .
3. Macro is type independent , It's just Not rigorous enough .
4. Macros can cause operator priority problems , It is easy for Cheng to make mistakes .
5. Macros can sometimes do things that functions can't do . such as : Macro parameters can have types , But functions can't do it .
#define MALLOC(num, type)\
(type *)malloc(num * sizeof(type))
...
// Use
MALLOC(10, int);// Type as parameter
// After preprocessor replacement :
(int *)malloc(10 * sizeof(int));1.2.7 Naming conventions
Capitalize all macro names Do not capitalize all function names
1.3 #undef
This instruction is used to remove a macro definition .
#undef NAME
// If an existing name needs to be redefined , Then its old name must first be removed .

1.4 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 compile different versions of a program according to the same source file , This feature is useful .( 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 on the other hand Machine memory 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 :
//linux Environment demonstration
gcc -D ARRAY_SIZE=10 programe.c
1.5 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 .
for instance : Debugging code , It's a pity , Reservation is in the way , So we can Selective compilation .

Common conditional compilation instructions :
1.
#if Constant expression
//... If the constant expression is true, it will participate in the compilation
#endif
// Constant expressions are evaluated by the preprocessor .
Such as :
#define __DEBUG__ 1
#if __DEBUG__
//..
#endif
2. Conditional compilation of multiple branches
#if Constant expression
//...
#elif Constant expression
//...
#else
//...
#endif
3. Judge whether it is defined
#if defined(symbol)
#ifdef symbol
#if !defined(symbol)// Judge Do not define participation in compilation, preceded by !
#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
#endif1.6 File contains
We already know , #include Instruction can cause another file to be compiled . It's like it actually appears in #include Where the order is equally . It's a simple alternative : The preprocessor first removes this instruction , And replace... With the contents of the containing file . Such a source file is contained 10 Time , So it's actually compiled 10 Time .
1.6.1 How header files are included :
< > and " " The main reason is that the search strategy is different :
<> Search strategy : Go directly to the library directory to find
“ ” Search strategy :1. First go to the path where the code is located to find 2. If the first step cannot be found , Then go to the library directory to find
The local file contains
#include "filename"
First, find the source file in the directory , If the header file is not found , The compiler looks like a library function header file Find header files in standard locations . If If you cannot find it, you will be prompted with a compilation error .
Linux The path to the standard header file of the environment :
/usr/include
VS The path to the standard header file of the environment :
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include // This is a VS2013 The default path for
The library file contains
#include <filename>
Find the header file Go directly to the standard path to find , If no compilation error is found .
Please note that :
Library files can also be used “” The form of includes , But this is less efficient , It's not easy to distinguish between library files and local files .
1.6.2 Nested files contain
If the header file accidentally contains , This leads to duplication and redundancy of file contents . How to solve this problem ?
answer : Conditional compilation .( Prevent header files from repeatedly containing )
The beginning of each header file is written :

Or add :
#pragma once
You can avoid the repeated introduction of header files .
A little sigh
Now I have a lot of snacks 、 A few bottles of water 、 A computer 、 An online class 、 The momentum of a blog writing for a day , I owe too much before , It needs to be mended well .
If there are any mistakes or deficiencies in this blog , Welcome to correct and supplement , I hope that's helpful . Thank you for reading (^__^)

边栏推荐
- 用户管理-分页
- 蓝图-类视图方法
- 如何快速上手强化学习?
- Li Hongyi machine learning team learning punch in activity day05 --- skills of network design
- torch中乘法整理,*&torch.mul()&torch.mv()&torch.mm()&torch.dot()&@&torch.mutmal()
- [codeworks round 801 div2 D tree queries] tree greedy conclusion
- How to quickly and effectively solve the problem of database connection failure
- 用pygame自己动手做一款游戏01
- numpy 数据类型转化
- 后台频道组管理功能实现
猜你喜欢
随机推荐
块,行内块元素之间存在间隙
分享一道关于#define的选择题(内含#define在预编译时的替换规则,程序环境和预处理相关知识)
Qsort - the sorting function in C language (with void*, callback function knowledge points
elment-ui使用方法
Hi3516dv300 environment setup
BIO、NIO、AIO区别
GCC 编译选项
蓝图-类视图方法
JDBC API details
李宏毅机器学习组队学习打卡活动day05---网络设计的技巧
B1030 perfect sequence
用户的管理-限制
p7 day1 初识Flask框架
redis锁
李宏毅机器学习组队学习打卡活动day04---深度学习介绍和反向传播机制
C语言做一个小迷宫
程序环境和预处理(上):一个程序是怎么成功运行的?
Carmaker quick start lesson 4 developing 48V P1 hybrid system
322 coin change of leetcode
Flask框架创建项目初期总结









