生成一个可执行的文件通常需要经过以下几个步骤:

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

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

  3. 把源代码转换为汇编语言 ── 和机器代码很相似, 但是在一定情况下我们仍然可以理解。 [1]

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

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

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

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

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

编译 这个词的意思通常指 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 能允许你按照标准使用一些非标准的扩展。有一些扩展非常有用,但不能与其他编译器兼容──实际上,这个标准的主要目的之一就是允许我们写出可以在任何系统上的由任何编译器编译的代码。这就叫做 可移植代码

通常来说,你应该让你的代码尽可能的可以移植。否则你就不得不完全重写你的代码以便能够在其他地方运行之──而且谁知道几年后你是否还会用它?

C语言编译器 cc 编译原理的更多相关文章

  1. gcc/g++等编译器 编译原理: 预处理,编译,汇编,链接各步骤详解

    摘自http://blog.csdn.net/elfprincexu/article/details/45043971 gcc/g++等编译器 编译原理: 预处理,编译,汇编,链接各步骤详解 C和C+ ...

  2. 学了编译原理能否用 Java 写一个编译器或解释器?

    16 个回答 默认排序​ RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和 ...

  3. 编译原理(一)绪论概念&文法与语言

    绪论概念&文法与语言 以老师PPT为标准,借鉴部分教材内容,AlvinZH学习笔记. 绪论基本概念 1. 低级语言:字位码.机器语言.汇编语言.与特定的机器有关,功效高,但使用复杂.繁琐.费时 ...

  4. Knowledge Point 20180303 对比编译器、解释器与Javac编译原理

    编译器与Javac编译原理 在前文我们知道了Java是一种编译语言和解释语言,它的源代码经过编译器Javac编译为能够被JVM识别的二进制语言,然后JVM将其解释为能够被平台识别的机器语言.那么什么是 ...

  5. MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义

    编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...

  6. 浅谈C++编译原理 ------ C++编译器与链接器工作原理

    原文:https://blog.csdn.net/zyh821351004/article/details/46425823 第一篇:      首先是预编译,这一步可以粗略的认为只做了一件事情,那就 ...

  7. Notepad++根据语言类型自动选择对应编译器来编译代码

    Notepad++的NppExec插件可以调用好多编译器来编译代码. 比如编译Java: NPP_SAVE javac "$(FULL_CURRENT_PATH)" java -c ...

  8. GCC编译器原理(二)------编译原理一:目标文件

    一.目标文件 在 UNIX® 和 Linux® 中,任何事物都是文件.UNIX 和 Linux 编程实际上是编写处理各种文件的代码.系统由许多类型的文件组成,但目标文件具有一种特殊的设计,提供了灵活和 ...

  9. <编译原理 - 函数绘图语言解释器(1)词法分析器 - python>

    <编译原理 - 函数绘图语言解释器(1)词法分析器 - python> 背景 编译原理上机实现一个对函数绘图语言的解释器 - 用除C外的不同种语言实现 解释器分为三个实现块: 词法分析器: ...

随机推荐

  1. N-gram介绍

    在实际应用中,我们经常需要解决这样一类问题:如何计算一个句子的概率?如: 机器翻译:P(high winds tonite) > P(large winds tonite) 拼写纠错:P(abo ...

  2. #在lua中的运用

    在lua中"#"表示返回表长度或字符串长度 例子一: a = "Hello " b = "World" print("Concat ...

  3. python学习笔记五 模块上(基础篇)

    模块学习 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要 ...

  4. pt-query-digest怎么分析慢查询日志分析数据

    在进行使用linux系统作为服务器的情况,那几需要进行对linux的服务器进行性能上数据进行抓取之后,就需要对数据中内容进行分析,看数据库中内容是否存在瓶颈上的问题,在进行获取到的数据的慢查日志,将使 ...

  5. [转]ZigBee On Windows Mobile--ZigBee模块天线设计

    原文出处:http://www.cnblogs.com/dearsj001/archive/2008/10/26/1320029.html

  6. XML详解:第一部分

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  7. HNOI2006-公路修建问题(二分答案+并查集)

    公路修建问题 OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕.所以,OIER Association组织成立了,旨 ...

  8. retire or not retire ? is a question.

    corejava 上的一段代码 因吹思婷 "C:\Program Files\Java\jdk1.8.0_101\bin\java" -Didea.launcher.port=75 ...

  9. Android_安装GooglePlay

    百度搜索:“google play 安装” http://jingyan.baidu.com/article/cbf0e500f4645b2eab28935a.html http://samsungb ...

  10. [转载] linux 程序运行过程中替换文件

    今天被朋友问及“Linux下可以替换运行中的程序么?”,以前依稀记得Linux下是可以的(而Windows就不让),于是随口答道“OK”.结果朋友发来一个执行结果:(test正在运行中)# cp te ...