编译原理及实践教程参考答案_第1页
编译原理及实践教程参考答案_第2页
编译原理及实践教程参考答案_第3页
编译原理及实践教程参考答案_第4页
编译原理及实践教程参考答案_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1. 翻译程序:能够将某种语言写的程序转换成另一种语言的程序,而且后者与前者在逻 辑上是等价的。编译程序:是一种将高级语言程序 (源程序 )翻译成低级语言 (目标程序 )的程序 解释程序:接受某高级语言的一个语句输入,进行解释并控制计算机执行,马上得到 这句的执行结果,然后再接受下一句。源程序:被翻译的程序。目标程序:翻译后的程序。 遍:对源程序或源程序的中间结果从头到尾扫描一次,并作有关的加工处理,生成新 的中间结果或目标程序。编译前端:主要指与源语言有关,与目标语言无关的部分,通常包括词法分析、语法 分析、语义分析和中间代码生成,与机器无关部分的代码优化编译后端:指与目标机器有关的部分。如

2、与机器有关的优化、目标代码生成2. 高级语言程序有哪两种执行方式?其特点是什么?阐述其主要异同点。 答:高级语言程序有编译程序和解释程序两种执行方式; 编译程序 ( Compiler ) 将高级程序设计语言程序翻译成逻辑上等价的低级语言(汇编语言 ,机器语言 )程序的翻译程序。解释程序 ( Interpreter ) 将高级程序设计语言写的源程序作为输入, 边解释边执行 源程序本身,而不产生目标程序的翻译程序。3. 编译过程可分为哪些阶段?各个阶段的主要任务是什么? 答:编译过程逻辑上可分为五个阶段:词法分析、语法分析、语义分析与中间代码生 成、代码优化、目标代码生成。第一阶段:词法分析任务

3、: 从左到右扫描源程序,识别出每个单词第二阶段:语法分析任务 : 在词法分析的基础上,根据语言的语法规则,将单词符号 串分解成各类语法短语 (例:程序、语句、表达式 )。第三阶段:语义分析和中间代码生成任务 :对语法分析所识别出的各类语法范畴分析 其含义,进行初步的翻译 (翻译成中间代码 )。第四阶段: 代码优化任务 :对已产生的中间代码进行加工变换, 使生成的目标代码更 为高效 (时间和空间 )。第五阶段:目标代码的生成任务 :把中间代码 ( 或经优化的中间代码 )变换成特定机器 上的低级语言代码。4. 编译程序有哪些主要构成成分?各自的主要功能是什么?答: (1) 记号 (token)当扫

4、描程序将字符收集到一个记号中时,它通常是以符号表示这个记号;这也就是说, 作为一个枚举数据类型的值来表示源程序的记号集。(2) 语法树( syntax tree )如果分析程序确实生成了语法树, 它的构造通常为基于指针的标准结构, 在进行分析时 动态分配该结构, 则整棵树可作为一个指向根节点的单个变量保存。 结构中的每一个节点都 是一个记录,它的域表示由分析程序和之后的语义分析程序收集的信息。(3) 符号表( symbol table ) 这个数据结构中的信息与标识符有关:函数、变量、常量以及数据类型。符号表几乎 与编译器的所有阶段交互:扫描程序、分析程序或将标识符输入到表格中的语义分析程序;

5、 语义分析程序将增加数据类型和其他信息; 优化阶段和代码生成阶段也将利用由符号表提供 的信息选出恰当的代码。 因为对符号表的访问如此频繁, 所以插入、 删除和访问操作都必须 比常规操作更有效。 尽管可以使用各种树的结构, 但杂凑表却是达到这一要求的标准数据结 构。有时在一个列表或栈中可使用若干个表格。(4) 常数表( literal table ) 常数表的功能是存放在程序中用到的常量和字符串,因此快速插入和查找在常数表中 也十分重要。 但是, 在其中却无需删除, 这是因为它的数据全程应用于程序而且常量或字符 串在该表中只出现一次。(5) 中间代码( intermediate code ) 根

6、据中间代码的类型(例如三元式代码)和优化的类型,该代码可以是文本串的数组、 临时文本文件或是结构的连接列表。 对于进行复杂优化的编译器, 应特别注意选择允许简单 重组的表示。(6) 临时文件( t e m p o r a ry file ) 计算机过去一直未能在编译器时将整个程序保留在存储器中。 这一问题已经通过使用临 时文件来保存翻译时中间步骤的结果或通过 “匆忙地 ”编译(也就是只保留源程序早期部分的 足够信息用以处理翻译)解决了。5. 编译程序的构造需要掌握哪些原理和技术? 答:源语言:理解其结构和含义 目标语言:必须清楚硬件的系统结构和指令的格式等 编译方法6. 编译程序构造工具的作用

7、是什么?答:自动生成:LEX(词法分析)与YACC(用于自动产生LALR分析表)7. 编译技术可应用在哪些领域?答: 语言的结构化编辑器 :Turbo-Edit 、 editplus 和 Ultraedit 等 语言程序的调试工具语言程序的测试工具 高级语言之间的转换工具 交叉编译程序思考题 1? 1. 什么是编译程序 ?? 一种将高级语言程序 (源程序 )翻译成低级语言 (目标程序 )的程序?2. 编译过程分哪些阶段?各阶段的功能和任务是什么 ?略? 3. 写出 C 语言中字符集、单词、数据类型、各种表达式、语句和程序的组成答: C 语言字符集由字母,数字,空格,标点和特殊字符组成。C 语言

8、常用单词: 1. 数据类型关键字 (8 个 ): .int , short ,long, signed, unsigned .char , float, double2. 程序控制关键字 (10 个):.1) 分支结构 :if , else, switch, case, default, break.2) 循环结构 :do , while, for, continue3. 函数及数据存储关键字 (6 个 ):.void , return, auto, register, static, extern4. 构造数据类型关键字 (5 个 ):.struct, union, enum, typede

9、f, sizeof5. 其它 3个不常用 (3 个).goto, const, volatileC 语言数据类型包括:1. 基本类型(1)整型a.基本型b.长整型c.短整型d.无符号型(2) 实型a.单精度型b.双精度型(3) 字符型(4) 枚举类型2. 构造类型(1) 数组类型 (2) 结构体类型 (3) 共用体类型3. 指针类型C 语言的运算符可分为以下几类:1. 算术运算符用于各类数值运算。包括加 (+)、减(-)、乘(*)、除 (/)、求余 (或称模运算, %)、自增 (+)、 自减 (-)共七种。2. 关系运算符用于比较运算。包括大于 (>)、小于 (<)、等于 (=)

10、、 大于等于 (>=) 、小于等于 (<=) 和不 等于 (!=)六种。3. 逻辑运算符用于逻辑运算。包括与 (&&) 、或(|)、非(!) 三种。4. 位操作运算符参与运算的量,按二进制位进行运算。包括位与(&)、位或(|)、位非、位异或(人)、左移(<<) 、右移 (>>)六种。5. 赋值运算符用于赋值运算,分为简单赋值 (=) 、复合算术赋值 (+=,-=,*=,/=,%=) 和复合位运算赋值 (& =,|=,a=,>>=,<<=)三类共 一种。6. 条件运算符 这是一个三目运算符,用于条件求值

11、(?:)。7.逗号运算符 用于把若干表达式组合成一个表达式(,) 。8. 指针运算符用于取 内容(*)和取地址 (&) 二种运算。9. 求字节数运算符 用于计算数据类型所占的字节数 (sizeof) 。10.特殊运算符有括号(),下标,成员()等几种。优先级和结合性C 语言中,运算符的运算优先级共分为15 级。 1 级最高, 15 级最低。在表达式中,优先级较高的先于优先级较低的进行运算。 而在一个运算量两侧的运算符优先级相同时, 则 按运算符的结合性所规定的结合方向处理。C 语言中各运算符的结合性分为两种,即左结合性 (自左至右 )和右结合性 (自右至左 )。例如算术运算符的结合性是

12、自左至右,即先左后右。如有表达式 x-y+z 则 y 应先与 “-”号结合,执行 x-y 运算,然后再执行 +z 的运算。这种自左至右的结合方向就称为 “左结合性 ”。而自右至左的结合方向称为 “右结合性 ”。 最典型的右 结合性运算符是赋值运算符。如x=y=z, 由于 “=”的右结合性,应先执行 y=z 再执行 x=(y=z)运算。 C 语言运算符中有不少为右结合性,应注意区别,以避免理解错误。算术运算符和算术表达式基本的算术运算符1. 加法运算符 “ +”加法运算符为双目运算符,即应有两个量参与加法运算。如a+b,4+8等。具有右结合性。2. 减法运算符 “-”减法运算符为双目运算符。但

13、“-”也可作负值运算符,此时为单目运算, 如-x,-5等具有左结合性。3. 乘法运算符 “*双”目运算,具有左结合性。4. 除法运算符 “/双”目运算具有左结合性。参与运算量均为整型时,结果也为整型,舍去小数。如果运算量中有一个是实型,则结果为双精度实型。void main() printf("nn%d,%dn",20/7,-20/7); printf("%f,%fn",20.0/7,-20.0/7);双目运算具有左结合性。参与运算量均为整型时,结果也为整型,舍去小数。如果运算量中有一个是实型,则结果为双精度实型。printf("nn%d,%d

14、n",20/7,-20/7);printf("%f,%fn",20.0/7,-20.0/7);本例中, 20/7, -20/7 的结果均为整型,小数全部舍去。而20.0/7 和-20 .0/7 由于有实数参与运算,因此结果也为实型。5. 求余运算符 (模运算符 ) “%”双目运算, 具有左结合性。 要求参与运算的量均为整型。 求 余运算的结果等于两数相除后的余数。void main() printf("%dn",100%3);双目运算,具有左结合性。求余运算符 % 要求参与运算的量均为整型。本例输出 100 除以 3 所得的余数 1。自增 1,

15、自减 1 运算符自增 1 运算符记为 “+”,其功能是使变量的值自增1。自减 1 运算符记为 “-”,其功能是使变量值自减 1。自增 1,自减 1 运算符均为单目运算,都具有右结合性。可有以下几种 形式: +i i 自增 1后再参与其它运算。 -i i 自减 1后再参与其它运算。i+ i 参与运算后, i 的值再自增 1。i-i 参与运算后, i 的值再自减 1。在理解和使用上容易出错的是 i+ 和 i-。 特别是当它们出在较复杂的表达式或语句中 时,常常难于弄清,因此应仔细分析。void main() int i=8; printf("%dn",+i); printf(&

16、quot;%dn",-i); printf("%dn",i+); printf("%dn",i-); printf("%dn",-i+); printf("%dn",-i-); i<-8 i<-i+1 i<-i-1 i<-i+1 i<-i-1 i<-i+1 i<-i-1 int i=8; printf("%dn",+i); printf("%dn",-i); printf("%dn",i+); print

17、f("%dn",i-); printf("%dn",-i+); printf("%dn",-i-);i 的初值为 8第2行i加1后输出故为9;第 3 行减 1 后输出故为 8;第 4 行输出 i 为 8 之后再加 1(为 9);第 5 行输出 i 为 9 之后再减 1(为 8) ;第 6 行输出 -8 之后再加 1(为 9);第 7 行输出 -9 之后再减 1(为 8) void main()int i=5,j=5,p,q;p=(i+)+(i+)+(i+);q=(+j)+(+j)+(+j); printf("%d,%d,%d

18、,%d",p,q,i,j);i<-5,j<-5,p<-0,q<-0i+i+i->p,i+1->i,i+1->i,i+1->i j+1->j,j+1->j,j+1->j,j+j+j->q int i=5,j=5,p,q; p=(i+)+(i+)+(i+);q=(+j)+(+j)+(+j);这个程序中,对 P=(i+)+(i+)+(i+)应理解为三个i相加,故P值为15。然后i再自增 1 三次相当于加 3 故 i 的最后值为 8。而对于 q 的值则不然, q=(+j)+(+j)+(+j) 应理解为 q 先自增 1 ,

19、再参与运算,由于 q 自增 1 三次后值为 8,三个 8 相加的和为 24, j 的最后值仍 为 8。算术表达式表达式是由常量、变量、函数和运算符组合起来的式子。一个表达式有一个值及其类型, 它们等于计算表达式所得结果的值和类型。表达式求值按运算符的优先 级和结合性规定的顺序进行。 单个的常量、变量、函数可以看作是表达式的特例。算术表达式是由算术运算符和括号连接起来的式子, 以下是算术表达式的例子:a+b(a*2) c (x+r)*8-(a+b) 7+i sin(x)+sin(y)(+i)-(j+)+(k-)赋值运算符和赋值表达式简单赋值运算符和表达式,简单赋值运算符记为“=。”由 “=”连接

20、的式子称为赋值表达式。其一般形式为: 变量 =表达式 例如:x=a+bw=sin(a)+sin(b)y=i+-j 赋值表达式的功能是计算表达式的值再赋予左边的变量。赋值运算符具有右结合 性。因此a=b=c=5可理解为a=(b=(c=5)在其它高级语言中,赋值构成了一个语句,称为赋值语句。而在 C 中,把 “=”定义为运算符,从而组成赋值表达式。 凡是表达式可以出现的地方均可出现赋值表达式。例如, 式子x=(a=5)+(b=8)是合法的。它的意义是把5赋予a, 8赋予b,再把a,b相加,和赋予x ,故 x 应等于 13。在 C 语言中也可以组成赋值语句, 按照 C 语言规定, 任何表达式在其未尾

21、加上分号就 构成为语句。因此如 x=8;a=b=c=5 ;都是赋值语句,在前面各例中我们已大量使用过了。如果赋值运算符两边的数据类型不相同, 系统将自动进行类型转换,即把赋值号右边 的类型换成左边的类型。具体规定如下:1. 实型赋予整型,舍去小数部分。前面的例2.9 已经说明了这种情况。2. 整型赋予实型,数值不变,但将以浮点形式存放,即增加小数部分 (小数部分的值为0)。3. 字符型赋予整型,由于字符型为一个字节,而整型为二个字节,故将字符的 ASCII码值放到整型量的低八位中,高八位为 0。4. 整型赋予字符型,只把低八位赋予字符量。void main()int a,b=322;float

22、 x,y=8.88;char c1='k',c2;a=y;x=b;a=c1;c2=b;printf("%d,%f,%d,%c",a,x,a,c2);int a,b=322;float x,y=8.88;char c1='k',c2;prin tf("%d,%f,%d,%c",a=y,x=b,a=c1,c2=b);本例表明了上述赋值运算中类型转换的规则。a为整型,赋予实型量 y值8 88后只取整数8。x为实型,赋予整型量 b值322,后增加了小数部分。字符型量 c1赋予a变为整 型,整型量b赋予c2后取其低八位成为字符型(b

23、的低八位为01000010,即十进制66,按 ASCII码对应于字符 B)。复合赋值符及表达式在赋值符“=之前加上其它二目运算符可构成复合赋值符。如+ =,-=,*=, / =,%=,<< = ,>> = , &=,人=,|=。 构成复合赋值表达式的一般形式为:变量 双目运算符=表达式它等效于变量=变量运算符表达式例如:a+=5等价于a=a+5x*=y+7等价于x=x*(y+7) r%=p等价于r=r%p复合赋值符这种写法,对初学者可能不习惯,但十分有利于编译处理,能提高编译效率并产生质量较高的目标代码。逗号运算符和逗号表达式在逗号运算符C语言中逗号,”也是一种

24、运算符,称为逗号运算符。其功能是把两个表达式连接起来组成一个表达式,称为逗号表达式。其一般形式为:表达式1,表达式2其求值过程是分别求两个表达式的值,并以表达式2的值作为整个逗号表达式的值。void mai n()int a=2,b=4,c=6,x,y;y=(x=a+b),(b+c);prin tf("y=%d,x=%d",y,x);a<_2,b<_4,c<_6,x<_0,y<_0x<-a+b,y<-b+c本例中,y等于整个逗号表达式的值,也就是表达式2的值,x是第一个表达式的值。对于逗号表达式还要说明两点:1. 逗号表达式一般形式

25、中的表达式 1和表达式2也可以又是逗号表达式。例如: 表达 式1,(表达式2,表达式3)形成了嵌套情形。因此可以把逗号表达式扩展为以下形式:表 达式1,表达式2,表达式n整个逗号表达式的值等于表达式 n的值。2. 程序中使用逗号表达式,通常是要分别求逗号表达式内各表达式的值,并不一定要求 整个逗号表达式的值。3. 并不是在所有出现逗号的地方都组成逗号表达式,如在变量说明中,函数参数表中逗 号只是用作各变量之间的间隔符。C语言表达式和语句一、表达式前面已经提到过表达式, 相信大家对表达式也有了一个初步的认识, 它是由常量、变量、运算符组合(到 以后讲函数时,函数也可以是组成表达式的元素),计算以

26、后返回一个结果值。表达式的结束标志是分号(;), C语言中所有的语句和声明都是用分号结束,在分号出现之前,语句是不完整的。例如:1+2;Counter/3+5;Height*Width;(以表达式本身什么事情都不做,只是返回结果值。在程序不对返回的结果值做任何操作的情况下,返回 的结果值不起任何作用,表达式的作用有两点,一个是放在赋值语句的右边,另一个是作为函数的参数 后再介绍 ) 。表达式返回的结果值是有类型的。表达式隐含的数据类型取决于组成表达式的变量和常量的类型。因 此,表达式的返回值有可能是某种大小的整型,或者是某精度的浮点型,或者是某种指针类型。这里面就有类型转化的问题了,在前面说整

27、型运算的时候也提到过。类型转化的原则是从低级向高级 自动转化 (除非人为的加以控制 ) 。计算的转换顺序基本是这样的:字符型-整型-长整型-浮点型-单精度型 -双精度型 就是当字符型和整型在一起运算时,结果为整型,如果整型和浮点型在一起运算,所得的结果就是浮 点型,如果有双精度型参与运算,那么答案就是双精度型了。强制转换是这样的,在类型说明符的两边加上括号,就把后面的变量转换成所要的类型了。如:(int) a;(float) b;第一个式子是把 a 转换成整型,如果原先有小数部分,则舍去。第二个式子是把 b 转换成浮点型,如果原先是整数,则在后面补0。每一个表达式的返回值都具有逻辑特性。如果返

28、回值为非0,则该表达式返回值为真,否则为假。这种逻辑特性可以用在程序流程控制语句中。有时表达式也不参加运算,如:if(a|b) 53?a+:b+;当 a 为真时, b 就不参加运算了,因为不管 b 如何,条件总是真。二、语句( 一) 、赋值语句其实这个问题,在讲赋值运算符的时候已经讲了一些了。Amount=1+2;Total=Counter/3+5;Area=Height*Width;也许你会发现,这些赋值语句很象代数方程,在某些情况下,我们的确可以这样理解,但有时它们 是不一样的。看下面:Num=Num+1;这显然不是一个等式。( 二) 、用逗号分隔开的声明语句C 语言可大多数语言一样,允许

29、用逗号分隔声明语句中的标识符列表,说明这些运算符是同一变量 类型。例如:float Area,Height,Width;但有些程序员喜欢把标识符写在不同的行上。如:float Area,Height,Width;这样写至少有一个好处,就是可以在每个标识符后边加上注释。在声明变量的时候,也可以直接给变量赋值,这叫做变量的初始化。 如: int a;a=3;等价于 :int a=3;我们也让某些变量初始化,某些不初始化,如:int a=3,b,c=5;在进行初始化时,初始化表达式可以是任意的( 对全局变量和静态变量有区别 ) ,由于逗号运算符是从左到右运算的,那么看看这样行不行?int a=3,b

30、=a,c=5;( 三 ) 、标准输入输出语句Turbo C 2.0 标准库提供了两个控制台格式化输入、输出函数scanf(); 和 printf(); 这两个函数可以在标准输入输出设备上以各种不同的格式读写数据。 scanf() 函数用来从标准输入设备 (键盘 )上读数据, printf() 函数用来向标准输出设备 (屏幕 )写数据。下面详细介绍这两个函数的用法。1. 标准输入语句scanf() 函数是格式化输入函数 , 它从标准输入设备 (键盘 ) 读取输入的信息。其调用格式为 : scanf("< 格式化字符串 >", < 地址表 >);格式化字

31、符串包括以下三类不同的字符 ;(1) . 空白字符 : 空白字符会使 scanf() 函数在读操作中略去输入中的一个或多个空白字符。(2) . 非空白字符 : 一个非空白字符会使 scanf() 函数在读入时剔除掉与这个非空白字符相同的字 符。(3) . 格式化说明符 :以"%" 开始 ,后跟一个或几个规定字符 ,用来确定输出内容格式。Turbo C 2.0 提供的输入格式化规定符如下 :符号作用%d十进制有符号整数%u十进制无符号整数%f浮点数%s字符串%c单个字符%p指针的值%x,%X无符号以十六进制表示的整数%o无符号以八进制表示的整数地址表是需要读入的所有变量的地址

32、 , 而不是变量本身,取地址符为 '&' 。各个变量的地址之间同 ","分开。例如:scanf("%d,%d",&i,&j);上例中的 scanf() 函数先读一个整型数 , 然后把接着输入的逗号剔除掉 , 最后读入另一个整型数。如 果"," 这一特定字符没有找到 ,scanf() 函数就终止。若参数之间的分隔符为空格 ,则参数之间必须输入一个或 多个空格。说明:(a) . 对于各个变量,类型说明符是什么,输入格式化说明符就应该用对应的类型。否则会出现 程序错误或输入数据和理想的不一样。(b)

33、. 对于字符串数组或字符串指针变量, 由于数组名和指针变量名本身就是地址, 因此使用scanf() 函数时 , 不需要在它们前面加上 "&" 操作符。char *p,str20;scanf("%s", p); scanf("%s", str);具体字符串,指针的知识以后再介绍。(c) . 可以在格式化字符串中的 "%" 各格式化规定符之间加入一个整数, 表示任何读操作中的最大位数。如上例中若规定只能输入 10 字符给字符串指针 p, 则第一条 scanf() 函数语句变为 : scanf("%10

34、s", p);程序运行时一旦输入字符个数大于 10, p 就不再继续读入。实际使用 scanf() 函数时存在一个问题 , 下面举例进行说明 :当使用多个 scanf() 函数连续给多个字符变量输入时 , 例如 :char c1, c2;scanf("%c", &c1);scanf("%c", &c2);运行该程序 ,输入一个字符 A 后回车 (要完成输入必须回车 ),在执行 scanf("%c",&c1) 时,给变量 c1 赋值"A",但回车符仍然留在缓冲区内,执行输入语句sca

35、nf("%c",&c2)时,变量c2输出的是一空行,如果输入 AB后回车,那么实际存入变量里的结果为cl为A, c2为Bo要解决以上问题 , 可以在输入函数前加入清除函数 fflush();( 这个函数的使用方法将在本节最后讲 述 ) o(d) . 当在格式说明符之间加入 '*' 时,表示跳过输入,例如: scanf("%3*d",&a);当输入12345的时候,前面三个字符跳过去不考虑,最终变量a的值为45。2.标准输出语句printf() 函数是格式化输出函数 ,一般用于向标准输出设备按规定格式输出信息。 在编写程序时

36、经 常会用到此函数。 printf() 函数的调用格式为 :printf("< 格式化字符串 >", < 参量表 >); 其中格式化字符串包括两部分内容 : 一部分是正常字符 , 这些字符将按原样输出 ;另一部分是格式化规定字符,以"%" 开始 ,后跟一个或几个规定字符,用来确定输出内容格式。参量表是需要输出的一系列参数 ,其个数必须与格式化字符串所说明的输出参数个数一样多 ,各参 数之间用 ","分开,且顺序一一对应 ,否则将会出现意想不到的错误。对于输出语句,还有两个格式化说明符符号作用%e指数形式的浮点数

37、%g自动选择合适的表示法说明:(1) .可以在"%"和字母之间插进数字表示最大场宽。例如: %3d 表示输出 3位整型数 ,不够 3位右对齐。%9.2f 表示输出场宽为 9的浮点数 ,其中小数位为 2,整数位为 6,小数点占一位 ,不够9 位右对齐。%8s 表示输出 8 个字符的字符串 ,不够 8 个字符右对齐如果字符串的长度、或整型数位数超过说明的场宽 ,将按其实际长度输出。但对浮点数 ,若 整数部分位数超过了说明的整数位宽度 ,将按实际整数位输出 ; 若小数部分位数超过了说明的小数位宽度 ,则 按说明的宽度以四舍五入输出。另外 ,若想在输出值前加一些 0, 就应在场宽项

38、前加个 0。例如: %04d 表示在输出一个小于 4 位的数值时 ,将在前面补 0使其总宽度为 4 位。 如果用浮点数表示字符或整型量的输出格式,小数点后的数字代表最大宽度 ,小数点前的数字代表最小宽度。例如: %6.9s 表示显示一个长度不小于 6且不大于 9的字符串。若大于 9,则第 9个字 符以后的内容将被删除。(2) . 可以在 "%" 和字母之间加小写字母 l, 表示输出的是长型数。例如 : %ld 表示输出 long 整数%lf 表示输出 double 浮点数(3) . 可以控制输出左对齐或右对齐,即在 "%" 和字母之间加入一个 "

39、;-" 号可说明输出为左对齐 , 否则为右对齐。例如: %-7d 表示输出 7 位整数左对齐%-10s 表示输出 10 个字符左对齐一些特殊规定字符 (可以参照前面说的转义字符 )字符作用n换行f清屏并换页r回车tTab 符xhh表示一个 ASCII 码用 16 进表示由本节所学的 printf() 函数, 并结合上一节学习的数据类型 , 看下面的语句 ,加深对 Turbo C 2.0 数据 类型的了解。char c; int a=1234;float f=3.141592653589;double x=0.12345678987654321;c='x41'print

40、f("a=%dn", a); printf("a=%6dn", a);printf("a=%06dn", a); printf("a=%2dn", a);printf("f=%fn", f);printf("f=6.4fn", f); printf("x=%lfn", x);printf("x=%18.16lfn",x);printf("c=%cn", c);printf("c=%xn", c);

41、? 4. 查阅如下一种资料:-(1)与某种语言(如java、VB等)的编译程序有关用 c 语言编 de 编译程序for 循环语句翻译 递归下降法 输出三地址码 /#define MAX 100#include<iostream.h>#include<stdio.h>#include<string.h>char strMAX;char ch;int turn;char strTokenMAX;int kind;int n=0;/ 存放 strtoken 元素的个数struct Word/ 结构体 存放单词int sort;char wordMAX;/ 存放 s

42、trtoken 的内容;/recordx=new Word;x 是其下标Word *record12;/ 放所有识别出来的单词,分别存放他们的编号以及字符串,/ 词法分析 /int buffer()/ 载入int i=0;cout<<" 输入程序,以 “ #作”为结束标志。 "<<endl;for(int n=0;n<=MAX;n+) for(;i<=MAX;i+)scanf("%c",&stri);/cin>>stri 不可用,用 C 语言读入字符。if(stri='#')brea

43、k;/ 如果尾数为识别码 #,则表示程序读完 ,跳出循环 . break;return(i);bool IsLetter(char ch)/ 判断是否是字母if(ch>=65&&ch<=90|ch>=97&&ch<=122) return(true);elsereturn(false);bool IsDigit(char ch)/ 判断是否是数字if(ch>=48&&ch<=57) return(true);else return(false);char GetChar(int i)/ 读取字符char ch;

44、ch=stri;return(ch);char GetBC(char ch)/ 判断是不是空格或者换行,如果是,直接读取下一个字符直道不再空 白为止if(ch=32|ch=10)turn+;ch=GetChar(turn);ch=GetBC(ch);/ 递归实现return(ch);elsereturn(ch);void Concat()/ 连接,即为 strtoken 赋值strTokenn=ch;n+;int Reserve()/ 以单词为单位查找保留字,是则返回编码,不是则返回0,用来区分标志符和保留字 if(strcmp(strToken," DIM0")=0)/

45、调用 strcmp 函数实现 , return(1);else if(strcmp(strToken,"for0")=0)return(2);else if(strcmp(strToken,"step0")=0) return(3);else if(strcmp(strToken,"until0")=0) return(4);else if(strcmp(strToken,"do0")=0) return(5);else return(6);void clear()n=0;/* 语法递归分析 */int A(int

46、 * c,int & q)if(cq+=3)if(cq=7) q+;return 1;else cout<<"step 右部出错 "<<endl;return 0;else cout<<"error 'step'"<<endl;return 0;int B(int * b,int & o) if(bo+=4)if(bo=7) o+;return 1;else cout<<"until 右部出错 "<<endl;return 0;el

47、se cout<<"error 'until'"<<endl;return 0; int S2(int * d,int & h)if(dh+=6)if(dh+=8) if(dh=6|dh=7) h+; return 1; else cout<<" 赋值语句右部出错 "<<endl;return 0;else cout<<" 赋值语句缺少赋值运算符 "<<endl;return 0;else cout<<" 赋值语句左部

48、出错 "<<endl;return 0;int S1(int * m,int & n) if(S2(m,n) if(A(m,n)if(B(m,n) return 1; else return 0;else return 0;else return 0;int S(int *a,int & z)if (az+=2)if (S1(a,z) if(az+=5)if(S2(a,z) cout<<"succeed!"<<endl;return 1;else return 0;else cout<<"e

49、rror 'do'"<<endl; return 0;else return 0;else cout<<"error 'for'"<<endl; return 0;void main()cout<<"*产生式 *"<<endl;/ for step until do i j =cout<<" S ->for S1 do S2"<<endl; / 编号 2 3 4 5 6 7 8 cout<<&

50、quot; S1 ->S2AB"<<endl;cout<<" S2 ->i=j"<<endl;cout<<" A ->stepj"<<endl;cout<<" B ->untilj"<<endl; int num;turn=0;num=buffer()-1;int x=0;/ 计识别的单词的个数for(;turn<=num;turn+)/ 总循环 ,ch 存放刚读入的字符, strtoken 存放已识别的标志付或

51、保留 字, turn 是数组 str 的下标ch=GetChar(turn);ch=GetBC(ch);if(IsLetter(ch) while(IsLetter(ch)&&turn<=num|IsDigit(ch)&&turn<=num)Concat();ch=GetChar(+turn);strTokenn='0'ch=NULL;/ 此 ch 不是标志符中的符号turn=turn-1;kind=Reserve();recordx=new Word; recordx->sort=kind;/12345 或 6/cout<

52、;<kind; / 测试cout<<"("for(int i=0;i<n;i+)recordx->wordi=strTokeni;cout<<recordx->wordi;/ 输出识别的标志符或保留字 cout<<","<<kind<<")"<<endl; recordx->wordi='0' clear();x+;else if(IsDigit(ch)while(IsDigit(ch)&&turn&l

53、t;=num)Concat();ch=GetChar(+turn);ch=NULL; turn=turn-1;kind=7;/ recordx=new Word;recordx->sort=kind;/cout<<"("for(int i=0;i<n;i+) recordx->wordi=strTokeni; cout<<recordx->wordi; cout<<","<<kind<<")"<<endl; recordx->word

54、i='0'clear();x+;else if(ch='=')kind=8;/recordx=new Word;recordx->word0='='recordx+->sort=kind; cout<<"(=,"<<kind<<")"<<endl;elsecout<<"error input!"<<endl;/* 语法分析 */int y;/*for(y=0;y<x;y+)cout<<r

55、ecordy->sort<<" "/ 打印单词的编号 。cout<<endl;*/int anaMAX;/ 存放词法分析得到的单词序列的编号的序列 int m;for(m=0;m<x;m+)anam=recordm->sort;/ 将 sort 作为数组保存起来/ 语法分析 /int j=0;/ 制导翻译 / if(!S(ana,j) cout<<" 语法出错 !"<<endl;else cout<<" 三地址码如下: "<<endl; cout

56、<<"100 "int i=0; while(record1->wordi!='0') cout<<record1->wordi+;cout<<record2->word0; i=0;while(record3->wordi!='0') cout<<record3->wordi+;cout<<endl; cout<<"101 goto 103"<<endl; cout<<"102 &quo

57、t;i=0;while(record1->wordi!='0') cout<<record1->wordi+;cout<<":=" i=0;while(record1->wordi!='0') cout<<record1->wordi+;cout<<"+"i=0;while(record5->wordi!='0') cout<<record5->wordi+;cout<<endl; cout<&

58、lt;"103 if "i=0;while(record1->wordi!='0') cout<<record1->wordi+;cout<<"<"i=0;while(record7->wordi!='0') cout<<record7->wordi+;cout<<" goto 105"<<endl; cout<<"104 goto 107"<<endl; cout<

59、;<"105 "i=0;while(record9->wordi!='0') cout<<record9->wordi+;cout<<":="i=0;while(record11->wordi!='0') cout<<record11->wordi+;cout<<endl; cout<<"106 goto 102"<<endl;cout<<"107 end"<<

60、;endl;-(2)与编译程序的理论有关-(3)与某种高级语言的发展有关C 语言编译过程总结详解C 语言的编译链接过程要把我们编写的一个 c 程序(源代码) 转换成可以在硬件上运行 的程序(可执行代码) ,需要进行编译和链接。编译就是把文本形式源代码翻译为机器语言 形式的目标文件的过程。 链接是把目标文件、 操作系统的启动代码和用到的库文件进行组织 形成最终生成可执行代码的过程。过程图解如下:I4 莊接器 *从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程。编译过程编译过程又可以分成两个阶段:编译和会汇编。编译编译是读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功 能等效的汇编代码,源文件的编译过程包含两个主要阶段:第一个阶段是预处

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论