您的位置:首页 > 其它

一个简单的 C 程序文件,经过 0、编写,1、预处理,2、编译,3、链接,终于生成了一个可执行文件

2011-08-01 11:51 706 查看
 用   C   写一个程序需要些什么工具?某甲:“编译器,VC   啦   TC   啦什么的……”

是吧?不对:)其实这句话首先不完整,其次有逻辑的错误。我们需要的不仅仅是一个编译器;首先我们需要的是一个书写程序的工具,一般统称“编辑器”。最简单的编辑器就是   Windows   自带的写字板,好一点的有   UltraEdit   或者   EditPlus   之类。在   Linux   下可以使用   VI,   Vim   或者大名鼎鼎的   Emacs   作为编辑器。编辑器的作用在于让你输入程序,并且保存为一个普通的文本文档。因此,如果你能记得在保存的时候选择“存为文本文件(*.txt)”或者类似的命令(以保证得到的文件里面没有杂七杂八的格式信息),用
  Microsoft   Word   或者   MacroMeidia   DreamWeaver   MX   也没有问题^_^   C/C++   的源文件名没有   Java   的文件命名机制那么   BT,但是有几个常规如下:

·C   源码文件后缀名为   .c

·C++   源码文件后缀名为   .cpp   .cxx   .cc,或者在区分文件名大小写的系统上为   .C

·C   头文件(表头档——我喜欢这个名字)为   .h

·C++   头文件为   .h   或者   .hpp,而标准库的头文件通常没有后缀名(如   iostream)

所有的这些后缀名都不影响文件本身的内容:所有文件都是   plain   text   ——纯文本文档。后缀名的作用在于提示程序员它所包含的内容,同时可以提示编译器应该采取的行为。

写程序不是写小说。除了编辑器,我们还需要一套工具,把我们写的程序代码转换成机器可以执行的二进制格式。这一套工具应该至少包含一个预处理器,一个编译器和一个链接器。对于   GNU   Binutils/GCC   系列工具,有预处理器   cpp   (C   Pre-Processor),编译器   gcc(GNU   C   Compiler)和   g++   (GNU   C++   Compiler),汇编器   as(The   GNU   assembler)   和链接器   ld(The  
GNU   Linker   )。这么多工具,都是干什么的?让我们一个一个瞧瞧看。

·这是一个很经典的   C   程序,传说中的   Hello,   World

gentoo@yuantoo   tmp   $   cat   hello.c

#include   <stdio.h>

int   main()

{

    printf( "Hello,   world!\n ");

}

·编译成   hello.exe  

gentoo@yuantoo   tmp   $   gcc   hello.c   -o   hello.exe

·运行

gentoo@yuantoo   tmp   $   ./hello.exe

Hello,   world!

好,现在看看它到底都做了什么工作。

第二步中,我用   gcc   hello.c   -o   hello.exe   把   hello.c   编译成了   hello.exe。这里其实还有几个步骤,但是   Gcc   自动的完成了它们。这包括预处理、编译和链接。

首先是预处理。我们可以让   gcc   在预处理之后停下:

gentoo@yuantoo   tmp   $   gcc   -E   hello.c

结果是,gcc   在屏幕上飞快的打印了无数的看不见的信息。可以看到最后几行是这样的:

extern   char   *ctermid   (char   *__s)   ;

#   807   "/usr/include/stdio.h "   3   4

extern   void   flockfile   (FILE   *__stream)   ;

extern   int   ftrylockfile   (FILE   *__stream)   ;

extern   void   funlockfile   (FILE   *__stream)   ;

#   831   "/usr/include/stdio.h "   3   4

#   2   "hello.c "   2

int   main()

{

    printf( "Hello,   world!\n ");

}

也就是说,我们的   hello.c   的内容是在最后。而前面的那些东西,都是从   <stdio.h>   以及   stdio.h   的包含文件中插入进来的信息。预处理器主要的工作就是处理所有源码中以   #   开头的行,将   #include   指令替换成指令指出的文件的内容,对   #define   定义的符号进行了文本替换,以及根据符号选择需要进入结果文件的内容。我们短短四行字的代码文件,经过   gcc   的预处理,得到了一个   913   行的文件。

预处理之后的工作是汇编——这也是真正编译工作的第一步骤。用   -S   标志可以让   gcc   在汇编之后停下来。

gentoo@yuantoo   tmp   $   gcc   -S   hello.c

gentoo@yuantoo   tmp   $   ls

hello.c     hello.s

我们得到了一个名为   hello.s   的文件。看看它的开始部分

gentoo@yuantoo   tmp   $   head   -n10   hello.s

                .file       "hello.c "

                .section                 .rodata

.LC0:

                .string   "Hello,   world!\n "

                .text

.globl   main

                .type       main,   @function

main:

                pushl       %ebp

                movl         %esp,   %ebp

熟悉吧!都是生成的汇编码。

生成汇编码之后的步骤是汇编,把汇编码转换成对象文件。

gentoo@yuantoo   tmp   $   as   hello.s   -o   hello.o   

得到了   hello.o,就是包含   hello.c   代码的对象代码。

得到的   hello   还不能运行,我们需要把它和   C   语言运行库链接起来。它不仅包含了程序的入口,还有   printf   等标准   C   库函数的实现。

gentoo@yuantoo   tmp   $   ld   -o   a.out   -dynamic-linker   /lib/ld-linux.so.2   /usr/lib/crt?.o   hello.o   -lc

这里,-o   hello.exe   表示输出为   hello.exe   文件。-dynamic-linker   /lib/ld-linux.so.2   表示将程序动态链接到   /lib/ld-linux.so.2   这个   shared   object。这个   shared   object   作为操作系统中的一个特殊的库,它负责引入其他的   so。同时,我们要在我们的程序中包含   /usr/lib   下的几个   crt?.o   对象文件:它们中包含了   C   程序的所需要的运行时环境。最后一个参数
  -lc   表示将程序链接到标准   C   库上(名为   libc.so.5,在   /usr/lib   目录下。ld   会根据配置文件自动搜索   /usr/lib   目录;如果库文件在其他目录中,则需要用   -L   参数指出。)执行完毕,我们得到了一个具有执行权限的   hello.exe   文件。

gentoo@yuantoo   tmp   $   ./hello.exe

Hello,   world!

gentoo@yuantoo   tmp   $

就这样,一个简单的   C   程序文件,经过   0、编写,1、预处理,2、编译,3、链接,终于生成了一个可执行文件。一般而言,gcc   编译器可以替我们完成整个过程,只要简简单单一个   gcc   -o   hello.exe   hello.c   命令,三个步骤就可以统统完成。

从上面可以看出,编写代码和编译代码完全是分离的两个过程,可以用完全不同的工具替换每个步骤(譬如用   notepad   或者   EditPlus   作编辑器编写代码,用   Cygwin   或者   Mingw   做编译器,等等)。VC   和   TC   都是所谓的   IDE(集成开发环境),它包含了编辑器、编译器和调试器,通常还包含了项目管理和文档生成以及其他一系列辅助工具,可以大大简化项目开发周期。它们既不是编译器,也不是编辑器;它们包含了这些所有东西。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐