当前位置:网站首页>C language | preprocessing
C language | preprocessing
2022-04-22 07:25:00 【ZXXL】
The process of compiling a program
First step : Pretreatment stage
demo.c --> demo.i( an # Chinese content )
The second step : Compile phase
demo.i --> demo.S ( Assembly files )
The third step : Assembly stage
demo.S --> demo.o ( No binaries with addresses )
Step four : Link phase
demo.o --> demo.elf ( Binary file with address )
The first three stages only need to be declared , Not yet linked into segments
In the link stage, you need to verify the source code
- Complete all the codes used ( Include _start)
- piecewise
- Add the executable address
About ELF file
.o A file is an object file , It is a kind of redirectable file , Usually, the ELF Format preservation , It contains the entry marks for each function , describe , When the program is to be executed, you also need to link (link). Link is to link multiple .o File chain into an executable file .
stay win Under the platform , The redirect file used to link can also be PE Format .obj file
When multiple programming languages want mixed compilation , It can be compiled into .o file , Link again (link) Make an executable .
Preprocessing instruction
Machine instructions : Let the processor perform an operation
Compile instructions : Let the compiler perform a compilation action
C file ——> Machine instructions + Compile instructions ( The preprocessing stage executes instructions )
Pretreatment stage :
C Language before compiling the source program , Some special preprocessing instructions will be explained first ( For example, we used #include The file contains instructions ), Generate a new source program ( This process is called compilation preprocessing ), Then do the usual compilation .
To distinguish between preprocessing instructions and general C sentence , All preprocessing instructions are written with the symbol " #" start , And no semicolon at the end . for example :
#define
MAX_ CNT 100
Preprocessing instructions can appear anywhere in the program , Its scope is from where it appears to the end of the file . Traditionally, we try to write preprocessing instructions at the beginning of the source program , In this case , Its scope is the whole source program file
C The preprocessing instructions provided by the language mainly include :
File contains : #include
Definition of macro : #define
Conditional compilation : #ifdef, #if_ _#elf, #ifndef
The file contains instructions
In the process of program development , When users develop programs , You often need to call ( quote ) Other existing programs , At this time, you need to include these into your file , In general use include( Nature is copy), The general format is as follows :
#indlude “ File with path ”
include Use of subsequent paths ” Or use <>?
< file name >:
Indicates that the system defaults to the specified - - Some records , such as /usr/indude Let's find the file with the specified file name , The premise is that these files must be in the default directory
advantage : Yes, you can omit the path
“ File with path ":
Means to find this file in the specified path first , If you don't have this file , Also go to the system default path to find this file
advantage : Yes, it includes <> The function of
File with path : It could be an absolute path , It could be a relative path
such as : If hello.c It is the same level directory as the code , It can be written as follows :
#indlude “/var/GZE2020/hello.c”
#indlude “./hello.c”
#incude “hello.c” // The same as above also indicates the current directory
Be careful
When a .c The file contains too many function functions , When our demand function is only a minority :
- include Although it can directly include .c file , But in the preprocessing phase, the whole .c Copy the contents of the file to the calling file , It leads to inefficiency
- include It doesn't say where the library file is , Instead, the compiler traverses the default library file according to the environment variables in the link phase , Generally used to include .h file , We need to encapsulate and declare the code in the file that we want to be called by others into the header file , At this point, the code you want to call is compiled into a library , At compile time, the compiler automatically finds , It will not produce 1 Medium problem
Three ways to call a piece of code
- #include “lib.c”
- Translate it into .o file After that, it is actively provided in the compilation link stage
- Compiled into the library ( Make it .so file And put it into the default lib Catalog ) The compiler automatically finds
When the function function in the library function is unknown to transfer parameters and return values , It is inconvenient to declare functions directly ; So take a declaration before calling .h file ( This file is dedicated to loading declarations for callers 、 Tell the caller which functions 、 Pass parameter and return type )
A procedure that provides or invokes code
Write a function containing **.c file after , Compile it into .o file Link directly to others ; Or make a library .so file ** Put it in a fixed directory and call others , At the same time through .h file Provide .c Prototype declaration of each function in the file
lib.c
int add_func(int a, int b)
{
return a + b;
}
int sub_func(int a, int b)
{
return a - b;
}
lib.h
int add_func(int , int );
int sub_func(int , int );
test.c( What others write needs to call what you write lib.c Code of function function in )
//#include "lib.c"
//int add_func(int , int );
//int sub_func(int , int );
#include "lib.h"
int main(int argc, char *argv[])
{
int c;
int a = 1;
int b = 2;
c = add_func(a, b);
c = sub_func(a, b);
return 0;
}
Macro definition instruction
stay C In language , Mainly through preprocessing instructions “#define" To define a macro , The general format is as follows :
#define Macro name Macrobody
It is actually the complex content expressed in simple form allowed by the compiler , In the preprocessing stage, the macro name has been transformed and expanded as a symbol
In actual use , There are two situations , They are without parameters and with parameters
With no arguments
#define Macro name character string , such as
#define DEBUG 10
The string on the right can also be omitted , such as
#define DEBUG
Indicates that the macro is empty , During preprocessing, it will be processed as empty , So it's ok , No mistake. .
With parameters
#define Macro name ( parameter list ) character string
Macros with parameters expand , Only simple replacement of characters and parameters , No calculation operation . So when defining macros , Generally, the parameters of the string are enclosed in a small bracket .
Example
#include <stdio.h>
#define MAX 100
#define ADD(x,y) (x+2*y)
#define strcpy__(dst, src) strcpy(dst, #src)
//# It means string , Will follow # The following macro parameters are converted into a string
strcpy__(buff,abc) amount to strcpy__(buff,“abc”)
#define FUN(arg) my##arg//## Is a connector.
be FUN(ABC)
Equivalent to myABC
#define SH_MINOR_LED_ON 0
#define SH_MINOR_LED_OFF 1
#define a1 1
#define a2 2
int main()
{
printf("add: %d\n", 3*ADD(1,2));
//printf("%s\n", CONCAT(1,2));
printf("%s, %d, %s\n", __FILE__, __LINE__, __FUNC__);
return 0;
}
When the content of a macro is complex , You can use \ Line break , as follows
# define atomic_compare_and_exchange_val_rel(mem, new, old) \ __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ mem, new, old, __ATOMIC_RELEASE)
ANSI Standard predefined macro names
__FILE__ Is a built-in macro , Represents the file name of the source file , Use %s Print
__LINE__ Is a built-in macro , Represents the line number of this line of code , Use %d Print
__DATE__ Macro instructions , It is in the form of month / Japan / A string of years , Represents the date when the source file was translated into code , Use %s Print
__TIME__ The time when the source code is translated to the object code is included as a string in __TIME__ in . The string form is : branch : second
__STDC__ If it is ANSI standard c The constant is 1, If it is other non ANSI The standard depends on the platform
#include <stdio.h>
int main()
{
printf("filename:%s\n",__FILE__);
printf("filenumber:%d\n",__LINE__);
printf("maketime: %s, %s\n", __DATE__, __TIME__);
return 0;
}
The difference between macro function and function
From the whole use process, we can find , Macro definition with parameters , The form in the source program is very similar to the function . But there are essential differences between the two :
- The macro definition does not involve the allocation of storage space 、 Parameter type matching 、 Parameter passing 、 Return value problem
- Function calls are executed while the program is running , Macro replacement is only carried out in the compilation preprocessing stage . Therefore, macros with parameters are more efficient than functions ( It is more efficient than the processor , But the compilation efficiency will be reduced )
- Macro functions are suitable for code blocks with high usage but simple logic .
that , How to use macro functions ?
Suppose there is such a function to compare the size of two numbers or expressions , First, we write it as a macro definition :
#define MAX( a, b) ( (a) > (b) (a) : (b) )
secondly , Implement it with functions :
int max( int a, int b)
{
return (a > b a : b)
}
If this code is to be used frequently , Let's choose to use function macros or functions to implement . Obviously, we won't choose to use functions to complete this task , There are two reasons :
- Function calls bring extra overhead , It needs to open up a stack space , Record the return address , Stack parameters , Returning from a function also frees the stack . This overhead not only reduces code efficiency , And the amount of code will increase greatly , Using macro definitions is better than functions in terms of code size and speed ;
2. The parameters of a function must be declared as a specific type , So it can only be used on expressions of the appropriate type , If we want to compare the size of two floating-point types , You have to write another comparison function specifically for floating-point types .
conversely , The macro definition above can be used to shape 、 Long plastic surgery 、 Single floating point 、 Double floating point and anything else that can be used “>” The operator compares the type of value size , in other words , Macros are type independent . Compared with using functions , The disadvantage of using macros is that every time you use macros , A copy of the macro definition code is inserted into the program . Unless the macro is very short , Otherwise, using macros will greatly increase the length of the program .
There are some tasks that cannot be implemented by functions at all , But macro definition is a good implementation . For example, parameter types cannot be passed to functions as parameters , But you can pass the parameter type to a macro with parameters .
See the following example :
#define MALLOC(n, type) \
((type * ) malloc ( (n)* sizeof (type)))
Use this macro , We can allocate a certain amount of space for any type , And return a pointer to this space . We can observe the exact working process of this macro :
int *ptr;
ptr = MALLOC ( 5, int );
// After expanding this macro, the result :
ptr = (int *) malloc ( (5) * sizeof(int) );
This example is one of the classic applications of macro definition , Completed the function that the function cannot complete .
Conditional compilation instructions
Conditional compilation refers to the preprocessing phase , Identify which code needs to be compiled into the program , Which code doesn't need to be compiled , This is mainly through conditional compilation instructions #if、 #ifdef、 #ifndef And so on
Use scenarios
- When you want to use a file on different platforms, such as win、x86、arm( Compilers are different ) when , The code that implements the same function may be different , At this point, you need to tell the compiler to compile the corresponding branch code
- When calling a piece of code nested ,#include " some .h file " This has expanded a piece of code , If the code is called twice , Will be expanded repeatedly .h Code in file , At this time, you need to .h file Judge whether the function code has been expanded
Application 2 Example
.h file
#ifndef __MYFUNC_H__
#define __MYFUNC_H__
int add_func(int, int);
#endif
.c file
#include "func.h"
#include "func.h"// Simulate nested calls
int main(int argc, char *argv[])
{
int a = 1,b = 2, c;
c = add_func(1, b);
printf("c: %d\n", c);
return 0;
}
#if Structure general format :
#if Conditions 1
…code1…
#elif Conditions 2
…code2…
#else
…code3…
#endif
Implement the following logic :
- If the condition 1 establish , Then the compiler will put #if And #elif Between code1 Code compiled in ( Be careful : It's compiled , Not execution , For peace if-else It's different )
- If the condition 1 Don't set up 、 Conditions 2 establish , Then the compiler will put #elif And #else Between code2 Code compiled in
- If the condition 1、2 It doesn't work , Then the compiler will put #else And #endif Between code3 Compile it
- Be careful , After conditional compilation , Add one on the last side #endif , Otherwise, the consequences will be very serious ( Think about the consequences for yourself )
#if and #elif The latter condition is generally to judge the macro definition rather than the variable , Because conditional compilation is a judgment made before compilation , Macro definitions are also defined before compilation , Variables are generated at runtime 、 It has the meaning of use
#ifdef Structure general format :
#ifdef MAX
…code…
#endif
If you have defined MAX This macro , will code Compile it .
#ifdef MAX
…code1…
#else
…code2…
#endif
#ifndef Structure general format :
#ifndef MAX
…code…
#endif
If not previously defined MAX This macro , will code Compile it .
What are the common preprocessing instructions ? What's the usage? ?
版权声明
本文为[ZXXL]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204220610405427.html
边栏推荐
- 最强操作符学习之路(C语言详解)
- 区间求和的问题——差分
- 437. 路径总和 III
- CSDN text style
- Error: (vlog-2892) Net type of 'i_ yc422' must be explicitly declared.
- (四)Sql Server中的字符集(排序规则)
- 最强数组学习之路
- Raspberry Pi 4b
- Complete a student information management system and systematically practice object-oriented, function, string and other knowledge. Realize the comprehensive application of knowledge. Use classes, fun
- If an error is reported, process the ES6 filter to filter the array
猜你喜欢

vivado生成和调用edf网表文件

1. Compile the following three modules of student information management system: and detect the implementation. 1. Add student information 4. Query student information 5. Query all student information

. net learning notes (I) -- introduction, advantages, design ideas, principles and applications of generics
![[DRC RTSTAT-1] Unrouted nets: 1 net(s) are unrouted](/img/bf/0851c85f766432f6d6306d52e67188.png)
[DRC RTSTAT-1] Unrouted nets: 1 net(s) are unrouted

JVM中唯一一个不会发生GC和OOM的存储区域

Two algorithm questions for Microsoft intern interview -- 20220119

顺序表 增删查(找)

快排与归并排序

Anaconda installation and use

Beyond Compare“授权密钥已被吊销”的解决办法
随机推荐
Quartus II防止信号被综合
MySQL learning notes
为什么非主键索引的叶子结点存放的数据是主键值
详解冒泡序列与数组名
Redis进阶
区间求和的问题——差分
Precautions for using feign to make remote calls
Written examination for summer internship of meituan spring recruitment -- 20220312
Host cannot Ping virtual machine in bridging mode
1. Compile the following three modules of student information management system: and detect the implementation. 1. Add student information 4. Query student information 5. Query all student information
SQL复习语法笔记整理,新鲜出炉
Byte Summer Internship - 20220304
八大排序的思想及其代码
(一)Sql Server的下载与安装
(5) Use Navicat to create database data table and set ID auto increment
快排与归并排序
Error: [HSI 55-1545], unable to generate fsbl normally, unable to read in MSS file, failed to close system mss
If an error is reported, process the ES6 filter to filter the array
【数论】同余(三):一元线性同余方程
Pycharm only needs five steps to improve the download speed by using Tsinghua image source