Compile + link + preprocessing instructions

Compile + link

C language execution process

We know that the final implementation of the machine is the binary code of 01 sequence, and what we write under IDE such as VS is actually a string of text. First, the compiler will convert all the codes we write into characters (using ASCⅡ codes) for storage, and then compile them into assembly language according to different instructions. At this time, the high-level language has reached the level of machine language, and assembly language is converted into binary again. Language, generate obj file (xxx.o), send it to linker, generate executable file (xxx.exe)
Insert picture description here

Compile

Compilation is divided into three steps: pre-compilation, compilation, and assembly. In order to better understand, we can understand the generated mode through the linux command line. The original file is as follows
Insert picture description here

Precompiled

1. The header file contains
2. The replacement of #define
3. The deletion of comments
Insert picture description here
GenerateInsert picture description here

Compile

At this stage
1, grammatical analysis
2, lexical analysis
3, semantic analysis
4, symbol summary
Insert picture description here
generationInsert picture description here

compilation

This stage of assembly code into a binary instruction, forming the symbol table
# Insert picture description here
generatedInsert picture description here

link

At this stage
1, merge segment table
2, merge and relocate symbol table to
Insert picture description here
generate
executable file The suffix of the executable file in the linux environment is .out
Insert picture description here

Preprocessing directive

Preprocessing symbol

FILE //The source file to compile
LINE //The current line number of the file
DATE //The date when the file was compiled
TIME //The time
when the file was compiled STDC //If the compiler complies with ANSI C, its value is 1, otherwise undefined

Macro definition

The essence of the macro is to replace all the defined variable positions that appear in the program theme at the recompilation stage, so it is best not to add;

  1. When calling the macro, first check the parameters to see if it contains any symbols defined by #define. If they are, they are replaced first.
  2. The replacement text is then inserted at the position of the original text in the program. For macros, the parameter names are replaced by their values.
  3. Finally, scan the result file again to see if it contains any symbols defined by #define. If it is, repeat the above process.
#define M 100
// 如果定义的 stuff过长,可以分成几行写,除了最后一行外,每行的后面都加一个反斜杠(续行符)。
#define DEBUG_PRINT printf("file:%s\tline:%d\t \
                          date:%s\ttime:%s\n" ,\
                          __FILE__,__LINE__ ,       \
                          __DATE__,__TIME__ )  

Macro definition functions and functions

1. Macro can simulate function definition

#define SQUARE(x) x*x
int main(){
    
    
	printf("%d",SQUARE(5));//替换后为 5*5=25
	return 0;
}

However, this definition method may cause priority errors

#define SQUARE(x) x*x
int main(){
    
    
	printf("%d",SQUARE(5+1));//替换后为 5+1*5+1=11
	return 0;
}

Or

#define double(x) (x)+(x)
int main(){
    
    
	printf("%d",2*SQUARE(5+1));//替换后为 2*(5+1)+(5+1)=18
	return 0;
}

So usually

#define SQUARE(X) ((X)*(X))

2. Comparison of macros and functions
Macros are generally used to perform simple operations

#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 the function and return from the function may take more time than the actual execution of this small calculation work. So macros are better than functions in terms of program
    size and speed.
  2. More importantly, the parameters of the function must be declared as a specific type. So functions can only be used on expressions of the appropriate type. On the contrary, how can this macro be
    applied to the types that can be compared with >, such as integers, long integers, and floating-point types. Macros are type independent.
    Of course, compared with macros, functions also have disadvantages:
  3. Every time a macro is used, a copy of the macro definition code will be inserted into the program. Unless the macro is relatively short, it may greatly increase the length of the program.
  4. Macros cannot be debugged.
  5. Since macros are not type-independent, they are not rigorous enough.
  6. Macros may cause problems with operator precedence, making the process prone to errors.
    Insert picture description here

Some special preprocessing directives

1. # Replace the variable that needs to be replaced in the form of a string.
For example: you need to define the macro print (format, value) so that num is printed in format

#define PRINT(FORMAT, VALUE)\ 
 printf("the value of " #VALUE "is "FORMAT "\n", VALUE);//打印出来为 the value of a is 10

2.## Link two variables

#define ADD_TO_SUM(num, value) 
 sum##num += value; 
ADD_TO_SUM(5, 10);//作用是:给sum5增加10.

3. #undef is used to remove a definition and has the opposite effect of #define
4. Command line definition
has the following code

#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; 
}

We observe that ARRAY_SIZE is not defined,
and it can be defined using the command line in the Linux environment

gcc -D ARRAY_SIZE=10 programe.c

4. Conditional compilation
#if there is endif
#ifndef If it is not defined, it will participate in compilation, if it is defined, it will not participate in compilation.
#ifdef or #if defined() If it is defined, it will participate in compilation. If it is not defined, it will not participate in compilation.

1. 
#if 常量表达式
 //... 
#endif 
//常量表达式由预处理器求值。
如:
#define __DEBUG__ 1 
#if __DEBUG__ 
 //.. 
#endif 
2.多个分支的条件编译
#if 常量表达式
 //... 
#elif 常量表达式
 //... 
#else 
 //... 
#endif 
3.判断是否被定义
#if defined(symbol) 
#ifdef symbol 
#if !defined(symbol) 
#ifndef symbol 
4.嵌套指令
#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

Insert picture description here
Insert picture description here
5. Prevent multiple references of header files. The
first way
Insert picture description here
The second way

#pragma once

Guess you like

Origin blog.csdn.net/weixin_54225634/article/details/115024062