当前位置:网站首页>Detailed explanation of C language conditional compilation
Detailed explanation of C language conditional compilation
2022-06-13 01:56:00 【richardgann】
The preprocessing process scans the source code , Make a preliminary transformation of it , Generate new source code for the compiler . It can be seen that the preprocessing process precedes the compiler to process the source code .
stay C In language , There is no inherent mechanism to perform some of the following functions : Include other source files at compile time 、 Defining macro 、 Decide whether to include some code at compile time according to the conditions . To do this , You need to use a preprocessor . Although at present most compilers contain preprocessors , But they are generally considered compiler independent . The preprocessing process reads the source code , Check the statement and macro definitions that contain preprocessing instructions , And the source code response conversion . Preprocessing also removes comments and extra white space from the program .
The preprocessing instruction is based on # The line of code that begins with the .# The number must be the first character on the line except any white space character .# Next is the instruction keyword , In keywords and # Any number of white space characters are allowed between numbers . The whole line of statements constitutes a preprocessing instruction , This instruction will do some conversion to the source code before the compiler compiles . Here are some preprocessing instructions :
Instructions purpose
# Empty command , No effect
#include Contains a source file
#define Defining macro
#undef Cancel defined macro
#if If the given condition is true , Then compile the following code
#ifdef If the macro has been defined , Then compile the following code
#ifndef If the macro is not defined , Then compile the following code
#elif If the front #if Given conditions are not true , The current condition is true , Then compile the following code
#endif End one #if……#else Conditional compilation block
#error Stop compiling and display error messages
One 、 File contains
#include The function of the preprocessing instruction is to expand the included file at the instruction . Inclusion can be multiple , That is to say, an included file can also contain other files . standard C The compiler supports at least octet nested inclusion .
The preprocessing process does not check whether a file has been included in the conversion unit and prevents multiple inclusion of it . In this way, when the same header file is included multiple times , Different effects can be achieved by giving compile time conditions . for example :
#define AAA
#include "t.c"
#undef AAA
#include "t.c"
To avoid header files that can only be included once being included multiple times , You can use compile time conditions in the header file to control . for example :
/*my.h*/
#ifndef MY_H
#define MY_H
……
#endif
There are two formats for including header files in a program :
#include <my.h>
#include "my.h"
The first method is to enclose the header file with angle brackets . This format tells the preprocessor to search the included header file in the header file of the compiler or external library . The second method is to enclose the header file with double quotation marks . This format tells the preprocessor to search the included header file in the source code file of the currently compiled application , If you can't find it , Then search the header file of the compiler .
The reason for using two different inclusion formats is , The compiler is installed in a public subdirectory , The compiled applications are in their own private subdirectories . An application contains both the common header file provided by the compiler , Also contains custom private header files . The adoption of two different inclusion formats enables the compiler to distinguish a set of common header files among many header files .
Two 、 macro
A macro defines an identifier that represents specific content . The preprocessing replaces the macro identifier that appears in the source code with the value of the macro definition . The most common use of macros is to define global symbols that represent a value . The second use of macros is to define macros with parameters , Such macros can be called like functions , But it expands the macro at the call statement , The actual parameters in the call are used to replace the formal parameters in the definition .
1.#define Instructions
#define Preprocessing instructions are used to define macros . The simplest form of this instruction is : First, the deity gives an identifier , Then give the code represented by this identifier . In the following source code , Just use this code to replace the identifier . This macro extracts some global values to be used in the program , Assign some memory identifiers .
#define MAX_NUM 10
int array[MAX_NUM];
for(i=0;i<MAX_NUM;i++) /*……*/
In this case , For those who read the program , Symbol MAX_NUM It has a specific meaning , The value it represents gives the maximum number of elements that the array can hold . This value can be used multiple times in a program . As an agreement , It is customary to define macros in all capital letters , In this way, it is easy to distinguish the macro identifier of program red from the general variable identifier . If you want to change the size of the array , Just change the macro definition and recompile the program .
The value represented by a macro can be a constant expression , It is allowed to include macro identifiers that have been previously defined . for example :
#define ONE 1
#define TWO 2
#define THREE (ONE+TWO)
Notice that the macro definition above uses parentheses . Although they are not necessary . But out of caution , It should be bracketed . for example :
six=THREE*TWO;
The preprocessing process converts the above line of code into :
six=(ONE+TWO)*TWO;
Without that bracket , Turn it into six=ONE+TWO*TWO; 了 .
Macros can also represent a string constant , for example :
#define VERSION "Version 1.0 Copyright(c) 2003"
2. Parameterized #define Instructions
Macros with arguments and function calls look a little similar . Take an example :
#define Cube(x) (x)*(x)*(x)
Any numeric expression or even function call can be used to replace parameters x. Here again, I would like to remind you to pay attention to the use of parentheses . The expanded macro is completely enclosed in a pair of parentheses , And the parameters are also contained in parentheses , This ensures the integrity of macros and parameters . Look at a usage :
int num=8+2;
volume=Cube(num);
Expand to (8+2)*(8+2)*(8+2);
If you don't have those parentheses, it becomes 8+2*8+2*8+2 了 .
The following usage is unsafe :
volume=Cube(num++);
If Cube It's a function , The above writing is understandable . however , because Cube Is a macro , So there will be side effects . The erasure here is not a simple expression , They will produce unexpected results . They unfold like this :
volume=(num++)*(num++)*(num++);
Obviously , The result is 10*11*12, instead of 10*10*10;
So how to use safely Cube Where's macro ? Operations that may have side effects must be moved outside the macro call :
int num=8+2;
volume=Cube(num);
num++;
3.# Operator
Appears in the macro definition # Operator converts the following argument to a string . Sometimes this usage is used as # Called the stringing operator . for example :
#define PASTE(n) "adhfkj"#n
main()
{
printf("%s\n",PASTE(15));
}
In the macro definition # Operator tells the preprocessor , Convert any parameter passed to the macro in the source code into a string . So the output should be adhfkj15.
4.## Operator
## Operator is used to join parameters together . The preprocessor will appear in ## The parameters on both sides are combined into one symbol . See the following example :
#define NUM(a,b,c) a##b##c
#define STR(a,b,c) a##b##c
main()
{
printf("%d\n",NUM(1,2,3));
printf("%s\n",STR("aa","bb","cc"));
}
Finally, the output of the program is :
123
aabbcc
Don't worry , Unless it is necessary or the macro usage is just relevant to the work at hand , Otherwise few programmers would know ## Operator . Most programmers have never used it .
3、 ... and 、 Conditional compilation instructions
Conditional compilation instructions will determine which code is compiled , And which are not compiled . Compilation conditions can be determined by the value of the expression or whether a particular macro is defined .
1.#if Instructions
#if The instruction detects a constant expression following the creation of another key . If the expression is true , Then compile the following code , Know to appear #else、#elif or #endif until ; Otherwise, do not compile .
2.#endif Instructions
#endif Used to terminate #if Preprocessing instruction .
#define DEBUG 0
main()
{
#if DEBUG
printf("Debugging\n");
#endif
printf("Running\n");
}
Because the program definition DEBUG Macro representative 0, therefore #if The condition is false , Do not compile subsequent code until #endif, So the program directly outputs Running.
If you remove #define sentence , The effect is the same .
3.#ifdef and #ifndef
#define DEBUG
main()
{
#ifdef DEBUG
printf("yes\n");
#endif
#ifndef DEBUG
printf("no\n");
#endif
}
#if defined Equivalent to #ifdef; #if !defined Equivalent to #ifndef
4.#else Instructions
#else An instruction is used for a #if After the instruction , When the front #if When the condition of the instruction is not true , Just compile #else Later code .#endif The instruction will point to the condition block above .
#define DEBUG
main()
{
#ifdef DEBUG
printf("Debugging\n");
#else
printf("Not debugging\n");
#endif
printf("Running\n");
}
5.#elif Instructions
#elif The preprocessing instructions synthesize #else and #if Role of instructions .
#define TWO
main()
{
#ifdef ONE
printf("1\n");
#elif defined TWO
printf("2\n");
#else
printf("3\n");
#endif
}
The program is well understood , The output is zero 2.
6. Other standard directives
#error Instruction will cause the compiler to display an error message , Then stop compiling .
#line Instructions can change the file and line numbers that the compiler uses to indicate warnings and errors .
#pragma The directive has no formal definition . The compiler can customize its purpose . A typical usage is to prohibit or allow some annoying warning message .
边栏推荐
- Vs how to enter chromium subprocess debugging
- 兴趣相似的受众群体
- [the second day of actual combat of smart lock project based on stm32f401ret6 in 10 days] (lighting with library function and register respectively)
- [pytorch FAQ] numpy:dll load failed while importing_ multiarray_ Umath: the specified module could not be found.
- Stm32 3*3 matrix key (register version)
- Cmake has no obvious error after compilation, but prompts that pthread cannot be found
- Read routing table
- 30: Kakfa simulates JSON data generation and transmission
- 水管工遊戲
- 微服务开发环境搭建
猜你喜欢

Calculation of accuracy, recall rate, F1 value and accuracy rate of pytorch prediction results (simple implementation)

受众群体应该选择观察模式还是定位模式?

分享三个关于CMDB的小故事

Devaxpress Chinese description --tcxpropertiesstore (property store recovery control)

Implementation of pointer linked list
![[wsl2]wsl2 migrate virtual disk file ext4 vhdx](/img/e9/4e08e07c2de2f99c2938e79f7f1c44.png)
[wsl2]wsl2 migrate virtual disk file ext4 vhdx

Simple ranging using Arduino and ultrasonic sensors

Magics 23.0 how to activate and use the slice preview function of the view tool page

六、出库管理功能的实现

What did Hello travel do right for 500million users in five years?
随机推荐
What did Hello travel do right for 500million users in five years?
Devaxpress Chinese description --tcxpropertiesstore (property store recovery control)
Devaxpress Chinese description -- tdxgallerycontrol object (gallery component)
开发者来稿|AMD赛灵思中文论坛分享 - 提问的智慧
In the third quarter, the revenue and net profit increased "against the trend". What did vatti do right?
CXGRID keeps the original display position after refreshing the data
Interruption of 51 single chip microcomputer learning notes (external interruption, timer interruption, interrupt nesting)
Decompression and compression of chrome resource file Pak
Compiling minicom-2.7.1 under msys2
Shell command notes
Topic creation and running example of ROS
Delphi implements adding a column of serial number to the CXGRID list
The scientific innovation board successfully held the meeting, and the IPO of Kuangshi technology ushered in the dawn
如何利用您的自有数据来实现营销目标?
Numpy multidimensional array transpose transpose
水管工游戏
Vivo released originos ocean, and the domestic customized system is getting better and better
TensorFlow 2.x 多显卡分布式训练
[pytorch FAQ] numpy:dll load failed while importing_ multiarray_ Umath: the specified module could not be found.
matplotlib画图中文乱码