Linux 下可用的编译器有 GCC、EGCS 和 PGCC,其中最常用的编译器便是 GCC。
GCC 起初是 GNU 推出的 C语言编
译器,用于类 Unix 系统下的编程,所以名为 GNU C Compiler 。随着众多自由开发者的加入,GCC
发展迅速,如今已成为一个支持众多语言的编译器了,其中包括 C、C++、Ada、Object C 和 Java 等,以至于 GCC 开始被扩展为
GNU Compiler Collection ,也就是“GNU 编译器集合”的意思。
GCC用法:
1、GCC基本用法及其选项
gcc 或 g++ 的用法跟参数含义几乎一样,他们最基本的用法是:
2、只编译子程序(-c)
3、产生目标文件(-o)
4、附加调试信息(-g)
5、多文件编译
6、连接库文件。
② 什么是编译器
编译器
编译器是一种特殊的程序,它可以把以特定编程语言写成的程序变为机器可以运行的机器码。我们把一个程序写好,这时我们利用的环境是文本编辑器。这时我程序把程序称为源程序。在此以后程序员可以运行相应的编译器,通过指定需要编译的文件的名称就可以把相应的源文件(通过一个复杂的过程)转化为机器码了。
[编辑]编译器工作方法
首先编译器进行语法分析,也就是要把那些字符串分离出来。然后进行语义分析,就是把各个由语法分析分析出的语法单元的意义搞清楚。最后生成的是目标文件,我们也称为obj文件。再经过链接器的链接就可以生成最后的可执行代码了。有些时候我们需要把多个文件产生的目标文件进行链接,产生最后的代码。我们把一过程称为交叉链接。
一个现代编译器的主要工作流程如下:
* 源程序(source code)→预处理器(preprocessor)→编译器(compiler)→汇编程序(assembler)→目标程序(object code)→连接器(链接器,Linker)→可执行程序(executables)
工作原理
编译是从源代码(通常为高级语言)到能直接被计算机或虚拟机执行的目标代码(通常为低级语言或机器言)。然而,也存在从低级语言到高级语言的编译器,这类编译器中用来从由高级语言生成的低级语言代码重新生成高级语言代码的又被叫做反编译器。也有从一种高级语言生成另一种高级语言的编译器,或者生成一种需要进一步处理的的中间代码的编译器(又叫级联)。
典型的编译器输出是由包含入口点的名字和地址以及外部调用(到不在这个目标文件中的函数调用)的机器代码所组成的目标文件。一组目标文件,不必是同一编译器产生,但使用的编译器必需采用同样的输出格式,可以链接在一起并生成可以由用户直接执行的可执行程序。
编译器种类
编译器可以生成用来在与编译器本身所在的计算机和操作系统(平台)相同的环境下运行的目标代码,这种编译器又叫做“本地”编译器。另外,编译器也可以生成用来在其它平台上运行的目标代码,这种编译器又叫做交叉编译器。交叉编译器在生成新的硬件平台时非常有用。“源码到源码编译器”是指用一种高级语言作为输入,输出也是高级语言的编译器。例如: 自动并行化编译器经常采用一种高级语言作为输入,转换其中的代码,并用并行代码注释对它进行注释(如OpenMP)或者用语言构造进行注释(如FORTRAN的DOALL指令)。
预处理器(preprocessor)
作用是通过代入预定义等程序段将源程序补充完整。
编译器前端(frontend)
前端主要负责解析(parse)输入的源程序,由词法分析器和语法分析器协同工作。词法分析器负责把源程序中的‘单词’(Token)找出来,语法分析器把这些分散的单词按预先定义好的语法组装成有意义的表达式,语句 ,函数等等。 例如“a = b + c;”前端词法分析器看到的是“a, =, b , +, c;”,语法分析器按定义的语法,先把他们组装成表达式“b + c”,再组装成“a = b + c”的语句。 前端还负责语义(semantic checking)的检查,例如检测参与运算的变量是否是同一类型的,简单的错误处理。最终的结果常常是一个抽象的语法树(abstract syntax tree,或 AST),这样后端可以在此基础上进一步优化,处理。
编译器后端(backend)
编译器后端主要负责分析,优化中间代码(Intermediate representation)以及生成机器代码(Code Generation)。
一般说来所有的编译器分析,优化,变型都可以分成两大类: 函数内(intraproceral)还是函数之间(interproceral)进行。很明显,函数间的分析,优化更准确,但需要更长的时间来完成。
编译器分析(compiler analysis)的对象是前端生成并传递过来的中间代码,现代的优化型编译器(optimizing compiler)常常用好几种层次的中间代码来表示程序,高层的中间代码(high level IR)接近输入的源程序的格式,与输入语言相关(language dependent),包含更多的全局性的信息,和源程序的结构;中层的中间代码(middle level IR)与输入语言无关,低层的中间代码(Low level IR)与机器语言类似。 不同的分析,优化发生在最适合的那一层中间代码上。
常见的编译分析有函数调用树(call tree),控制流程图(Control flow graph),以及在此基础上的变量定义-使用,使用-定义链(define-use/use-define or u-d/d-u chain),变量别名分析(alias analysis),指针分析(pointer analysis),数据依赖分析(data dependence analysis)等等。
上述的程序分析结果是编译器优化(compiler optimization)和程序变形(compiler transformation)的前提条件。常见的优化和变新有:函数内嵌(inlining),无用代码删除(Dead code elimination),标准化循环结构(loop normalization),循环体展开(loop unrolling),循环体合并,分裂(loop fusion,loop fission),数组填充(array padding),等等。优化和变形的目的是减少代码的长度,提高内存(memory),缓存(cache)的使用率,减少读写磁盘,访问网络数据的频率。更高级的优化甚至可以把序列化的代码(serial code)变成并行运算,多线程的代码(parallelized,multi-threaded code)。
机器代码的生成是优化变型后的中间代码转换成机器指令的过程。现代编译器主要采用生成汇编代码(assembly code)的策略,而不直接生成二进制的目标代码(binary object code)。即使在代码生成阶段,高级编译器仍然要做很多分析,优化,变形的工作。例如如何分配寄存器(register allocatioin),如何选择合适的机器指令(instruction selection),如何合并几句代码成一句等等。
③ 在c语言中“可执行程序”是什么意思
C语言中的可执行程序就是将用文本信息表示的程序翻译成计算机认识的二进制代码串。
首先,我们先用C语言把源代码写好,然后交给C语言编译器。C语言编译器内部分为前端和后端。
(1)编译器前端
前端负责将C语言代码进行词法和语法上的解析,然后可以生成中间代码。
中间代码这部分不是必须的,但是它能够为程序的跨平台移植带来诸多好处。比如,同样的一份C语言源代码在一台计算机上编译完之后,生成一套中间代码。
然后针对不同的目标平台(比如要将这一套代码分别编译成 ARM 处理器的二进制机器码、MIPS 处理器的二进制机器码以及 x86 处理器的二进制机器码),只需要编写相应目标平台的编译器后端即可。
所以,这么做就可以把编译器的前端与后端剥离开来(这在软件工程上又可称为解耦合),不同处理器厂商可以针对自家的处理器特性,对中间代码生成到目标二进制代码的过程再度进行优化。
(2)编译器后端
接下来,由C语言编译器后端生成源文件相应的目标文件。
目标文件在 Windows 系统上往往是.obj文件,而在 Unix/Linux 系统上往往是.o文件,C语言的源文件在所有平台上都统一用.c文件表示。
(3)链接器
最后,对于各个独立的目标文件,通过连接器将它们合并成一个最终可执行文件。
(3)编译器的前端包括什么扩展阅读:
起初,C语言没有官方标准。1978年由美国电话电报公司(AT&T)贝尔实验室正式发表了C语言。布莱恩·柯林汉(Brian Kernighan) 和 丹尼斯·里奇(Dennis Ritchie) 出版了一本书,名叫《The C Programming Language》。
这本书被 C语言开发者们称为K&R,很多年来被当作 C语言的非正式的标准说明。人们称这个版本的 C语言为K&R C。
K&R C主要介绍了以下特色:
结构体(struct)类型
长整数(long int)类型
无符号整数(unsigned int)类型
把运算符=+和=-改为+=和-=。因为=+和=-会使得编译器不知道使用者要处理i = -10还是i =- 10,使得处理上产生混淆。
即使在后来ANSI C标准被提出的许多年后,K&R C仍然是许多编译器的最 准要求,许多老旧的编译器仍然运行K&R C的标准。
1970到80年代,C语言被广泛应用,从大型主机到小型微机,也衍生了C语言的很多不同版本。
1983年,美国国家标准协会(ANSI)成立了一个委员会X3J11,来制定 C语言标准。
1989年,美国国家标准协会(ANSI)通过了C语言标准,被称为ANSI X3.159-1989 "Programming Language C"。因为这个标准是1989年通过的,所以一般简称C89标准。有些人也简称ANSI C,因为这个标准是美国国家标准协会(ANSI)发布的。
1990年,国际标准化组织(ISO)和国际电工委员会(IEC)把C89标准定为C语言的国际标准,命名为ISO/IEC 9899:1990 - Programming languages -- C 。因为此标准是在1990年发布的,所以有些人把简称作C90标准。不过大多数人依然称之为C89标准,因为此标准与ANSI C89标准完全等同。
1994年,国际标准化组织(ISO)和国际电工委员会(IEC)发布了C89标准修订版,名叫ISO/IEC 9899:1990/Cor 1:1994 ,有些人简称为C94标准。
1995年,国际标准化组织(ISO)和国际电工委员会(IEC)再次发布了C89标准修订版,名叫ISO/IEC 9899:1990/Amd 1:1995 - C Integrity ,有些人简称为C95标准。
C99标准
1999年1月,国际标准化组织(ISO)和国际电工委员会(IEC)发布了C语言的新标准,名叫ISO/IEC 9899:1999 - Programming languages -- C ,简称C99标准。这是C语言的第二个官方标准。
参考资料:网络-c语言
④ gcc鏄浠涔堬纻
1銆乬cc
GCC锛圙NU Compiler Collection锛孏NU缂栬疟鍣ㄥ椾欢锛夋槸鐢盙NU寮鍙戠殑缂栫▼璇瑷璇戝櫒銆侴NU缂栬疟鍣ㄥ椾欢鍖呮嫭C銆丆++銆 Objective-C銆 Fortran銆丣ava銆丄da鍜孏o璇瑷鍓岖锛屼篃鍖呮嫭浜呜繖浜涜瑷镄勫簱锛埚俵ibstdc++锛宭ibgcj绛夈傦级
GCC镄勫埯琛锋槸涓篏NU镎崭綔绯荤粺涓挞棬缂栧啓镄勪竴娆剧紪璇戝櫒銆侴NU绯荤粺鏄褰诲簳镄勮嚜鐢辫蒋浠躲傛ゅ勶纴钬滆嚜鐢扁濈殑钖涔夋槸瀹冨皧閲岖敤鎴风殑镊鐢便
2銆乴lvm+Clang
LLVM鏄鏋勬灦缂栬疟鍣(compiler)镄勬嗘灦绯荤粺锛屼互C++缂栧啓钥屾垚锛岀敤浜庝紭鍖栦互浠绘剰绋嫔簭璇瑷缂栧啓镄勭▼搴忕殑缂栬疟镞堕棿(compile-time)銆侀摼鎺ユ椂闂(link-time)銆佽繍琛屾椂闂(run-time)浠ュ强绌洪棽镞堕棿(idle-time)锛屽瑰紑鍙戣呬缭鎸佸紑鏀撅纴骞跺吋瀹瑰凡链夎剼链銆
LLVM璁″垝钖锷ㄤ簬2000骞达纴链鍒濈敱University of Illinois at Urbana-Champaign镄凛hris Lattner涓绘寔寮灞曘2006骞碈hris Lattner锷犵洘Apple Inc.骞惰嚧锷涗簬LLVM鍦ˋpple寮鍙戜綋绯讳腑镄勫簲鐢ㄣ侫pple涔熸槸LLVM璁″垝镄勪富瑕佽祫锷╄呫
3銆乄atcom C/C++
Watcom C/C++ 缂栬疟鍣ㄣ乄atch Fortran 缂栬疟鍣 缁忓凡鍦ㄤ笉鍏跺厛鍓嶆墍灞炲叕鍙窼ybase鍞鍗, 钥岃 SciTech 杞浠跺叕鍙 浣滀负 Open Watcom 寮婧愬寘 鍙戣屻傜被浼间簬鍏朵粬镄 寮婧愮紪璇戝櫒(渚嫔 [GCC])椤圭洰锛学atcom C浠g爜灏忚屼究鎼猴纴 鍏剁紪璇戝櫒钖庣(浠g爜鐢熸垚鍣)镄勭洰镙囩爜鍙鍙樸
璇ョ紪璇戝櫒鍙鍦―OS銆丱S/2銆乄indows绛夋搷浣灭郴缁熶笂杩愯岋纴骞剁敓鎴愬悇绉嶅彲杩愯岀殑(涓嶅繀鏄璇ユ搷浣灭郴缁熺殑)浠g爜銆傝ョ紪璇戝櫒鏀鎸丯ovell NetWare镄 NLM 鐩镙囩爜銆傜洰鍓嶆h繘琛 涓 Linux銆乵odern BSD (渚嫔侳reeBSD) 镎崭綔绯荤粺 閲嶅畾鐩镙囩爜锛屼互渚垮湪 x86銆丳owerPC 鍙娿鍏跺畠澶勭悊鍣ㄤ笂杩愯屻
Open Watcom C/C++ 镄1.4鐗堜簬2005骞12链埚彂琛岋纴閲囩敤 Linux x86 涓哄疄楠岀洰镙, 鏀鎸丯T銆丱S/2绛塰ost骞冲彴镟炬湁镆愯寮幂疆镄凲NX鐗堟湰锛屼絾鍏剁紪璇戞墍椤荤殑搴揿苟链寮婧愬彂琛屻傚綋鍓嶆渶杩戠殑绋冲畾鐗堟槸1.9鐗堬纴鍦2010骞6链埚彂琛屻
4銆丏igital Mars
DigitalMars鏄涓娆鹃珮镐ц兘镄勭紪璇戝櫒锛屽姛鑳藉寘钖锛屽揩阃熺紪璇/阈炬帴镞躲佸己澶х殑浼桦寲鎶链銆丆ontract璁捐°佸畬鏁寸殑璧勬簮搴撱佹祻瑙圚TML鏂囨。锛屽弽姹囩紪銆佸簱銆佽祫婧愮紪璇戝櫒绛夈傚懡浠よ屽强GUI鐗堟湰銆佹暀绋嬨佷唬镰佺ず渚嬨佸湪绾挎洿鏂般佹爣鍑嗘ā𨱒垮簱绛夌瓑銆
5銆丮SVC绯诲垪
涓嵘isual Studio闆嗘垚鍙戝竷锛屽井杞镊宸辩殑缂栬疟鍣锛孷S鏄涓涓锘烘湰瀹屾暣镄勫紑鍙戝伐鍏烽泦锛屽畠鍖呮嫭浜嗘暣涓杞浠剁敓锻藉懆链熶腑镓闇瑕佺殑澶ч儴鍒嗗伐鍏凤纴濡俇ML宸ュ叿銆佷唬镰佺℃带宸ュ叿銆侀泦鎴愬紑鍙戠幆澧(IDE)绛夌瓑銆
镓鍐欑殑鐩镙囦唬镰侀傜敤浜庡井杞鏀鎸佺殑镓链夊钩鍙帮纴鍖呮嫭Microsoft Windows銆乄indows Mobile銆乄indows CE銆.NET Framework銆.NET Compact Framework鍜孧icrosoft Silverlight 鍙奥indows Phone銆
⑤ 编译原理中的句柄是什么意思
是操作系统用来管理不同的对象,给他们一个编号而已
比如窗口、线程、图标等都会对应一个句柄,这样可以方便标识与管理
句柄其实也就是一个整数值,而且是唯一的
⑥ 交叉编译器的分类
编译器可以生成用来在与编译器本身所在的计算机和操作系统(平台)相同的环境下运行的目标代码,这种编译器又叫做“本地”编译器。另外,编译器也可以生成用来在其它平台上运行的目标代码,这种编译器又叫做交叉编译器。交叉编译器在生成新的硬件平台时非常有用。“源码到源码编译器”是指用一种高阶语言作为输入,输出也是高阶语言的编译器。例如: 自动并行化编译器经常采用一种高阶语言作为输入,转换其中的代码,并用并行代码注释对它进行注释(如OpenMP)或者用语言构造进行注释(如FORTRAN的DOALL指令)。
预处理器(preprocessor)
作用是通过代入预定义等程序段将源程序补充完整。
编译器前端(frontend)
前端主要负责解析(parse)输入的源代码,由语法分析器和语意分析器协同工作。语法分析器负责把源代码中的‘单词’(Token)找出来,语意分析器把这些分散的单词按预先定义好的语法组装成有意义的表达式,语句 ,函数等等。 例如“a = b + c;”前端语法分析器看到的是“a, =, b , +, c;”,语意分析器按定义的语法,先把他们组装成表达式“b + c”,再组装成“a = b + c”的语句。 前端还负责语义(semantic checking)的检查,例如检测参与运算的变量是否是同一类型的,简单的错误处理。最终的结果常常是一个抽象的语法树(abstract syntax tree,或 AST),这样后端可以在此基础上进一步优化和处理。
编译器后端(backend)
编译器后端主要负责分析,优化中间代码(Intermediate representation)以及生成机器代码(Code Generation)。
一般说来所有的编译器分析,优化,变型都可以分成两大类:函数内(intraproceral)还是函数之间(interproceral)进行。很明显,函数间的分析,优化更准确,但需要更长的时间来完成。
⑦ 编译原理第三版清华大学
“编译原理”是计算机专业非常重要的一门专业课,在计算机教学中有着举足轻重的地位。
编译原理中编译系统是整个计算机系统中极其重要的系统软件,它的作用是把计算机高级语言最终翻译成等价的计算机指令,从而保证高级程序设计语言顺利运行。所以,“编译原理”是计算机科学中基本研究内容之一。
编译器:编译器是计算机程序中应用比较多的工具,在对编译器进行前端设计时,一定要充分考虑影响因素,还要对词法、语法、语义进行分析。
过程分析:将高级程序设吾言,如C、C++、Java等,翻译成计算机可以执行的机器指令代码流的过程,即是编译的过程。编译过程一般分为6个步骤,即词法分析、语法分析、语义分析、中间代码生成、中间代码优化、目标代码生成。