当前位置:首页 » 编程软件 » 编译程序框架图

编译程序框架图

发布时间: 2025-05-24 15:30:05

编译程序有哪些主要构成成分它们各自的主要功能是什么

编译过程分为分析和综合两个部分,并进一步划分为词法分析、语法分析、语义分析、代码优化、存储分配和代码生成等六个相继的逻辑步骤。这六个步骤只表示编译程序各部分之间的逻辑联系,而不是时间关系。

编译过程既可以按照这六个逻辑步骤顺序地执行,也可以按照平行互锁方式去执行。在确定编译程序的具体结构时,常常分若干遍实现。对于源程序或中间语言程序,从头到尾扫视一次并实现所规定的工作称作一遍。每一遍可以完成一个或相连几个逻辑步骤的工作。

例如,可以把词法分析作为第一遍;语法分析和语义分析作为第二遍;代码优化和存储分配作为第三遍;代码生成作为第四遍。

反之,为了适应较小的存储空间或提高目标程序质量,也可以把一个逻辑步骤的工作分为几遍去执行。例如,代码优化可划分为代码优化准备工作和实际代码优化两遍进行。

(1)编译程序框架图扩展阅读

从左至右逐个字符地对源程序进行扫描,产生一个个的单词符号,把作为字符串的源程序改造成为单词符号串的中间程序。执行词法分析的程序称为词法分析程序或扫描器。

源程序中的单词符号经扫描器分析,一般产生二元式:单词种别;单词自身的值。单词种别通常用整数编码,如果一个种别只含一个单词符号,那么对这个单词符号,种别编码就完全代表它自身的值了。若一个种别含有许多个单词符号,那么,对于它的每个单词符号,除了给出种别编码以外,还应给出自身的值。

词法分析器一般来说有两种方法构造:手工构造和自动生成。手工构造可使用状态图进行工作,自动生成使用确定的有限自动机来实现。

编译程序的语法分析器以单词符号作为输入,分析单词符号串是否形成符合语法规则的语法单位,如表达式、赋值、循环等,最后看是否构成一个符合要求的程序,按该语言使用的语法规则分析检查每条语句是否有正确的逻辑结构,程序是最终的一个语法单位。编译程序的语法规则可用上下文无关文法来刻画。

Ⅱ 高级语言程序有两种工作方式编译方式和解释方式

具体如下。
编译型工作过程图,编译程序功能就是把高级语言书写的源代码译成与之等价的目标程序(汇编语言或机器语言)。解释型,解释程序实现高级语言的三种方式解释型在词法、语法和语义分析方面与编译程序的工作原理基本相同,但在运行时直接执行源程序或源程序的内部形式,即解释程序不产生源程序的目标程序,解释程序通常可以分为两部分:第一部分是分析部分,经语义分析后把源程序翻译成中间代码,中间代码常用逆波兰式表示。第二部分是解释部分。
高级语言(High-levelprogramminglanguage)是一种独立于机器,面向过程或对象的语言。高级语言是参照数学语言而设计的近似于日常会话的语言。例如,要将2个变量相加并赋值给第三个变量,用高级语言表达为var3=var1+var2。

Ⅲ tc 编译、连接和生成程序分别叫什么名字求助高手!!!!!

何编译、调试和运行源程序。并给出Turbo C的常用编辑命令。最后介绍Turbo C编译、连接和运行时的常见错误。

一、Turbo C程序设计基本步骤
程序设计方法包括三个基本步骤:
第一步: 分析问题。
第二步: 画出程序的基本轮廓。
第三步: 实现该程序。
3a. 编写程序
3b. 测试和调试程序
3c. 提供数据打印结果
下面, 我们来说明每一步的具体细节。
第一步: 分析问题
在这一步, 你必须:
a. 作为解决问题的一种方法, 确定要产生的数据(输出)。作为这一子步的一部分, 你应定义表示输出的变量。
b. 确定需产生输出的数据(称为输入), 作为这一子步的一部分, 你应定义表示输入的变量。
c. 研制一种算法, 从有限步的输入中获取输出。 这种算法定义为结构化的顺序操作, 以便在有限步内解决问题。就数字问题而言, 这种算法包括获取输出的计算, 但对非数字问题来说, 这种算法包括许多文本和图象处理作。

第二步: 画出程序的基本轮廓
在这一步, 你要用一些句子(伪代码)来画出程序的基本轮廓。每个句子对应一个简单的程序操作。对一个简单的程序来说, 通过列出程序顺序执行的动作,便可直接产生伪代码。然而, 对复杂一些的程序来说, 则需要将大致过程有条理地进行组织。对此, 应使用自上而下的设计方法。
当使用自上而下的设计方法时, 你要把程序分割成几段来完成。列出每段要实现的任务, 程序的轮廓也就有了, 这称之为主模块。当一项任务列在主模块时,仅用其名加以标识, 并未指出该任务将如何完成。这方面的内容留给程序设计的下一阶段来讨论。将程序分为几项任务只是对程序的初步设计。整个程序设计归结为下图所示的流程图1.。
┏━━━━━━━━━━━━━━━┓
┃ 主模块 ┃
┏━━━━━━━┓ ┃ 输入数据 ┃
┃ 主模块 ┃ ┃ 计算购房所需的金额 ┃
┃ ┃ ┃ 计算装修所需的金额 ┃
┃ 任务1 ┃ ┃ 计算总金额 ┃
┃ 任务2 ┃ ┃ 输出计算结果 ┃
┃ 任务3 ┃ ┃ ┃
┃ 任务4 ┃ ┗━━━━━━━┳━━━━━━━┛
┃ ┃ ┏━━━━━┳━━━━━╋━━━━┳━━━━━┓
┃ ┃ ┏━━┻━┓┏━━┻━┓┏━━┻━┓┏━┻━┓┏━━┻━┓
┗━━━━━━━┛ ┃输入数据┃┃购房额..┃┃装修额..┃┃总额..┃┃输出结果┃
┗━━━━┛┗━━━━┛┗━━━━┛┗━━━┛┗━━━━┛
图1. 程序初步设计 图2. 第二级程序设计

如果把主模块的每项任务扩展成一个模块, 并根据子任务进行定义的话, 那么, 程序设计就更为详细了(见图2.)。这些模块称为主模块的子模块。程序中许多子模块之间的关系可象图2.中那样归结为一张图。这种图称为结构图。
要画出模块的轮廓, 你可不考虑细节。如果这样的话, 你必须使用子模块,将各个模块求精, 达到第三级设计。继续这一过程, 直至说明程序的全部细节。
这一级一级的设计过程称为逐步求精法。在编写程序之前, 对你的程序进行逐步求精, 对你来说, 是很好的程序设计实践, 会使你养成良好的设计习惯。
我们则才描述了程序设计中自上而下的设计方法。实际上就是说, 我们设计程序是从程序的"顶部"开始一直考虑到程序的"底部"。

第三步: 实现该程序
程序设计的最后一步是编写源码程序。 在这一步, 把模块的伪代码翻译成Turbo C语句。
对于源程序, 你应包含注释方式的文件编制, 以描述程序各个部分做何种工作。此外, 源程序还应包含调试程序段, 以测试程序的运行情况, 并允许查找编程错误。一旦程序运行情况良好, 可去掉调试程序段, 然而, 文件编制应做为源程序的固定部分保留下来, 便于你或其他人维护和修改。
二、源程序的输入、编译和运行

C语言是一种中级语言, 用户用C语言编写的程序称为源程序, 存放用C 语言所写源程序文件名字最后的两个字符一般必须为".c"。计算机硬件不能直接执行源程序, 必须将源程序翻译成二进制目标程序。翻译工作是由一个程序完成的,这个程序称为编译程序, 翻译的过程称为编译, 编译的结果称为目标程序, 存放目标程序文件名字紧后的字符一般为".OBJ"或".O"。程序翻译成目标程序后, 便可进行连接。"连接"的目的是使程序变成在计算机上可以执行的最终形式。在这一阶段, 从系统程序库来的程序要与目标程序连接, 连接的结果称为执行程序,存放执行程序文件名字一般以".EXE"结尾。
在Turbo C集成开发环境中建立一个新程序通常有以下几个步骤:
(1). 在编辑器中编写源文件。
(2). 生成可执行文件。

在DOS提示符下键入TC, 即可进入Turbo C了。进入主TC屏后, 按F3键, 即可在随之出现的框中输入文件名, 文件名可以带".C"也可以不带( 此时系统会自动加上)。输入文件名后, 按回车, 即可将文件调入, 如果文件不存在, 就建立一个新文件(也可用下面例子中的方法输入文件名)。系统随之进入编辑状态。就可以输入或修改源程序了, 源程序输入或修改完毕以后, 按Ctrl+F9(同时按下Ctrl键和F9键), 则立即进行编译、连接和执行, 这三项工作是连续完成的。
下面我们试着建立一个Turbo C名为"HELLO.C"的源程序(因程序很小, 这里就不画出该程序的轮廓图了):
1. 操作步骤:
(1). 将系统置于DOS提示符下:
(2). 键入命令:
tc hello.c
使系统进入Turbo C集成开发环境, 并建立一个名为HELLO.C的文件。这时, 系统进入Turbo C编辑环境。
(3). 通过键盘输入程序, 例如:
main()
{
printf("Hello, world\n");
}
则程序进入计算机存贮器。
2. 程序存盘
为防止意外事故丢失程序, 最好将输入的程序存贮到磁盘中。在编辑窗口下,可直接按F2键或按F10键, 再按F键进入File菜单项, 再按S或W键将文件存盘。存盘时屏幕最底行会显示:
"saving edit file"
3. 编译一个程序
对源程序进行编译有两种方法: (1). 直接按Alt+F9即可。(2). 按F10 键返回主菜单, 选择Compile项, 屏幕显示Compile 下拉菜单, 从下拉菜单中选择Compile to .OBJ项, 按回车键。
进入编译状态后, 屏幕会出现一个编译窗口, 几秒钟后, 屏幕显示一闪烁信息:
Success: press any key
表示编译成功。此时可按任意键, 编译窗口消失, 光标返回主菜单。
如果编译时产生警告Warning或出错Error信息, 这些具体错误信息会显示在屏幕下部的信息窗中, 必须纠正这些错误。对源程序进行修改, 重新进行编译。
4. 运行程序
源程序经编译无误后, 可以投入运行。具体操作如下:
(1). 如果当前还在编辑状态, 可按Alt+R, 再选择RUN项即可。
(2). 按Ctrl+F9。
程序投入运行时, 屏幕会出现一个连接窗口, 显示Turbo C 正在连接和程序所需的库函数。连接完毕后, 会出现屏幕突然一闪, 后又回到TC主屏幕, 发生了什么? 让我们按Alt+F5看看, 此时屏幕被清除, 在顶部显示"Hello, world"字样。再按任意键, 即可又回到TC主屏幕。
5. 列磁盘文件目录
现在请按Alt+X退出Turbo C, 返回DOS提示符, 键入dir hello.*, 回车, 则屏幕显示:
HELLO C 42 1-09-93 10:18
HELLO OBJ 221 1-09-93 10:22
HELLO EXE 4486 1-09-93 10:25
...
第一个文件HELLO.C是源文件文本, 在DOS提示符下键入TYPE HELLO.C命令,可在屏幕上显示该文件的内容。可看到该程序只有42个字节。
第二个文件HELLO.OBJ是Turbo C编择程序产生的二进制机器指令(目标码),如果用DOS命令TYPE显示该文件, 屏幕可能会出现混乱的信息。
第三个文件HELLO.EXE是Turbo C连接程序产生的实际可执行文件。在DOS 提示符下键入HELLO并按回车, 屏幕将显示"Hello, world"。

Turbo C 常用的编辑命令
Turbo C编辑程序大约有50条命令, 用以移动光标, 按页查看正文, 查找并替换字符串等。如下表所示。

表1. Turbo C编辑程序命令
━━━┳━━━━━━━━━┳━━━━━━━━━━━━━
类别 ┃ 功能 ┃ 默认键
━━━╋━━━━━━━━━╋━━━━━━━━━━━━━
┃ 字符左 ┃ Ctrl+S或Left
基 ┃ 字符右 ┃ Ctrl+D或Right
本 ┃ 字左 ┃ Ctrl+A
光 ┃ 字右 ┃ Ctrl+F
标 ┃ 上行 ┃ Ctrl+E或Up
移 ┃ 下行 ┃ Ctrl+X或Down
动 ┃ 上滚 ┃ Ctrl+W
命 ┃ 下滚 ┃ Ctrl+Z
令 ┃ 上一页 ┃ Ctrl+R或PgUp
┃ 下一页 ┃ Ctrl+C或PgDn
━━━╋━━━━━━━━━╋━━━━━━━━━━━━━
快 ┃ 行头 ┃ Ctrl+QS或Home
速 ┃ 行尾 ┃ Ctrl+QD或End
光 ┃ 窗口头 ┃ Ctrl+QE
标 ┃ 窗口底 ┃ Ctrl+QX
移 ┃ 文件头 ┃ Ctrl+QR
动 ┃ 文件尾 ┃ Ctrl+QC
命 ┃ 块头 ┃ Ctrl+QB
令 ┃ 块尾 ┃ Ctrl+QK
┃ 上次光标位置 ┃ Ctrl+QP
━━━╋━━━━━━━━━╋━━━━━━━━━━━━━
输 ┃ 插入模式 ┃ Ctrl+V或Ins
入 ┃ 插入行 ┃ Ctrl+N
与 ┃ 删除行 ┃ Ctrl+Y
删 ┃ 删除至行尾 ┃ Ctrl+QY
除 ┃ 删除光标左边字符┃ Ctrl+H或Backspace
命 ┃ 删除光标处字符 ┃ Ctrl+G或Del
令 ┃ 删除光标右边字符┃ Ctrl+T
━━━╋━━━━━━━━━╋━━━━━━━━━━━━━
┃ 标记块首 ┃ Ctrl+KB
┃ 标记块尾 ┃ Ctrl+KK
┃ 标记单个字 ┃ Ctrl+KT
块 ┃ 复制块 ┃ Ctrl+KC
命 ┃ 删除块 ┃ Ctrl+KY
令 ┃ 块取消 ┃ Ctrl+KH
┃ 块移动 ┃ Ctrl+KV
┃ 读块 ┃ Ctrl+KR
┃ 写块 ┃ Ctrl+KW
━━━╋━━━━━━━━━╋━━━━━━━━━━━━━
┃ 异常结束操作 ┃ Ctrl+U或Ctrl+Break
┃ 制表 ┃ Ctrl+L或Tab
其 ┃ 自动缩进 ┃ Ctrl+OI
┃ 定界符配对 ┃ Ctrl+Q[或Ctrl+Q]
它 ┃ 查找 ┃ Ctrl+QF
┃ 查找并替换 ┃ Ctrl+QA
┃ 查找标记 ┃ Ctrl+QN
┃ 退出编辑 ┃ Ctrl+KQ
━━━┻━━━━━━━━━┻━━━━━━━━━━━━━

Turbo C 程序的调试

一个程序设计好了以后, 通常会有一些错误, 查找和修改程序中的错误是令人头痛的事。Turbo C集成开发环境提供了一调试装置, 使得这一个工作容易了许多, 程序调试达到了编译和运行级。

一、TC消息窗口

使用TC最好的理由之一是它允许用户修改语法错误(编译时) 和评估编译器给出的警告。TC将编译器和连接器发出的消息收集到一缓冲区中, 然后在消息窗口中显示, 这样在访问源代码的同时, 还能一下看到这些消息。
现将上面的HELLO.C制造一点语法错误, 将第一行包含语句的#去掉, 再去掉第五行printf语句中的后引号。现在程序看上去是这样的:
include <stdio.h>
main()
{
printf("Hello, world\n);
}
按CTRL+F9重新编译之。编译窗口将显示有多少错误和警告: 应为两个错误, 0个
警告。
当看见编译窗口中的Press anykey提示时, 按空格键, 消息窗口立刻被激活,亮条出现在第一个错误或警告上, 这时编辑窗口中也会有一亮条--- 它标志着编译器给出的错误或警告在源代码中的相应位置。
这时可用光标键将消息窗口中的亮条上下移动, 注意到编辑窗口中的亮条也随着跟踪源代码中错误发生的位置。如果将亮条置于"compile"上, 则编辑器显示文件的最后位置。
如果消息窗口太长看不见, 可用左、右光标水平滚动消息, 为了一次能够多看点信息, 可按F5放大消息窗口。放大后, 编辑窗口不可见了, 因此不进行错误跟踪。现在, 保持分屏模式。
为了改正错误, 将消息窗口中的亮条置于第一个错误消息上, 回车, 光标移到编辑窗口中错误产生处, 注意, 编辑器状态给出所选消息( 这在放大模式下是有用的)改正之。(将第一行拿走的#重新写上)。
当不只一个错误时, 可用两种方法来修改下一错误。
第一种方法和前面一样, 按F6回到消息窗口选择想修改的下一条消息。
第二种方法不用回到消息窗口, 只要按Alt+F8, 编译器就会将光标移至消息窗口中列的下一个错误。按Alt+F7可移至前一个错误。
这两种方法各有长短, 视情况而定。有时源代码中一个愚蠢的错误把编译弄糊涂了, 产生好多消息, 这时选择修改第一条消息就使得其余的一些错误消息没有什么意义了, 这种情况发生时, 使用方法一会方便些, 一修改完第一个错误之后回到消息窗口, 再滚动到下一个有意义的消息上, 选择之。在别的情况下, 按Alt+F8会方便得多。
记住, Alt+F7和Alt+F8是热键, TC中无论何时均起作用。因此在消息窗口中按Alt+F8得到的不是当前亮行消息, 而是下一个消息(按Enter选择当前消息)。
但如果没别的编译消息, Alt+F8就不起作用了。
注: 可以如此法选择连接消息, 但它们不跟踪源文件。在修改语法错误的过程当中, 经常需要增加、删除正文, 编辑器是记住的, 依然能正确定位错误位置。
没有必要记住行号和增加、删除的正文行。

二、Turbo C集成调试器

一旦修改好语法错误之后程序编译就没什么问题了, 但还是可能不按要求运行, 因为可能有逻辑错误(运行错误)。这种错误跟踪就无助于发现错误位置了。TC有一个集成调试器可以跟踪运行错误。通过调试器可以运行, 在断点处暂停,检查变量的值, 甚至可以改变之, 以看程序会有什么反应。
Turbo C集成调试器是源程序级的调试器, 即用同你编写程序一样的" 语言"来控制调试器。例如, 为了显示数组中的一个元素的值, 可告诉调试器显示这样的表达式的值:
Ctrl+F4 Debug/Eavluate 计算表达式, 允许修改变量的值。
Debug/Find Function 查找函数定义, 显示在编辑窗口中。 仅在调试时才有效。
Ctrl+F3 Debug/Call Stack 显示调用栈, 可显示任何函数的当前执行位置, 其方法是在调用栈中选择相应的
函数名。仅在调试时有效。
Debug/Source Debugging 控制是否允许调试: 置为On时, 集成调
试器和单独调试器均可用 ; 置为
Standalone时, 只能用单独调试器
调试, 虽然还能在TC中运行; 置为
None时, 在.EXE文件不置调试信息,
两种调试均不能调试。
Ctrl+F4 Break/Watch/Add Watch 增加一监视表达式。
Break/Watch/Delete Watch 删除一监视表达式。
Break/Watch/Edit 编辑一监视表达式。
Break/Watch/Remove All 删除所有监视表达式。
Watches
Ctrl+F8 Break/Watch/Toggle 设置或清除光标所在行的断点。
Breakpoint
Break/Watch/Clear 删除程序中所有断点。
Breakpoint
Break/Watch/Next 显示下一断点
Breakpoint
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

表3. 调试器菜单命令及其热键
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
热键 菜单命令 功能
———————————————————————————————————
F5 在整屏和分屏之间放大缩小活动窗口。
Alt+F5 将显示转到用户屏, 击任意键返回。
F6 在编辑窗口与监视窗口或消息窗口间
切换。
Alt+F6 若编辑窗口是活动的, 转到最近一次
装入编辑器的文件; 若下面窗口是活
动的, 则在监视窗口和消息窗口间切换。
Ctrl+F9 Run/Run 调试运行或不调试运行程序, 必要时
编译、连接源文件, 若编译、 连接时
Debug/Source Debuging和O/C/C/OBJ
Debug Information为On, 则运行程序
到断点或程序末尾。
Project/Remove Messages 删除消息窗口中的内容。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

判断程序是否出错或者为什么出错是编程中最有挑战意义的一方面。这里建义你进行预防性设计, 具体做法为:
(1). 将代码写清楚点, 应作适当缩进, 使用文字说明和描述性的变量名。
(2). 代码应简单, 把精力放在简单语句中的复杂表达式, 而不是一些复杂语句。Turbo C的代码优化机制将大大提高代码的效率, 而且调试、阅读、 修改
起来容易。
(3). 尽量用目的简单、好定义的函数构建程序。 这会便于编制调试程序和分析结果, 而且阅读、修改起来也要容易一些。
(4). 应尽量减少各个函数要求的数据和改变数据的元素个数。这也会便于编制测试程序和分析结果; 同样便于阅读、修改程序。并且还限制了出错函数可能造成的巨大混乱的牵涉面, 便得能在一个调试节中多运行函数几次。
(5). 要留心编写程序中的公共函数, 或者说在其它程序中可再用的函数.编写、调试一个一般性的函数通常要比编写、调试两个或更多的特殊函数要容易。

Turbo C编译、连接和运行时的常见错误
一、编译时的常见错误
1. 数据类型错误。此类错误是初学者编程时的常见现象, 下面是一些要引起注意的错误:
(1) 所有变量和常量必须要加以说明。
(2) 变量只能赋给相同类型的数据。
(3) 对scanf()语句, 用户可能输入错误类型的数据项, 这将导致运行时出错, 并报出错信息。为避免这样的错误出现, 你就提示用户输入正确类型的数据。
(4) 在执行算术运算时要注意:
a. 根据语法规则书写双精度数字。要写0.5, 而不是写.5; 要写1.0,
而不是1。尽管C语言会自动地把整型转换成双精度型, 但书写双精
度型是个好习惯。让C语言为你做强行转换这是一种效率不高的程序
设计风格。 这有可能导致转换产生错误。
b. 不要用0除。这是一个灾难性的错误, 它会导致程序失败, 不管C
语言的什么版本, 都是如此, 执行除法运算要特别小心。
c. 确保所有的双精度数(包括那些程序输入用的双精度数) 是在实数
范围之内。
d. 所有整数必须在整数允许的范围内。这适用于所有计算结果,包括中间结果。

2. 将函数后面的";"忘掉。此时错误提示色棒将停在该语句下的一行, 并显示:
Statement missing ; in function <函数名>

3. 给宏指令如#include, #define等语句尾加了";"号。

4. ""、"("和")"、"/*"和"*/"不匹配。 引时色棒将位于错误所在的行, 并提示出有关丢掉括号的信息。

5. 没有用#include指令说明头文件, 错误信息提示有关该函数所使用的参数未定义。

6. 使用了Turbo C保留关键字作为标识符, 此时将提示定义了太多数据类型。

7. 将定义变量语句放在了执行语句后面。此时会提示语法错误。

8. 使用了未定义的变量, 此时屏幕显示:
Undefined symbol '<变量名>' in function <函数名>

9. 警告错误太多。忽略这些警告错误并不影响程序的执行和结果。编译时当警告错误数目大于某一规定值时(缺省为100)便退出编译器, 这时应改变集成开发环境Options/Compiler/Errors中的有关警告错误检查开关为off。

10. 将关系符"=="误用作赋值号"="。此时屏幕显示:
Lvalue required in function <函数名>

二、连接时的常见错误

1. 将Turbo C库函数名写错。这种情况下在连接时将会认为此函数是用户自定义函数。此时屏幕显示:
Undefined symbol '<函数名>' in <程序名>

2. 多个文件连接时, 没有在"Project/Project name中指定项目文件 (.PRJ文件), 此时出现找不到函数的错误。

3. 子函数在说明和定义时类型不一致。
4. 程序调用的子函数没有定义。

三、运行时的常见错误

1. 路径名错误。在MS-DOS中, 斜杠(\)表示一个目录名; 而在Turbo C 中斜杠是个某个字符串的一个转义字符, 这样, 在用Turbo C 字符串给出一个路径名时应考虑"\"的转义的作用。例如, 有这样一条语句: file=fopen("c:\new\tbc.dat", "rb");
目的是打开C盘中NEW目录中的TBC.DAT文件, 但做不到。这里"\"后面紧接的分别是"n"及"t", "\n"及"\t"将被分别编译为换行及tab字符, DOS将认为它是不正确的文件名而拒绝接受, 因为文件名中不能和换行或tab字符。正确的写法应为:
file=fopen("c:\\new\\tbc.dat", "rb");
2. 格式化输入输出时, 规定的类型与变量本身的类型不一致。例如:
float l;
printf("%c", l);
3. scanf()函数中将变量地址写成变量。例如:
int l;
scanf("%d", l);
4. 循环语句中, 循环控制变量在每次循环未进行修改, 使循环成为无限循
环。
5. switch语句中没有使用break语句。
6. 将赋值号"="误用作关系符"=="。
7. 多层条件语句的if和else不配对。
8. 用动态内存分配函数malloc()或calloc()分配的内存区使用完之后, 未用free()函数释放, 会导致函数前几次调用正常, 而后面调用时发生死机现象,不能返回操作系统。其原因是因为没用空间可供分配, 而占用了操作系统在内存中的某些空间。
9. 使用了动态分配内存不成功的指针, 造成系统破坏。
10. 在对文件操作时, 没有在使用完及时关闭打开的文件。

Ⅳ 编译原理

C语言编译过程详解
C语言的编译链接过程是要把我们编写的一个C程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接。编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程。链接是把目标文件、操作系统的启动代码和用到的库文件进行组织形成最终生成可执行代码的过程。过程图解如下:

从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程。
一、编译过程
编译过程又可以分成两个阶段:编译和汇编。
1、编译
编译是读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,源文件的编译过程包含两个主要阶段:
第一个阶段是预处理阶段,在正式的编译阶段之前进行。预处理阶段将根据已放置在文件中的预处理指令来修改源文件的内容。如#include指令就是一个预处理指令,它把头文件的内容添加到.cpp文件中。这个在编译之前修改源文件的方式提供了很大的灵活性,以适应不同的计算机和操作系统环境的限制。一个环境需要的代码跟另一个环境所需的代码可能有所不同,因为可用的硬件或操作系统是不同的。在许多情况下,可以把用于不同环境的代码放在同一个文件中,再在预处理阶段修改代码,使之适应当前的环境。
主要是以下几方面的处理:
(1)宏定义指令,如 #define a b。
对于这种伪指令,预编译所要做的是将程序中的所有a用b替换,但作为字符串常量的 a则不被替换。还有 #undef,则将取消对某个宏的定义,使以后该串的出现不再被替换。
(2)条件编译指令,如#ifdef,#ifndef,#else,#elif,#endif等。
这些伪指令的引入使得程序员可以通过定义不同的宏来决定编译程序对哪些代码进行处理。预编译程序将根据有关的文件,将那些不必要的代码过滤掉
(3) 头文件包含指令,如#include "FileName"或者#include <FileName>等。
在头文件中一般用伪指令#define定义了大量的宏(最常见的是字符常量),同时包含有各种外部符号的声明。采用头文件的目的主要是为了使某些定义可以供多个不同的C源程序使用。因为在需要用到这些定义的C源程序中,只需加上一条#include语句即可,而不必再在此文件中将这些定义重复一遍。预编译程序将把头文件中的定义统统都加入到它所产生的输出文件中,以供编译程序对之进行处理。包含到C源程序中的头文件可以是系统提供的,这些头文件一般被放在/usr/include目录下。在程序中#include它们要使用尖括号(<>)。另外开发人员也可以定义自己的头文件,这些文件一般与C源程序放在同一目录下,此时在#include中要用双引号("")。
(4)特殊符号,预编译程序可以识别一些特殊的符号。
例如在源程序中出现的LINE标识将被解释为当前行号(十进制数),FILE则被解释为当前被编译的C源程序的名称。预编译程序对于在源程序中出现的这些串将用合适的值进行替换。
预编译程序所完成的基本上是对源程序的“替代”工作。经过此种替代,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。这个文件的含义同没有经过预处理的源文件是相同的,但内容有所不同。下一步,此输出文件将作为编译程序的输出而被翻译成为机器指令。
第二个阶段编译、优化阶段。经过预编译得到的输出文件中,只有常量;如数字、字符串、变量的定义,以及C语言的关键字,如main,if,else,for,while,{,}, +,-,*,\等等。
编译程序所要作得工作就是通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码。
优化处理是编译系统中一项比较艰深的技术。它涉及到的问题不仅同编译技术本身有关,而且同机器的硬件环境也有很大的关系。优化一部分是对中间代码的优化。这种优化不依赖于具体的计算机。另一种优化则主要针对目标代码的生成而进行的。
对于前一种优化,主要的工作是删除公共表达式、循环优化(代码外提、强度削弱、变换循环控制条件、已知量的合并等)、复写传播,以及无用赋值的删除,等等。
后一种类型的优化同机器的硬件结构密切相关,最主要的是考虑是如何充分利用机器的各个硬件寄存器存放的有关变量的值,以减少对于内存的访问次数。另外,如何根据机器硬件执行指令的特点(如流水线、RISC、CISC、VLIW等)而对指令进行一些调整使目标代码比较短,执行的效率比较高,也是一个重要的研究课题。
2、汇编
汇编实际上指把汇编语言代码翻译成目标机器指令的过程。对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。目标文件中所存放的也就是与源程序等效的目标的机器语言代码。目标文件由段组成。通常一个目标文件中至少有两个段:
代码段:该段中所包含的主要是程序的指令。该段一般是可读和可执行的,但一般却不可写。
数据段:主要存放程序中要用到的各种全局变量或静态的数据。一般数据段都是可读,可写,可执行的。
UNIX环境下主要有三种类型的目标文件:
(1)可重定位文件
其中包含有适合于其它目标文件链接来创建一个可执行的或者共享的目标文件的代码和数据。
(2)共享的目标文件
这种文件存放了适合于在两种上下文里链接的代码和数据。
第一种是链接程序可把它与其它可重定位文件及共享的目标文件一起处理来创建另一个 目标文件;
第二种是动态链接程序将它与另一个可执行文件及其它的共享目标文件结合到一起,创建一个进程映象。
(3)可执行文件
它包含了一个可以被操作系统创建一个进程来执行之的文件。汇编程序生成的实际上是第一种类型的目标文件。对于后两种还需要其他的一些处理方能得到,这个就是链接程序的工作了。
二、链接过程
由汇编程序生成的目标文件并不能立即就被执行,其中可能还有许多没有解决的问题。
例如,某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数,等等。所有的这些问题,都需要经链接程序的处理方能得以解决。
链接程序的主要工作就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。
根据开发人员指定的同库函数的链接方式的不同,链接处理可分为两种:
(1)静态链接
在这种链接方式下,函数的代码将从其所在地静态链接库中被拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态链接库实际上是一个目标文件的集合,其中的每个文件含有库中的一个或者一组相关函数的代码。
(2) 动态链接
在此种方式下,函数的代码被放到称作是动态链接库或共享对象的某个目标文件中。链接程序此时所作的只是在最终的可执行程序中记录下共享对象的名字以及其它少量的登记信息。在此可执行文件被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间。动态链接程序将根据可执行程序中记录的信息找到相应的函数代码。
对于可执行文件中的函数调用,可分别采用动态链接或静态链接的方法。使用动态链接能够使最终的可执行文件比较短小,并且当共享对象被多个进程使用时能节约一些内存,因为在内存中只需要保存一份此共享对象的代码。但并不是使用动态链接就一定比使用静态链接要优越。在某些情况下动态链接可能带来一些性能上损害。
我们在linux使用的gcc编译器便是把以上的几个过程进行捆绑,使用户只使用一次命令就把编译工作完成,这的确方便了编译工作,但对于初学者了解编译过程就很不利了,下图便是gcc代理的编译过程:

从上图可以看到:
预编译
将.c 文件转化成 .i文件
使用的gcc命令是:gcc –E
对应于预处理命令cpp
编译
将.c/.h文件转换成.s文件
使用的gcc命令是:gcc –S
对应于编译命令 cc –S
汇编
将.s 文件转化成 .o文件
使用的gcc 命令是:gcc –c
对应于汇编命令是 as
链接
将.o文件转化成可执行程序
使用的gcc 命令是: gcc
对应于链接命令是 ld
总结起来编译过程就上面的四个过程:预编译、编译、汇编、链接。了解这四个过程中所做的工作,对我们理解头文件、库等的工作过程是有帮助的,而且清楚的了解编译链接过程还对我们在编程时定位错误,以及编程时尽量调动编译器的检测错误会有很大的帮助的。

Ⅳ 涓轰粈涔堢▼搴忚佸厛缂栬疟锛屾墠鑳借繍琛屽晩锛

褰撶紪鍐椤畬涓涓绋嫔簭钖庯纴闇瑕侀栧厛杩涜岀紪璇戯纴铹跺悗鍐嶈繍琛屻

濡备笅锲炬墍绀猴纴绋嫔簭缂栧啓瀹屾瘯钖庯纴镣瑰嚮宸ュ叿镙忎腑镄凟xecute,阃夋嫨compile(缂栬疟锛

濡傛灉娌℃湁阌栾锛屽啀阃夋嫨Execute,阃夋嫨run锛堣繍琛)

镓╁𪾢璧勬枡

缂栬疟灏辨槸鎶婇珮绾ц瑷鍙樻垚璁$畻链哄彲浠ヨ瘑鍒镄2杩涘埗璇瑷锛岃$畻链哄彧璁よ瘑1鍜0锛岀紪璇戠▼搴忔妸浜轰滑镡熸倝镄勮瑷鎹㈡垚2杩涘埗镄勚缂栬疟绋嫔簭鎶娄竴涓婧愮▼搴忕炕璇戞垚鐩镙囩▼搴忕殑宸ヤ綔杩囩▼鍒嗕负浜斾釜阒舵碉细璇嶆硶鍒嗘瀽锛涜娉曞垎鏋愶绂璇涔夋镆ュ拰涓闂翠唬镰佺敓鎴愶绂浠g爜浼桦寲锛涚洰镙囦唬镰佺敓鎴愩备富瑕佹槸杩涜岃瘝娉曞垎鏋愬拰璇娉曞垎鏋愶纴鍙堢О涓烘簮绋嫔簭鍒嗘瀽锛屽垎鏋愯繃绋嬩腑鍙戠幇链夎娉曢敊璇锛岀粰鍑烘彁绀轰俊鎭銆

缂栬疟璇瑷鏄涓绉崭互缂栬疟鍣ㄦ潵瀹炵幇镄勭紪绋嬭瑷銆傚畠涓嶅儚鐩磋疟璇瑷涓镙凤纴鐢辫В閲婂櫒灏嗕唬镰佷竴鍙ヤ竴鍙ヨ繍琛岋纴钥屾槸浠ョ紪璇戝櫒锛屽厛灏嗕唬镰佺紪璇戜负链哄櫒镰侊纴鍐嶅姞浠ヨ繍琛屻傜悊璁轰笂锛屼换浣旷紪绋嬭瑷閮藉彲浠ユ槸缂栬疟寮忥纴鎴栫洿璇戝纺镄勚傚畠浠涔嬮棿镄勫尯鍒锛屼粎涓庣▼搴忕殑搴旂敤链夊叧銆



热点内容
文件上传加速 发布:2025-05-24 22:26:10 浏览:297
数据库访问页 发布:2025-05-24 22:26:07 浏览:529
linux操作命令大全 发布:2025-05-24 22:26:05 浏览:351
排列5源码 发布:2025-05-24 22:19:44 浏览:35
android字符串的截取字符串 发布:2025-05-24 22:17:37 浏览:82
我的世界服务器op菜单怎么做 发布:2025-05-24 22:07:38 浏览:852
安卓接口的耳机如何使用 发布:2025-05-24 22:06:59 浏览:825
tiff编译器 发布:2025-05-24 22:02:02 浏览:494
dosbox怎么编译生成obj 发布:2025-05-24 22:01:13 浏览:755
访问网络access数据库 发布:2025-05-24 22:01:02 浏览:339