Topic Three:
1) Pre-compilation
Handle all comments, with spaces instead,
Delete all # define, and expand all macro definitions,
Processing conditional Compilation Directives # If, #ifdef, #elif, #else, #endif
Deal with # include, expand the files contained in the chant,
Keep the #pragma instructions that the compiler needs to use.
Pre-processing directive: GCC-E File.c–o hello.i
Compile:
A series of lexical analysis, syntax analysis and semantic analysis for processing files
The main analysis of the syntax analysis of keywords, descriptors, whether the immediate number is legal, parsing the main analysis of whether the expression follows the grammatical rules
Semantic Analysis sub-grammatical analysis of the basis of further analysis of whether the expression is legitimate
Code optimization generates the corresponding assembly code file after the analysis is finished
compiler directive: Gcc–s file.c–o Hello.s
Assembler: The assembler transforms the assembly code into instructions that the machine can execute,
Almost every assembly sentence corresponds to a machine instruction.
Assembly instructions: Gcc–c File.s–o hello.o
The meaning of the linker
The main function of a connector is to handle the parts of each module that are referenced to each other,
So that the various modules can be correctly linked.
Module assembly: Static link, (FILE1.O,FILE2.O,LIBC.A)-à Linker (linker)-àa.out
Dynamic Link: File1.cà compiler (GCC) àfile1.oà Connector (linker) Àa.out
Lib1.soàstub1à Connector (linker) Àa.out
Lib2.soàstub2à Linker (linker) Àa.out
The compiler mainly divides the compilation work into preprocessing, compiling and assembling three parts
The work of the connector is to link the individual modules to the executable program,
Static link is completed at compile time, dynamic link is completed at run time,
2) macro definition and Usage analysis:
To define a macro constant:
#define定义宏常量可以出现代码的任何地方
#define从本行开始, the following code can use this macro constant
#define ERROR-1
#define PI 3.1415926
#define PATH_2 "D:\Delphi\C\Topic3.ppt"
#define PATH_1 D:\Delphi\C\Topic3.ppt
#define PATH_3 D:\Delphi\c\
Topic3.ppt
Top-Yo macro expression
#define expression gives the illusion of a function call, but not a function,
#define表达式可以比函数更强大
#define Expressions are more error-prone than functions
#define SUM (A, B) (q) +
#define MIN (a) < (b)? (a):(B))
#define DIM (a) () (sizeof (a)/sizeof (*a))
Is there a problem with the macro expression above? Is it a fully equivalent function?
Comparison of macro expressions and functions
The macro expression is processed during the precompiled period, and the compiler does not know that the macro exists.
A macro expression uses "argument" to completely replace a formal parameter without any operation.
The macro expression has no overhead for any calls
Macro expression cannot appear defined
#define FAC (N) ((n>0)? (FAC (n-1) +1): 0)
Int J=FAC (100);
Whether a macro defines a constant or an expression that has effect or restriction
int F1 (int a, int b)
{
#define MIN (a) (a) < (b) a:b)
Return MIN (A, b);
}
int f2 (int a,int b,int c)
{
Return min (min (b), c);
}
Int Main ()
{
Printf ("%d\n", F1 (2,1));
Printf ("%d\n", F2 (5,3,2));
Return 0;
}
Powerful built-in macros,
_file_------The compiled file name-----file1.c
_line_------Current line number---25
_date_-------Compile date------Jan 31 2012
_time_-------Compile time----17:01:01
_STDC_-------compiler follows the standard C specification-1
Defining log Macros
#define F (x) ((x)-1)
What does the macro definition above mean?
Macro definition The space is not daring? IS macro "call" sensitive to whitespace?
Conditional compilation usage Analysis
Conditional compilation behaves like a if...else in C language
Conditional compilation is a precompiled instruction command that controls whether a piece of code is compiled
#define C1
Int Main ()
{
#if (C==1)
printf ("This is first printf ... \ n");
#else
printf ("This is second printf ... \ n");
#endif
Return 0;
}
The confusion of #include
The essence of #include embeds the existing file contents into the current file,
#include的间接包含同样会产生嵌入文件内容的动作
The meaning of conditional compilation
Conditional compilation allows us to vary the code segments according to different conditions, thus producing different target codes
#if #else ... #endif被预编译器处理, and IF...ELSE statements are processed by the compiler and must be compiled into the target code
The actual engineering condition compilation is mainly used in two situations:
Different product lines share a single piece of code
Differentiate between debug and release versions of compiled products
Total: summary
Use of conditional compilation:
The compiler command line enables you to define the macros used by the preprocessor
Conditional compilation avoids repeating the same file with the header,
Conditional compilation is the code that can differentiate different product lines in engineering development.
Conditional compilation can define the release and debug versions of the product
#error的用法:
#error用于生成一个编译错误的消息, and stop compiling;
Usage: #error message Note: The message does not need to be surrounded by double quotes,
#error编译指示字用于自定义程序员特有的编译错误消息类似的, the #warning is used to generate compilation warnings, but does not stop compiling.
#error and #warning的使用: custom error messages
#line的用法:
#line用于强制指定新的行号和编译文件名, and renumber the code of the source program
Usage:
#line number Filenames Note: filename can be omitted
The essence of #line compiler indicator is to redefine _line_ and _file_
#pragma预处理分析: #pragma是编译器指示字, which instructs the compiler to complete some specific actions,
Many of the indicators defined by the #pragma are specific to the compiler and the operating system,
#pragma is not portable between different compilers
The preprocessor ignores #pragma directives that it does not recognize.
Two different compilers may interpret the same #pragma instruction in two different ways,
General usage: #pragma parameter note: Different parameter parameter syntax and meaning vary
#pragma message:
The message parameter has a similar implementation in most compilers,
The message parameter outputs messages to the compiled Output window at compile time,
Message can be versioned with the domain code, note: The message is a VC-specific compiler designator, which is ignored in GCC.
#pragma examples of use under different compilers:
#pragma pack
What is memory alignment?
Different types of data are arranged in memory according to certain rules, rather than one-by-one emissions of the sequence, which is the alignment
struct TEST1
{
Char C1;
Short S;
Char C2;
int i;
}
struct TEST2
{
Char C1;
Char C2;
Short S;
int i;
}
Do the two types occupy the same amount of memory space?
#pragma pack
Why do I need to align my memory?
CPU read memory is not sequential, but is divided into blocks read, the size of the block can only be 1, 2, 4, 8, 16 bytes
When the data for the read operation is misaligned, two bus cycles are required to access the memory, so performance can be greatly compromised.
Some hardware platforms can only go from a specified address to certain types of data, otherwise throw a hardware exception.
#pragma pack
#pragma pack can change the compiler's default to I go way
#pragma pack (2) #pragma pack (4)
struct TEST1 struct TEST2
{ {
Char C1; Char C1;
Short S; Char C2;
Char C2; Short S;
int i; int i;
} }
#pragma pack () #pragma pack ()
sizeof (struct Test1) =?
sizeof (struct Test2) =?
#pragma pack:
The amount of memory the struct occupies
The first member starts at 0 offsets,
Each member is aligned by its type size and the smaller of the specified alignment parameter n.
The offset address and the member occupancy size need to be aligned
The alignment parameter of a struct member is the maximum value of its arguments used by all its members
The whole length of the structure must be an integer multiple of all alignment parameters,
After-school thinking:
Can a struct variable be judged directly using the MEMCMP function? Why?
#和 # #晕窜使用解析:
#运算符:
#运算符用于在预编译期将宏参数转为字符串
#include <stdio.h>
#define Convers (x) #x
int main ()
{
printf ("%s\n", Coners (Hello world!));
printf ("%s\n", Convers (100));
printf ("%s\n", Convers (while));
printf ("%s\n", Convers (return));
return 0;
}
#运算符在宏中的妙用:
# # Operator:
# #运算符用于在预编译期粘连两个符号
#include <stdio.h>
#define NAME (n) name# #n
int main ()
{
int NAME (1);
int Namr (2);
NAME (1) = 1;
NAME (2) = 2;
printf ("%d\n", NAME (1));
printf ("%d\n", NAME (2));
return 0;
}
Use # #定义结构类型:
C Language Learning Notes---precompilation