C语言编译器 cc 编译原理

生成一个可执行的文件一般须要通过如下几个步骤:前端

  1. 预处理你的源代码,去掉注释,以及其余技巧性的工做就像在 C 中展开宏。函数

  2. 检查代码的语法看你是否遵照了这个语言的规则。若是没有,编译器会给出 警告。测试

  3. 把源代码转换为汇编语言 ── 和机器代码很类似, 可是在必定状况下咱们仍然能够理解。 [1]优化

  4. 把汇编语言转换为机器语言──是的,咱们在说位元和字节,就是1和0。spa

  5. 检查你是否准确地使用了函数和全局变量相似的东西。例如,若是你调用了一个不存在的函数,编译器就会给出警告。命令行

  6. 若是你是从多个源代码文件编译,就要学会如何把这些文件组合到一块儿。debug

  7. 把产生出来的东西用系统的运行装载器装入内存并运行。调试

  8. 最后,把可执行文件写入文件系统。code

编译 这个词的意思一般指 1 到 4 步──其余的 步骤叫作 链接。有时侯第一步叫作 预处理 。第三和第四步叫作 汇编排序

  幸运的是,几乎全部这些细节都是隐藏的,由于 cc 只是一个前端。它根据正确的参数调用程序来处理代码。只要输入

%

 

cc foobar.c

就会把 foobar.c 经过以上的步骤编译出来。若是你有多个文件要编译,只要输入

%

 

cc foo.c bar.c

注意,语法检查就是──纯粹的检查语法。而不会检测你可能犯的任何逻辑错误。好比无限循环,或者是你想用一元排序却使用了冒泡排序。 [2]

cc 有不少选项,在帮助手册中均可以找到。这里列出了一些最重要的选项,而且有例子。

-o filename 

输出的文件名。若是你不使用这个选项,cc为产生 出一个叫 a.out 的执行文件。 [3]

%   cc foobar.c 可执行文件是    a.out   %   cc -o foobar foobar.c 可执行文件是    foobar 
-c 

仅仅编译文件,不会链接。若是你只想检查你写的测试程序的语法的话,这个选项很是有用。或者你会使用 Makefile

%   cc -c foobar.c   

这会产生一个 目标文件 (不可执行) 叫作 foobar.o。这个文件能够和其余的目标文件链接在一块儿构成一个可执行文件。

-g 

产生一个可调试的可执行文件。编译器会在可执行文件中植入一些信息,这些信息可以把源文件中的行数和被调用的函数联系起来。在你一步一步调试程序的时候,调试器可以使用这些信息来显示源代码。这是 很是 有用的;缺点就是被植入的信息让程序变得更大。一般状况下,开 发一个程序的时候咱们常用 -g,可是咱们在编译一个 “release 版本” 的程序的时候,若是程序工做得让人满意了,我 们就不使用 -g 编译。

%   cc -g foobar.c   

这会产生一个可调试版本的程序。 [4]

-O 

产生一个优化版本的可执行文件。编译器会使用一些聪明的技巧产生出比普通编译产生的文件执行更快的可执行文件。能够在 -O 加上数字来使用更高级的优化。可是这样作常常会暴露出编译器的优化器中的一些 错误。例如,2.1.0 版本的 FreeBSD 中的 cc 在某些状况 下使用了 -O2 的话,会产生出错误的代码。

优化一般只在编译一个 release 版本的时候才被打开。

%   cc -O -o foobar foobar.c   

这会产生一个优化版本的 foobar

-O和 -O1指定1级优化

-O2 指定2级优化

-O3 指定3级优化

-O0指定不优化

$cc -c O3 -O0 hello.c

当出现多个优化时,以最后一个为准!!

-I 

可指定查找include文件的其余位置.例如,若是有些include文件位于比较特殊的地方,好比/usr/local/include,就能够增长此选项以下:

$cc -c -I/usr/local/include -I/opt/include hello.c

此时目录搜索会按给出的次序进行.

 

   -E 

这个选项是相对标准的,它容许修改命令行以使编译程序把预先处理的C文件发到标准输出,而不实际编译代码.在查看C预处理伪指令和C宏时,这是颇有用的.可能的编译输出可从新定向到一个文件,而后用编辑程序来分析:

 

$cc -c -E hello.c >cpp.out

此命令使include文件和程序被预先处理并重定向到文件cpp.out.之后能够用编辑程序或者分页命令分析这个文件,并肯定最终的C语言代码看起来如何.

-D 

容许从编译程序命令行定义宏符号

 

一共有两种状况:一种是用-DMACRO,至关于在程序中使用#define MACRO,另外一种是用-DMACRO=A,至关于 
   程序中的#define MACRO A.如对下面这代码: 

#ifdefine DEBUG

printf("debug message\n");

#endif

编译时可加上-DDEBUG参数,执行程序则打印出编译信息

下面的三个参数会迫使 cc 检查你的代码是否符合一些国际标准,常常被咱们叫作 ANSI 标准,虽然严格的来讲它是一个 ISO 标准。

-Wall 

打开全部 cc 的做者认为值得注意的警告。不要只看这个选项的名字,它并无打开全部 cc 可以注意到的全部警告。

-ansi 

关闭大多数,但并非全部,cc 提供的非 ANSI C 特性。不要只看选项的名字,它并不严格保证你的代码会兼容标准。

-pedantic 

关闭 全部 cc 的非 ANSI C 特性。

没有这些选项,cc 能容许你按照标准使用一些非标准的扩展。有一些扩展很是有用,但不能与其余编译器兼容──实际上,这个标准的主要目的之一就是容许咱们写出能够在任何系统上的由任何编译器编译的代码。这就叫作 可移植代码

一般来讲,你应该让你的代码尽量的能够移植。不然你就不得不彻底重写你的代码以便可以在其余地方运行之──并且谁知道几年后你是否还会用它?

相关文章
相关标签/搜索