当前位置:网站首页>C language -- program environment and preprocessing
C language -- program environment and preprocessing
2022-07-24 14:01:00 【Hair is not as much as code】
Catalog
Program translation environment and execution environment
Macro parameters with side effects
Common conditional compilation instructions
#inlcude and #include"test.h" difference
Other preprocessing instructions
Program translation environment and execution environment
stay ANSI C In any implementation of , There are two different environments .
The first 1 One is the translation environment , In this environment, source code is converted into executable machine instructions .
The first 2 One is the execution environment , It's used to actually execute code
Detailed compilation + link
Source file :.c file
This is the target file , The linker link.exe, Executable program .exe
Compilation can be divided into three steps : precompile / Preprocessing , compile , assembly
stay gcc Underground depends on the precompiled results , You should enter test.c-E, A lot of things will appear after typing
Preprocessing / precompile
stay gcc Underground depends on the precompiled results , You should enter test.c-E, A lot of things will appear after typing
Input gcc test.c-E-o test.i Will generate test.i file
We turn on test.i file , Can see a lot of things
open stdio.h file
We can see stdio.h There are three documents
And just compiled test.i There are also these three documents in the document
We can be sure :test.i The contents of the document come from stdio.h, That is to say, the pretreatment stage stdio.h All the files will be included in test.i In file
We add a line of comments to the program , And macros , Next, let's compile
After pretreatment , We found that there were no comments and macros , And put define The defined symbols are replaced
summary
All the things done in the preprocessing stage are text operations
The pretreatment will perform the following operations :1. The header file contains
2.define Defines the substitution of symbols , Delete defined symbols
3. Note delete
compile
Options gcc test.i -S Compile the file just preprocessed
gcc test.c-S Preprocess before compiling
Stop when the compilation is complete , The results are stored in test.s in
Input test.i-S And then there will be one test.s file , open .s After the document , We will see a lot of assembly code
This is because of compilation truncation ,C Language converts code into assembly code
How do we do that ?
The conversion needs to go through Syntax analysis 、 Lexical analysis 、 Symbol summary 、 Semantic analysis
Symbol summary
Symbolic summarization will put global variables ( Global variable name , Global function name, etc ) Sum it up , Will not summarize partial
summary
The compilation phase converts the program into assembly code , It will go through the following operations : Syntax analysis 、 Lexical analysis 、 Symbol summary 、 Semantic analysis
assembly
Yes, just now .s Document carried out -c Handle , Input gcc test.s -c, We can see that test.o file
test.o file
This is what it looks like when you open it
The assembly phase converts assembly code into binary instructions , It will also form a symbol table
Form a symbol table
After compilation add.c Will generate add.s file ,test.c Will generate test.s file , After assembly, it will generate add.o and test.o file ,add.o and test.o Will form a symbol table , The symbol table will give these global variables an address
test.c Inside Add Just stating Add, adopt test.cAdd Can't find the real address Add , in other words test.c Inside Add The address of is invalid
summary
After compilation , Will be able to .s File becomes .o file , And generate symbol table
link
Generated above add.o and test.o The file in Linux The format in the environment is elf Format ,linux The executable program format under is also elf Format
elf The format will be .o The document is divided into several paragraphs , Then when the executable program is generated, it will be merged according to the same segment
After merging , Merge and reposition symbol tables
At the time of merging, because of just Add There are two symbol tables , But only one of them can be merged , Therefore, we will choose the correct address when merging
After the merger, it becomes
The combined symbol table for executable programs
When there is no such function , Errors will occur when linking , This is because there is no Add The symbol table of
summary
When linking :1. Merge segment tables
2. Merging and relocating symbol tables
compile + Link summary

Running environment
The process of program execution :
1. The program must be loaded into memory . In an operating system environment : This is usually done by the operating system . In an independent environment , The loading of the program must be arranged manually , It can also be done by putting executable code into read-only memory .
2. The execution of the procedure begins . And then I call main function .
3. Start executing program code . At this point, the program will use a runtime stack (stack), Store function local variables and return address . Programs can also use static (static) Memory , Variables stored in static memory retain their values throughout the execution of the program .
4. To terminate the program . Normal termination main function ; It could be an accidental termination .
Pretreatment details
Predefined symbols
__FILE__
__LINE__
__DATE__
__TIME__
__STDC__// Source files to compile
// The current line number of the file
// The date the file was compiled
// When the file was compiled
// If the compiler follows ANSI C, Its value is 1, Otherwise, it is not definedThese predefined symbols are built into the language .
At this point, we can see the printed file path
Check the line
Check the time
Can be used to write files
VS Undefined __STDC__
but linux have access to
#define
grammar :
#define name stuffstay define When defining identifiers , Do you want to add... At the end ; ?
#define MAX 1000;
#define MAX 1000
If #define Add ;, there pf=1000;;
#define MAX 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 . // If you define stuff Too long , It can be divided into several lines , Except for the last line , Add a backslash after each line ( Line continuation operator ). #define DEBUG_PRINT printf("file:%s\tline:%d\t \ date:%s\ttime:%s\n" ,\ __FILE__,__LINE__ , \ __DATE__,__TIME__ )
#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 define macro (define macro).
Here's how the macro is declared :
#define name( parament-list ) stuff
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 ofAt the time of calculation , Macro parameters will be replaced directly , Please see the following example
![]()
#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 macros , No recursion .
2. When the preprocessor searches #define When defining symbols , The contents of string constants are not searched .
# and ##
# The role of
C In language, you can print strings like this
We want to input a variable and initialize it , You can print it out the value of X is x,X and x Changes with the variable and the value of the variable , But in C Functions in language cannot realize this function , We can do that
stay N Add in front #,N Will not be replaced by 10,N Will be replaced with the corresponding string
Use # , You can change a macro parameter into a corresponding string
Optimize the above program
## The role of
## 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 .
Macro parameters with side effects
When macro parameters appear more than once in the macro definition , If the parameter has side effects , Then you may be in danger when using this macro , Lead to unpredictable consequences . The side effect is the permanent effect of expression evaluation .
for example :
x+1;// No side effects
x++;// With side effects
Macro and function comparison
#define MAX(a, b) ((a)>(b)?(a):(b))Then why not use functions to accomplish this task ?
There are two reasons :
1. The code used to call and return from the function may take more time than actually performing this small computation .
So macros are better than functions in terms of program size and speed .
2. 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 can be used for > To compare the types of . Macros are type independent .
The disadvantages of macro : Of course, compared with functions, macros also have disadvantages :
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 .
3. Macro is type independent , It's not rigorous enough .
4. Macros can cause operator priority problems , It is easy for Cheng to make mistakesMacros can also be used in this way
Belong to sex #define Defining macro function generation code Long degree Every time I use it , Macro code is inserted into the program . Except very
Beyond small macros , The length of the program will increase significantlyFunction code only appears in one place ; Every time
The first time you use this function , Call that
The same code in placeOf board That's ok speed degree faster There is an extra opening for the call and return of the function
pin , So it's relatively slowfuck do operator optimal First level Macro parameters are evaluated in the context of all surrounding expressions ,
Unless you put parentheses , Otherwise, the priority of adjacent operators may produce
Unforeseen consequences , Therefore, it is suggested that macros include more when writing
Number .Function parameters are only evaluated when the function is called
Value once , Its result value is passed to the function
Count . The evaluation result of the expression is easier to predict
measuring .belt Yes vice do use Of ginseng Count Parameters may be replaced at multiple locations in the macro body , So there are side effects
The evaluation of parameters used may produce unpredictable results .Function parameters are evaluated only when passing parameters
Time , The result is easier to control .ginseng Count class type Macro parameters are type independent , As long as the operation on parameters is legal ,
It can be used for any parameter type .The arguments to the function are type dependent , Such as
If the type of parameter is different , It needs to be different
Function of , Even if their task is
Different .transfer try Macros are inconvenient to debug Functions can be debugged statement by statement Deliver return Macros cannot be recursive Functions can be recursive
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
#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 .
Command line definition
#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; }Some parameters can be defined during compilation
//linux Environment demonstration gcc -D ARRAY_SIZE=10 programe.c
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 —— If the conditions are met, compile , If you are not satisfied, do not 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__ // If you define __DEBUG__, Just execute the following statement printf("%d\n", arr[i]);// To see if the array assignment is successful . #endif //__DEBUG__ } return 0; }
Common conditional compilation instructions
1.
#if Constant expression
...
#endif // Constant expressions are evaluated by the preprocessor .
Such as :
#define __DEBUG__ 1
#if __DEBUG__
//..
#endifIf if If the following expression is true, compile , Otherwise, do not participate in the compilation
2. Conditional compilation of multiple branches
#if Constant expression
//...
#elif Constant expression
//...
#else
//...
#endif
3. Judge whether it is defined
#if defined(symbol) // If the condition is true
#ifdef symbol // If the condition is true
#if !defined(symbol) // If the condition is false
#ifndef symbol // If the condition is false
4. Nested instruction
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 #endifFollow if and else Nesting is very similar
File contains
If the header file contains too many times , The content of the header file will appear many times in the file generated by precompiling
To solve this problem , Write at the beginning of each header file
#ifndef __TEST_H__ #define __TEST_H__ // Content of header file #endif //__TEST_H__perhaps
#pragma onceYou can avoid the repeated introduction of header files
#inlcude<stdio.h> and #include"test.h" difference
<>:
Search strategy , Go directly to the library directory to find
" ":
1. First go to the path where the code is located to find
2. If you can't find it, go to the library to find it
Other preprocessing instructions
#error
#pragma
#line
...
Realization offsetof function
offsetof(type, member-designator)
- type -- This is a class type , among ,member-designator Is a valid member indicator .
- member-designator -- This is a class Member indicator of type
- The return type of this macro is size_t Value , Express type The offset of the member in the .
Ideas : Put the numbers 0-n Cast to address , Then it is transformed into shaping , The result is the offset
(struct S*)0 // hold 0 Cast to address , Let the structure address change from 0 Start ((struct S*)0)->m_name , Find the variable name relative to , Is to get this structure member &((struct S*)0)->m_name, Take out the member address (int)&((struct S*)0)->m_name// Cast to integer
#include <stdio.h> #include<stddef.h> struct S { char c1; int i; char c2; }; #define OFFSETOF(type,m_name) (int)&((type*)0)->m_name int main() { printf("%d\n", OFFSETOF(struct S, c1)); printf("%d\n", OFFSETOF(struct S, i)); printf("%d\n", OFFSETOF(struct S, c2)); return 0; }
边栏推荐
- Concurrent programming ----------- set
- R语言epiDisplay包的kap函数计算Kappa统计量的值(总一致性、期望一致性)、对多个评分对象的结果进行一致性分析、评分的类别为多个类别、如果评分中包含缺失值则标准误及其相关统计量则无法计算
- Data Lake series articles
- Error reported when using activiti to create a database table
- Data modification and insertion
- The fourth edition of Zhejiang University probability proves that the uncorrelation of normal distribution random variables is equivalent to independence
- Network security - file upload content check bypass
- 【无标题】rhcsa第一次作业
- 解决 uni-starter 使用本地函数可以登录微信 但是使用云函数登录失败
- Default color setting in uiswitch off state
猜你喜欢

【无标题】

Network security - war backdoor deployment

Nessus security testing tool tutorial
![[untitled]](/img/67/793d1fd7c295f0af9f683ffa389757.png)
[untitled]

2022.7.22 模拟赛

Matlab program for natural gas flow calculation

CSDN garbage has no bottom line!

Network security - filtering bypass injection

rhce第一次作业

Network security - file upload competitive conditions bypass
随机推荐
学习scipy minimize
22-07-23周总结
[untitled] rhcsa first operation
字符串——剑指 Offer 58 - II. 左旋转字符串
解决 uni-starter 使用本地函数可以登录微信 但是使用云函数登录失败
Matlab program for natural gas flow calculation
2022.7.22 simulation match
Introduction to the separation of front and rear platforms of predecessors
Uni app background audio will not be played after the screen is turned off or returned to the desktop
Data modification and insertion
Nessus security testing tool tutorial
SQL subquery
JS get object attribute value
Where can Huatai Securities open an account? Is it safe to use a mobile phone
Data Lake series articles
达梦实时主备集群搭建
Ansible installation and deployment of automated operation and maintenance
Network security - error injection
Multithreaded common classes
The solution to the error of [installation detects that the primary IP address of the system is the address assigned by DHCP] when installing Oracle10g under win7
Source file :.c file 



















































