C进阶养成记 - 养成记19:编译过程简介

--事物的难度远远低于对事物的恐惧! 

    本章节我们来聊一聊编译过程,我们写代码通常会用现成的集成开发环境,比如vs2010等,写完后一键编译,就能获取我们想要的可执行文件,那么在这一键编译的过程中,发生了什么?编译是个怎样的过程?要想了解这个过程,我们首先来了解下编译器。

    编译器大概可由如下几个部分组成:


由图我们可以得知,编译器由 预处理器、编译器、汇编器、链接器组成,而编译过程,则可参考如下的这张图:


    从图中可看到,代码从源程序到目标文件,经过的步骤比较负责,下边我们来逐一分析:

    预编译:

        -处理所有的注释,用空格代替

        -将所有的#define删除,并且展开所有的宏定义

        -处理条件编译指令#if,#ifdef,#elseif,#else,#endif等

        -处理#include,展开被包含的文件

        -保留编译器需要使用的#pragma指令

        gcc中预编译指令为:gcc -E file.c -o file.i

        VC中的预编译指令为:cl -E file.c > out.i

下边来看个示例:

//header.h 

char* p = "Delphi";
int i = 0;
//main.c
#include "header.h"

// Begin to define macro

#define GREETING "Hello world!"
#define INC(x) x++

// End

int main()
{   
    p = GREETING;
    
    INC(i);
    
    return 0;
}
vs2010下使用预编译器进行与编译,cl -E main.c > main.i,main.i文件的内容如下:
#line 1 "main.c"
#line 1 "f:\\study\\c\\header.h"

char* p = "Delphi";

int i = 0;
#line 2 "main.c"

int main()
{   
    p = "Hello world!";
    
    i++;
    
    return 0;
}

从main.i的内容,我们可以知道,头文件被展开了、注释去掉了、#define去掉了,并且在对应的位置作了宏替换

编译:

    -在预编译完成后,就由编译器对预编译完成的文件进行词法分析语法分析语义分析

        -词法分析:分析关键字,标识符,立即数等是否合法

        -语法分析:分析表达式是否遵循语法规则

        -语义分析:在语法分析的基础上进一步分析表达式是否合法

    -分析结束后进行代码优化生成相应的汇编代码文件

    gcc中的编译指令为:gcc -S file.c -o file.s

汇编:

    -汇编器将编译得到的汇编代码转变为机器可以执行的指令

    -每条汇编语句几乎都对应一条机器指令

总结:

    编译过程分为预处理,编译,汇编和链接四个阶段

        -预处理:处理注释,宏以及已经以#开头的符号

        -编译:进行词法分析,语法分析和语义分析

        -汇编:将汇编代码翻译为机器指令的目标文件


猜你喜欢

转载自blog.csdn.net/lms1008611/article/details/80030139