编译原理复习总结

关键词:

编译原理复习总结(精选6篇)

篇1:编译原理复习总结

一、简答题

1.什么是编译程序?

答:编译程序是一种将高级语言程序(源程序)翻译成低级语言(目标程序)的程序 。

将高级程序设计语言程序翻译成逻辑上等价的低级语言(汇编语言,机器语言)程序的翻译程序。

2.请写出文法的形式定义?

答:一个文法G抽象地表示为四元组 G=(Vn,Vt,P,S)

– 其中Vn表示非终结符号

– Vt表示终结符号,Vn∪Vt=V(字母表),Vn∩Vt=φ

– S是开始符号,

– P是产生式,形如:α→β(α∈V+且至少含有一个非终结符号,β∈V*)

3.语法分析阶段的功能是什么?

答:在词法分析的基础上,根据语言的语法规则,将单词符号串分解成各类语法短语(例:

程序、语句、表达式)。确定整个输入串是否构成语法上正确的程序。

4.局部优化有哪些常用的技术?

答:优化技术1—删除公共子表达式

优化技术2—复写传播

优化技术3—删除无用代码

优化技术4—对程序进行代数恒等变换(降低运算强度)

优化技术5—代码外提

优化技术6—强度削弱

优化技术7—删除归纳变量

优化技术简介——对程序进行代数恒等变换(代数简化)

优化技术简介——对程序进行代数恒等变换(合并已知量)

5.编译过程分哪几个阶段?

答:逻辑上分五个阶段:词法分析、语法分析、语义分析与中间代码生成、代码优化、目

标代码生成。每个阶段把源程序从一种表示变换成另一种表示。

6. 什么是文法?

答:文法是描述语言的语法结构的形式规则。是一种工具,它可用于严格定义句子的结构;

用有穷的规则刻划无穷的集合;文法是被用来精确而无歧义地描述语言的句子的构成方式;文法描述语言的时候不考虑语言的含义。

7. 语义分析阶段的功能是什么?

答:对语法分析所识别出的各类语法范畴分析其含义,进行初步的翻译(翻译成中间代码);

并对静态语义进行审查。

8.代码优化须遵循哪些原则?

答:等价原则:不改变运行结果

有效原则:优化后时间更短,占用空间更少

合算原则:应用较低的代价取得较好的优化效果

9.词法分析阶段的功能是什么?

答:

逐个读入源程序字符并按照构词规则切分成一系列单词

任务:读入源程序,输出单词符号

— 滤掉空格,跳过注释、换行符

— 追踪换行标志,指出源程序出错的行列位置

— 宏展开,……

10.什么是符号表?

答:符号表在编译程序工作的过程中需要不断收集、记录和使用源程序中一些语法符号

的类型和特征等相关信息。这些信息一般以表格形式存储于系统中。如常数表、变量名表、数组名表、过程名表、标号表等等,统称为符号表。对于符号表组织、构造和管理方法的好坏会直接影响编译系统的运行效率。

11.什么是属性文法?

答:是在上下文无关文法的基础上,为每个文法符号(含终结符和非终结符)配备若干个属

性值,对文法的每个产生式都配备了一组属性计算规则(称为语义规则)。在语法分析过程中,完成语义规则所描述的动作,从而实现语义处理。

12.什么是基本块

答:是指程序中一顺序执行的语句序列,其中只有一个入口语句和一个出口语句,入口

是其第一个语句,出口是其最后一个语句。

13.代码优化阶段的功能是什么?

答:对已产生的中间代码进行加工变换,使生成的目标代码更为高效(时间和空间)。

14.文法分哪几类?

答:文法有四种:设有G=(Vn,Vt,P,S),不同类型的文法只是对产生式的要求不同:

0型文法(短文文法): G的每个产生式αβ满足:α∈V+且α中至少含有一个非终结符,β∈V*

1型文法(上下文有关文法):如果G的每个产生式αβ均满足|β|>=|α|,仅当Sε除外,但S不得出现在任何产生式的右部

2型文法(上下文无关文法):G的每个产生式为Aβ, A是一非终结符,β∈V*

3型文法(正规文法):G的每个产生式的形式都是:AαB或Aα,其中A,B是非终结符,α是终结符串。(右线性文法)。

15.循环优化常用的技术有哪些?

答:代码外提;强度削弱;删除归纳变量。

16.什么是算符优先文法?

答:算符文法G的任何终结符a,b之间要么没有优先关系,若有优先关系,

至多有

中的一种成立,则G为一算符优先文法。

二、计算题

(一)推导、最左推导、最右推导和语法树,复习表达式文法及相关例题。

1. 表达式的推导

例: G = ({E}, {i, +, *, (, ) } , P , E)

P: E E+E | E*E | (E) | i

答:表达式(i)和(i+i)*i的推导:

E (E) (i)

E E*E (E)*E (E + E)*E (i + E)*E (i + i)*E (i + i)*i

E E*E E*i (E)* i (E + E)*i (E+ i)*i (i + i)*i

(i+i)*i的最左推导过程:

E E*E (E)*E (E + E)*E (i + E)*E (i + i)*E (i + i)*i

(i+i)*i的最右推导过程:

E E*E E*i (E + E)*i (E+ i)*i (i + i)*i

2.语法树

例:对文法G = ({E}, {i, +, *, (, ) } , P , E)

P: E E + E | E * E | ( E ) | i

答: 句子(i+i)*i 的语法树:

例: G = ({E}, {i, +, *, (, ) } , P , E)

P: E E + E | E * E | ( E ) | i

答:句子 ( i * i + i)的语法树:

(1) E (E) (E + E) (E * E + E) (i * E + E) (i *i + i)

(二)给定语言求文法

(三)逆波兰式

篇2:编译原理复习总结

机器语言: 由0、1代码构成,不需翻译就可直接执行其程序。

汇编语言: 机器指令助记符(伪代码)形式,汇编后才可执行其程序。

高级程序设计语言: 类自然语言和数学公式形式

(2) 基本术语

源程序(Source Program):用源语言写的程序。源语言可以是汇编语言,也可以是高级程

序设计语言。

目标程序(Target Program) :也称为“结果程序”,是源程序经翻译程序加工以后所生成

的程序。目标程序可以用机器语言表示,也可以用汇编语言或其它中间语言表示。

翻译程序(Translating Program):是指把一个源程序翻译成逻辑上等价的目标程序的程序。

源程序为其输入,目标程序为其输出。

汇编程序(Assembler):是指把一个汇编语言写的源程序转换成等价的机器语言表示的目

标程序的翻译程序。

编译程序(Compiler):若源程序是用高级程序设计语言所写,经翻译程序加工生成目标程

序,则该翻译程序就称为“编译程序”,也可称为编译器。

解释程序:是高级语言翻译程序的一种,他将源语言书写的源程序作为输入,解释一句

后就提交计算机执行一句,并不形成目标程序,就像外语翻译中的“口译”一样,不产生全文的翻译文本。

运行系统(Running System):目标程序执行时,需要有一些子程序(如一些连接装配程序

及一些连接库等)配合进行工作,由这些子程序组成的一个子程序库称为运行系统。 编译系统(Compiling System):编译程序和运行系统合称编译系统。

(3) 程序的翻译

除机器语言程序外,用其它语言书写的程序都必须经过翻译才能被计算机识别。这一过

程由翻译程序来完成。

编译方式是一种分阶段进行的方式,包括翻译和运行两部分。

前一阶段:翻译

后一阶段:运行,由运行系统配合完成。

(4) 过程

1、词法分析阶段

这个阶段的任务是从左到右一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号TOKEN)。

某源程序片断如下:

begin var sum, first, count: real; sum:=first+count*10 end.

保留字 begin var real end

标识符 sumfirstcountsumfirstcount

界符 .

逗号,逗号,冒号:分号;加号+乘号*赋值号 :=整数10 10

2、语法分析阶段

是编译过程的第二个阶段。语法分析的任务是在词法分析的基础上将单词序列分解成各类语法短语,如“程序”,“语句”,“表达式”等等。一般这种语法短语,也称语法单位,或语法成分,或语法范畴。

语法分析所依据的是语言的语法规则,即描述程序结构的规则。通过语法分析确定整个输入串是否构成一个语法上正确的程序。

3、语义分析阶段

依据语言的语义规则,对语法分析得到的语法结构分析其含义以及应进行的运算,审查源程序中有无语义错误,为代码生成阶段收集类型信息。

4、中间代码生成

在进行了上述的语法分析和语义分析阶段的工作之后,有的编译程序将源程序转变成一种内部表示形式,这种内部表示形式叫做中间代码。

所谓“中间代码”是一种结构简单,含义明确的记号系统,这种记号系统可以设计为多种多样的形式。

重要的设计原则:一是容易生成;二是容易将它翻译成目标代码。

5、代码优化

任务:对前阶段产生的中间代码系列进行变换或改造。目的是使生成的目标代码更高效,即省时间省空间。例如上例四个四元式可优化为下面两个四元式。

6、目标代码生成

任务:将中间代码变换成特定机器上的绝对指令代码或可重定位的指令代码或汇编指令代码。它的工作与硬件系统结构和指令含义有关。

7、表格管理

编译过程中源程序的各种信息被保留在种种不同的表格里,编译各阶段的工作都涉及到构造、查找或更新有关的表格,因此需要有表格管理的工作;

8、出错处理

如果编译过程中发现源程序有错误,编译程度应报告错误的性质和错误发生的地点,并且将错误所造成的影响限制在尽可能小的范围内,使得源程序的其余部分能继续被编译下去,有些编译程序还能自动校正错误,这些工作称之为出错处理。

(5) 前端与后端

参考上面的图,目的是为了在多种源语言和多种目标语言的开发过程中,可以灵活搭配组合,消除重复开发的工作量,提高编译系统的开发效率。

(6) 遍

所谓遍,是对源程序或源程序的中间形式从头到尾扫视并完成规定任务的过程。

每一遍扫视可完成一个阶段或多个阶段的功能。

一遍的编译程序:以语法分析程序为核心 。

多遍扫描的优点:

可以减少内存容量的需求,分遍后,以遍为单位分别调用编译的各个程序,各遍程序可以相互覆盖。

可使各遍的编译程序相互独立,结构清晰。

能够进行充分优化,产生高质量的目标程序。

可将编译程序分为前端和后端,有利于编译程序的移植。

多遍扫描的缺点

每遍都要读符号、送符号,增加了许多重复性的工作,降低编译效率。

(7) 程序设计语言范型(从支持的计算模式)

1. 强制(命令)式语言:是面向动作的,即一个计算过程看做是一系列动作,其动作是命令驱动,以语言形式表示。

也称过程式语言,如C,FORTRAN等;

2. 函数式语言:注重程序表示的功能

也称应用式语言,如ML和LISP等;

3. 基于规则的语言:检查一定的使能条件,满足时执行动作

也称逻辑程序设计语言,如PROLOG。

4. 面向对象语言:提供抽象数据类型,支持封装性、继承性和多态性。

如C++和Java等。

(1) 符号和符号串

1、字母表:元素的有穷非空集合。

2、符号串:由字母表中的符号组成的任何有穷序列。

3、符号串的头尾,固有头和固有尾:如果z=xy是一符号串,那么x是z的头,y是z

的尾,如果x是非空的,那么y是固有尾;同样如果y非空,那么x是固有头。 如:设z=abc,那么z的头是,a, ab, abc, 除abc外,其它都是固有头;z的尾是, c, bc, abc, z的固有尾是, c, bc。

4、符号串的运算

(1)符号串的连接:设x和y是符号串,x和y的连接xy是把y的符号写在x的符号后得的符号串。

如:x=ST, y=abu, 则xy=STabu显然有x=x=x。

(2)符号串的方幂:设x是符号串,把x自身连接n次得x的几次方幂xn。

如:设x=ab则x0=x1=abx2=ababx3=ababab

(3)符号串集合的乘积:设A和B为符号串集合,则A和B的乘积定义为AB={xy|xA且yB}

如:a={a, b}, B={00, 11} 则AB={a00, a11, b00, b11} 显然:{}A=A{}=A

(4)符号串集合的方幂:设A为符号串集,则A的n次方幂An定义为:An=AA……A=AAn-1=An-1A

(5)符号串集合的正闭包A+:A+=A1 U A2 U … U An U …

(6)符号串集合的闭包A*:A*=A0 U A+ = {} U A+

如:设有正字母表={0,1} 则*=0 U 1 U 2 U … U n U …={, 0, 1, 00,01, 10, 11, 000, 001,……}

(2) 文法

文法G定义为四元组(VN ,VT,P,S)其中:

(1)VN 为非终结符号集

非终结符号表示一个语言短语(或语法成分、语法单位)。 如 程序、语句、表达式等。一般用大写字母或用〈 〉括起表示非终结符号。

(2)VT 为终结符号集

终结符号:组成语言的基本符号。是文法中不属于非终结符号集合的符号。一般用小写字母或不带〈 〉的符号表示。如程序设计语言的.单词符号。

设V=VN U VT,称V为文法G的字母表。

(3)P 为产生式(也称规则)的集合。

产生式的形式:→或∷=,其中∈V+,∈V*

(4)S 称作识别符号或开始符号,是一个非终结符号。

一般表示此文法定义的最大语法短语,至少要在一条产生式 中作为左部出现。 句型、句子的定义

设G[S]是一文法,如果符号串x是从识别符号推导出来的,即有S*x, 则称x是文法G[S]的句型。

若x仅由终结符号组成,即S*x, xV T ,则称x为G[S]的句子。

句型:在一棵树生长过程的任何时刻,所有那些端末结点自左至右的排列,就是一个句型。

语言的定义:文法G产生的语言记为L(G),它是文法G产生的全部句子的集合。 文法等价定义:若L(G1)=L(G2)则称文法G1和G2是等价的。

(3) 文法的类型 N.Chomsky

0型文法:定义0型语言,对应Turing机;

1型文法:定义1型语言,对应线性限界自动机;箭头后面的要比前面的长或相等 2型文法:定义2型语言,对应非确定下推自动机;箭头前面的是非终结符,后面是串 3型文法:定义3型语言,对应有限自动机。非终结符可以推出一个终结符或一个终结符和一个非终结符

最右推导也称为规范推导,所得句型称为规范句型。

如果一个文法存在某个句型对应两棵不同的语法树,则说这个文法是二义的。或者说,若一个文法中存在某个句型,它有两个不同的最左(最右)推导,则这个文法是二义的。

上下文无关文法是否具有二义性是不可判定的。

但有些特殊的2型文法[例如LL(1)、LR(0)、LR(1)等文法]是无二义性的。 一个文法兼有左递归和右递归是导致二义性的常见原因。

排除文法二义性通常有两种方法:

(1)在语义上加些限制

(2)重新构造一个无二义性的文法

(4) 句型的分析

句型的分析:就是识别一个符号串是否为某文法的句型。是某个推导的构造过程。 分析方法分两大类:自上而下分析法和自下而上分析法推导与归约,最右推导是规范推导,逆过程为规范规约

若S*A+(由A+得)则称是句型相对于非终结符A的短语。

若S*A(由A→得)则称是句型相对于A→的直接短语(也称简单短语)。 一个句型的最左直接短语称为该句型的句柄。

一棵子树(至少要有父子两代)的所有端末结点自左至右排列起来形成相对于子树根的短语。若子树只有父子两代,则得到直接短语。

(5) 有关文法

(1)有害规则 文法中含形如U→U的产生式。

它对描述语言没有必要,且会引起文法的二义性。

(2)多余规则 文法中任何一个句子的推导都用不到的规则。

(3)无用规则 文法中含形如U→V的产生式,即单产生式。

为保证文法G的任一非终结符A在句子推导中出现,必须满足如下两个条件:

(1)A必须在某句型中出现,A。

(2) 必须能够从A推导出终结符号串t。

有关文法的化简和改造,包括以下几项工作:

(1)无用符号和无用产生式的删除。

(2) -产生式的消除。

(3)单产生式的消除。

(4)左递归的消除。

(1) 词法分析输出

单词符号(TOKEN) 是一个程序设计语言的基本语法符号。程序设计语言的单词符号一般可分成下列5种:

1.基本字,也称关键字,如PASCAL语言中的begin,end,if,while和var等。

2.标识符,用来表示各种名字,如常量名、变量名和过程名等。

3.常数,各种类型的常数,如25,3.1415,TRUE和“ABC”等。

4.运算符,如+,*,<= 等。

5.界符,如逗点,分号,括号等。

词法分析程序所输出的单词符号常常采用下二元式表示:(单词种别,单词自身的值) 可用整数码或助记符等表示。

(2) 单词的描述工具

程序设计语言中的单词(TOKEN)是基本语法符号。单词符号的语法可以用有效的工具加以描述。

正规式和它所表示的正规集的递归定义如下。设字母表为∑,辅助字母表∑ ={ |, ·, *, (, ) }

定义(正规式和它所表示的正规集):

设字母表为Σ,辅助字母表Σ`={Φ,ε,|,·,*,(, }。

② ε和Φ都是Σ上的正规式,它们所表示的正规集分别为{ε}和{ };

② 任何a∈Σ,a是Σ上的一个正规式,它所表示的正规集为{a};

③ 假定e1和e2都是Σ上的正规式,它们所表示的正规集分别为L(e1)和L(e2),那么,(e1), e1|e2, e1·e2, e1*也都是正规式,它们所表示的正规集分别为L(e1), L(e1)∪L(e2), L(e1)L(e2)和(L(e1))*。

④ 仅由有限次使用上述三步骤而定义的表达式才是Σ上的正规式,仅由这些正规式所表示的字集才是Σ上的正规集。

(3) 有穷自动机

有穷自动机(也称有限自动机)作为一种识别装置,它能准确地识别正规集,即识别正规文法所定义的语言和正规式所表示的集合,引入有穷自动机这个理论,正是为词法分析程

篇3:“编译原理”课程的教学探讨

1 当前教学中存在的问题

由于这门课程理论性强,内容丰富抽象,具有严密的逻辑性,使用到其它课程的知识较多,因此成为计算机专业诸课程中既难教又难学的一门课程。目前该课程在教学过程中主要存在以下问题:

1)课程内容抽象难理解

编译程序不同于一般的应用程序,是一个十分庞大和复杂的系统软件,它所包含的理论知识较多,抽象度也较高,要求教师在有限的课时内将课程内容讲解清楚,并使学生接受理解是有难度的。

2)基于面向过程语言的描述模型

目前,这门课程中的算法和模型描述是用PASCAL语言或者C语言等面向过程语言。虽然个别教材加入了少量关于面向对象语言编译技术的内容,那也是稍加点缀而已,用途较小。然而,面向对象语言已经成了高校计算机教学的主流语言,社会上大量使用的也是面向对象语言,而我们的编译原理教学仍然沿袭旧的面向过程语言,这种现象严重脱离了计算机技术发展和社会实际需要。

3)课程实验设计不合理

目前,大多数高校在“编译原理”课程的实验内容上基本上都是要求学生能上机实现一个小型模型语言的完整编译程序,或者是分四个单独的实验(词法一个实验,语法三个实验),它们的目的是让学生加深理解一些编译理论与算法,这对于一部分学生来说是不能完成的任务,也不能激发他们的兴趣(他们认为学习编译原理就是为了设计编译器),造成很大部分学生在动手之前就早早放弃了努力,也就不能达到预期的实验效果。

4)教学手段陈旧

目前,“编译原理”课程主要以理论教学为主,课时主要用于形式语言理论与各种语法分析算法、语义分析技术的讲授上,缺乏对实际编译器的分析。同时,在讲解的时候一般没有辅之以其它形象生动的教学手段,对学生是采用“灌输式”的教学模式,而没有采用“启发式”、“讨论式”等多种教学模式,因此学生觉得授课内容枯燥乏味,激不起他们学习的兴趣。

5)教学大纲统一

目前,每个高校计算机相关专业包括计算机科学与技术、软件工程、网络工程等,学生也存在不同的层次包括统招的“一本”、“二本”学生,以及“专升本”学生等。不同专业有不同的培养目标,不同的生源造成学生知识背景和自身素质也有差异。在这种情况下,在“编译原理”课程教学过程中实行统一的教学大纲显然不合适。

6)学生学习兴趣不浓

目前,学生普遍认为学习编译原理就是为了设计编译器,而大部分学生今后从事编译器设计工作的可能性较小,因此觉得没必要学。另外,目前面向对象的程序设计语言已经成为了主流,认为课程主要讲授面向过程的程序设计语言的处理已经落伍,因此失去了学习兴趣。

形成以上这些问题的原因既有主观的也有客观的,这些问题在我校的编译原理教学过程中也都不同程度地存在。为此,对“编译原理”课程的教学内容和教学方法进行探讨是十分必要的、有意义的。

2 需要解决的问题

1)课程内容的调整

“编译原理”课程内容丰富抽象,理论性和逻辑性很强,所以很多学生在学习时普遍感到枯燥、乏味,难理解,激不起学习兴趣。为此,需要对课程内容合理安排以便收到较好的教学效果。

a)抓住重点,分清主次

由于课程内容涉及较多,学生往往抓不住重点,分不清主次,结果导致劳而无功。为此,需要根据专业的不同,学生层次的不同,在不影响对编译系统理解的情况下,合理安排授课内容,切不可造成“统一重点的教学”、“统一层次的教学”、“统一大纲的教学”现象。

b)范例式编译器的剖析

为了帮助学生对编译思想和方法的理解,应在教学过程中增加一部分内容,即对一个范例式编译器进行剖析。该范例式编译器应采用教学中涉及到的典型编译思想与方法。学生在教师的指导下对实际编译器代码进行阅读,将使学生对抽象的编译理论与算法有更深刻的认识,从而达到较好的教学效果。

c)面向对象式语言的描述模型

当前,面向对象式语言已成为主流,而目前课程中的内容却是围绕面向过程式语言展开的。为此,需要在教学过程中增加一部分内容,即选择某个对象式语言来描述典型的编译算法。但就目前来看,以面向对象语言作为源语言来重新组织编译原理的教学内容并不合适。在教学过程中应向学生指明这一点,使之有个正确的认识。

2)实践环节的设计

“编译原理”也是一门实践性较强的课程,只有通过实践环节才能让学生加深对抽象理论的理解,培养其分析、设计软件的能力。为此,必须重视实践环节的教学,精心设计实验方案,合理组织实践训练(对于不同专业培养目标、不同类别学生素质差异,需设计不同的实验方案)。

a)设计合适的实验内容

目前,大多数高校在“编译原理”课程的实验内容上基本上都是要求学生能上机实现一个小型模型语言的完整编译程序,或者是分四个单独的实验(词法一个实验,语法三个实验)。这样的实验内容存在一个缺陷就是不能充分激发学生的学习兴趣,因为他们认为学习编译就是为设计编译器,而大部分学生以后从事这方面工作的可能性较小。为此,我们需要设计一个能运用编译理论和技术去解决实际问题的实验。例如,可以给定一个受限汉语的子集,引导学生用文法去描述它,然后把它应用到一个简单的自然语言查询的程序设计中去。

b)合理安排实验课时间

实验时间安排要具有灵活性,不要一周或两周一次实验,这样可能和授课的理论内容脱节。可以分别在每个实验的相关内容讲解完后安排这四个实验,并要求学生记录下每次实验的输入和输出形式,实现理论与实践的结合。

c)改进实验课教学方法

为了让实验能达到预期的效果,需要做以下工作:一是老师在实验前要将准备好的实验资料发放给学生,让学生利用业余时间分析、设计实验内容;二是老师指导学生一起讨论实验所涉及的原理、程序模块的功能和部分变量的用途;三是学生在理解的前提下,开始进行实验,老师随时进行监督指导。最后,在实验完成后,老师一定要检查学生的完成情况,并给予记录,学生则要记录下所有的实验结果。

3)教学方法的改进

“编译原理”课程抽象性和理论性较高,学生普遍感到内容难理解,更不能运用编译技术所涉及到的思想和方法去解决其他专业问题,学起来枯燥、无味。为此,需要灵活运用多种教学方法,以激发他们的学习兴趣和积极性,培养其分析、解决实际问题的能力。

a)多媒体辅助教学

“编译原理”课程涉及到形式语言与自动机理论,主要包括一些经典的语法、语义分析算法。这些理论和算法抽象复杂,不易理解。为此,需要借助多种辅助教学手段,如CAI课件、CAI教学系统和教学网站等。这样可以把抽象的理论形象化,把知识讲解化静为动,寓教于乐,培养和激发学生的学习兴趣。

b)师生互动式教学

教学是由“教”与“学”两方面构成的,师生互动才能“教”、“学”相长,提高教学效果。在课堂上,应采用“启发式”、“讨论式”、“提问式”等多种教学模式,以发散学生的思维,激发他们的思考能力;在课后,应通过教学网站发放调查问卷等形式及时获取学生对教学活动的意见与建议,学生也可以通过BBS系统进行交流,以便及时发现问题进而改进教学方法。还可以指定课后的时间组织小型的师生面对面交流,一方面是答疑,一方面也可以就编译领域的一些新问题、新动向进行研讨,进一步激发学生的学习积极性。

4)教材建设和CAI课件制作

目前为止,国内外已有不少关于“编译原理”的经典教材,因而我们暂时不打算重新编写授课教材。但从以上分析可知,目前的课程实验内容设计却各不相同,没有合适的实验教材,因此有必要根据我院特色来组织编写“编译原理”课程实验教材。同时,我们也将依据我院教学实际,重新合理组织教学内容,图文并茂,制作精良的CAI课件,以减少板书的时间,提高授课效率。

5)教学网站的建设

开发“编译原理”网络教学平台,构建良好的网络辅助教学环境,实现学习、答疑、作业和考试等各个教学环节的网络化,教师和学生可以很方便的利用该平台完成几乎所有教学活动,本课程教学网站主要将分四大模块:

a)基本信息

包括课程负责人、课程主讲人、教学队伍、自我评价、课程建设规划、课程教学录像等相关信息。

b)课程建设

课程概况:课程简介、课程大纲、教学日历、教材和参考文献。

教学资源:电子教材、电子课件(PPT)、电子课件、参考教案、例题源代码、习题答案、考试样卷及参考答案。

实验教学:实验教学大纲、实验内容、实验指导。

在线考试:为学生提供了模拟笔试、模拟机试和在线考试,实现了自动组卷和评分。

作业练习:提供了各章的练习题、单元测试题。

作业提交:主要提供了作业的发布与提交等功能。

c)BBS论坛

提供学生、老师相互之间的交流平台,以便及时发现问题进而改进教学方法和内容。

d)问卷调查

在课后,发放调查问卷及时获取学生对教学活动的意见与建议。

6)CAI教学系统的研制

CAI教学系统是辅助教学的一重要手段,通过它可以帮助学生加深对编译思想和方法的理解与运用,进而培养和激发他们的学习兴趣。我们将考虑按照图1所示的系统结构图来设计“编译原理”课程的CAI教学系统。

基本知识播放:提供每章的基本知识点的查询和一些基本知识点的程序实现等。

编译过程演示:这是CAI教学系统主要模块,提供了词法、语法、语义分析算法的动态演示,而且还要动态演示中间代码生成、中间代码优化和目标代码生成的执行过程。

自我测试:提供题库,让学生测试自己对所学知识的掌握情况。

系统维护:随着编译技术的发展,知识的不断更新,会出现一些新的概念和算法,因此系统也要随时增加新的知识点。另外,随着系统的运行,可能会发现一些不正确的地方,也需要及时修改。

3 结束语

“编译原理”是计算机专业中一门重要的课程,通过本课程的学习,可以使学生获得设计、分析和移植编译程序方面的初步能力。结合实际教学过程,本文分析了“编译原理”课程教学中所遇到的六个问题,探讨了需要解决的五个问题,以期望在今后的教学中能达到较好的效果。

摘要:“编译原理”是计算机专业中一门非常有用的核心课程,针对“编译原理”课程教学过程存在的问题,结合实际的教学情况,对“编译原理”课程的教学内容和方法进行了探讨,提出了解决思路和方法。

关键词:编译原理,教学内容,教学方法

参考文献

[1]陈火旺,刘春林,谭庆平等.程序设计语言编译原理[M].北京:国防工业出版社,2009.

[2]刘磊,郭德贵“.编译原理”课程建设研究[J].计算机教育,2006(6):8-10.

篇4:《编译原理》教学方法初探

关键词:编译原理;教学方法

TP314-4

编译原理是计算机相关专业的核心课程,是一门公认比较难学的课程。通过学习编译知识,有助于学生从宏观上把握编程语言;编译技术涉及到计算机的系统结构、指令集结构以及相关的操作系统,掌握编译技术有助于更进一步地理解计算机系统;从软件工程的角度来看,编译器是一个很好的系统软件,它所涉及的算法和技术可直接复用于软件开发的实践[1]。

一、教学现状

编译原理课程的理论性和实践性较强,在该课程的学习过程中涉及到大量抽象的理论知识,而实践动手环节的教学效果受制于对理论的理解程度。教学过程中,存在的问题有以下几个。

首先,学生对编译原理课程不够重视,缺乏学习动力。大多数的同学认为,编译原理课程的学习,与今后的就业没有多大的联系。而且就目前计算机领域的发展现状而言,并不需要重复编写构造编译器;课程本身的难度较大,有同学反应,课堂上老师讲授的知识可以理解,但是下课后往往想不起来;从而导致学生在学生过程中,学习积极性不够,动力不足。

其次,编译原理课程综合性较强,难度较大。涉及到的先修课程包括离散数学、程序设计基础、算法与数据结构、汇编语言、操作系统等,学生对这些先修课的基础知识的掌握程度参差不齐,甚至于有些学生根本没有掌握必要的基础知识;另外,该课程涉及的理论知识抽象,难以理解,如自动机理论等,涉及到的算法复杂,不容易实现,如语法分析阶段的自下而上的分析算法等,对于编译程序这个系统软件,各模块之间接口复杂,学生从整体上理解编译程序也存在一定困难。

第三,实践效果不理想。该课程的实践涉及许多其他相关课程的知识,因此,需要学生有较高的综合运用知识的能力,对于大多数同学,实践具有较大难度,对于基础知识较差的同学来说,很难达到课程的要求。

二、教学思路

(一)明确课程学习目标及其重要性

编译原理课程理论性较强,在讲授过程中,理论性的知识是授课的重点和难点。因此,整个上课过程中要让同学们明确学习该课程的意义,以及为什么要开设该课程,即学习编译原理的重要性,在整个课程的讲授过程中,可以多采用启发式教学方法,以期提高学生的学习兴趣。编译原理课程能够提高学生计算机思维能力。所谓计算机思维能力指的是具有抽象化与形式化思维的能力,编译器在设计过程中就运用了计算机思维的思想与方法,对学生进行计算机思维能力培养将有助于其更好地把握编译原理的目标[2]。另外,编译技术应用广泛,如软件系统安全、现有程序理解和软件工程的逆向工程等方面。

(二)精選教学内容

我们可以借鉴国内外知名大学在编译原理教学方面积累的宝贵的经验,如教学内容、教学方式以及教学手段等。但是,对于应用型普通本科院校而言,我们需要从自身的实际出发,根据我们的学生水平、课时的多少以及学校的办学特点,对编译原理的教学内容适当的选择,突出重点,是学生能够把握编译技术的核心内容。现在多数同学的注意力集中在一些细节的算法上,因此教学内容的选取原则是让学生宏观把握编译原理和技术。

编译原理主要包括五个阶段的讲解,即:词法分析阶段、语法分析阶段、语义分析与中间代码产生、代码优化和目标代码产生。

词法分析阶段,这部分内容的主线是正规式与有限自动机的相互转换,以及将有限自动机最小化。通过介绍正规式和有限自动机的概念,为什么需要转换,以及如何转换,让学生对有限自动机的识别功能,有个更深刻的理解。

语法分析阶段,该内容包括自上而下语法分析和自下而上语法分析两种。根据两类分析方法的特点,指出每种分析方法面临的问题或者说所需解决的关键问题,每种分析方法适用的文法环境,然后讲解如何实现每种分析方法。这一部分主要讲解两种具体的分析方法,即LL(1)分析方法和LR(0)分析方法。

自上而下的分析方法关键的问题是,非终结符有多个候选时,如何选择的问题,因此相关知识点较多,如消除递归(包括直接和间接)、消除回溯和求FIRST集FOLLOW集。对于这部分知识,学生容易把注意力集中在以上的具体算法上,所以,我们在教学中,需要重点讲述LL(1)分析方法的判别和预测分析表的构造,预测分析程序的构造和实现过程。可以采用案例教学法,以一个具体的小程序为例,讲解预测分析程序的实现过程,增强学生的直观感。

自下而上的分析方法关键的问题是,寻找句柄。对于上下文无关文法的分析,LR分析方法是一种高效的方法,包括:LR(0)、SLR、规范LR和LALR方法。LR分析表的生成算法较为复杂,因此讲解时重点应放在LR实现的关键问题,即如何确定栈顶符号是否构成句柄。对于这部分内容,重点让学生掌握LR(0)的分析方法。因为SLR(1)已经能够适应大多数的文法,所以规范LR和LALR方法部分,只需要让学生了解即可。

(三)加强实践环节

编译原理是一门理论性和实践性较强的课程。理论知识抽象难懂,我们可以通过实践,使学生加深对理论知识的理解。在实践教学中,我们可以从基本的验证试验开始,让学生循序渐进的学习,避免一开始就要求学生完成很难的任务,打击学生的信息和积极性。试验内容方面,比如对于词法分析,让学生先练习LEX的使用,之后设计编制调试一个具体的语法分析程序,要求功能简单,能把源程序中的关键字、标识符、运算符、常量和分隔符等识别出来即可,旨在加深学生对词法分析基本原理的理解。最后可以交给学生一个综合性的试验任务,让学生将零散的知识点串接起来,形成一个整体概念。

三、结束语

《编译原理》课程是计算机专业的核心课程之一,针对当前编译原理教学中存在的问题,就如何提高学生学习兴趣、合理安排教学内容等方面作了一些研究和探索。

参考文献:

[1]何炎祥,伍春香.计算机专业不需要开设编译原理课程吗?[J].计算机教育,2009,(4):61-62

篇5:编译原理课设总结(定稿)

经过一个星期的编译原理课程设计,在老师的指导以及小组同学的互相帮助下顺利完成该课程设计。通过该课程设计,收获很多。

此次课设,我们小组用的是java语言,在课设过程中,用到了以前开发过程中所没有的探索过的很多新方法,最直接的影响就是让我对java语言的认识与理解更近一层。并且掌握了什么是编译程序,编译程序工作的基本过程及其各阶段的基本任务,对课本上的知识有了更深的理解。

因为本实验用了java语言编写,个人觉得相比C语言模块更加清晰明了。在该词法分析程序中,我们用了java中的split方法对输入串进行分割,简单易懂。其次,在字符匹配过程中,引进了正则表达式,让输入串与之匹配,极大地缩减程序的繁琐性。同时,java的面对对象的性质在程序中得到充分的体现,在代码的编写过程中,将各种判定封装为函数,主函数通过调用这些封装函数完成功能,摒弃了C语言结构化的繁琐,使整个处理函数清晰可读。在测试多个用例时,发现程序的很多小错误,但最后都能够一一解决,尤其在这个过程中,我也充分体会到了团队合作的力量。此次课设更加深了对java语言的认识,并熟悉了java语言中正则表达式的用法。

篇6:编译原理复习总结

方法1

int WINAPI WinMain(//主函数

HINSTANCE hInstance,// handle to current instance HINSTANCE hPrevInstance, // handle to previous instance

LPSTR lpCmdLine,// command line

int nCmdShow

// show state)

WNDCLASS wndcls;//创建一个窗口对象

wndcls.cbClsExtra=0;//窗口类附加字节,为该类窗口所共享。通常0。

wndcls.cbWndExtra=0;//窗口附加字节。通常设为0。

wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//背景

wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);/光标

wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);//位图(图标)

wndcls.hInstance=hInstance;//当前应用程序事例句柄。

wndcls.lpfnWndProc=WinSunProc;// 窗口过程函数(回调函数)

wndcls.lpszClassName=“Weixin2003”;// 窗口名//类的名字

wndcls.lpszMenuName=NULL;//菜单名

wndcls.style=CS_HREDRAW | CS_VREDRAW;//窗口的类型

RegisterClass(&wndcls);//注册窗口

HWND hwnd;

hwnd=CreateWindow(“Weixin2003”,“

京”,WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL);//定义窗口句柄并创建窗口

ShowWindow(hwnd,SW_SHOWNORMAL);//显示窗口

UpdateWindow(hwnd);//更新窗口

MSG msg;//定义消息对象

/*做消息循环*/while(GetMessage(&msg, //接收消息的窗口句柄。//从消息队列中取出一条消息 NULL, //消息标识。0,0))//做消息循环

{

TranslateMessage(&msg);//进行消息(如键盘消息)转换

DispatchMessage(&msg);/分派消息到窗口的回调函数处理,}

return 0;}

//回调函数原形为LRESULT CALLBACK WindowProc();

LRESULT CALLBACK WinSunProc(//对消息的响应函数(回调函数)

HWND hwnd,// handle to window

UINT uMsg,// message identifier

WPARAM wParam, // first message parameter LPARAM lParam

// second message parameter){

switch(uMsg){

case WM_CHAR:break;

case WM_LBUTTONDOWN:

MessageBox(hwnd,“mouse clicked”,“weixin”,0);

HDC hdc;

hdc=GetDC(hwnd);

TextOut(hdc,0,50,“计算机编程语言培训”,strlen(“计算机编程语言培训”));

ReleaseDC(hwnd,hdc);

break;

case WM_PAINT:

HDC hDC;

PAINTSTRUCT ps;

hDC=BeginPaint(hwnd,&ps);

TextOut(hDC,0,0,“维新培训”,strlen(“维新培训”));

EndPaint(hwnd,&ps);

break;

case WM_CLOSE:

if(IDYES==MessageBox(hwnd,“是否真的结束?”,“weixin”,MB_YESNO))

{DestroyWindow(hwnd);}

break;

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

return DefWindowProc(hwnd,uMsg,wParam,lParam);

}

总结:创建一个完整的窗口需要经过下面四个操作步骤: 一,设计一个窗口类;如:WNDCLASS wndcls;二,注册窗口类;

如:RegisterClass(&wndcls);

三,创建窗口;

如:CreateWindow(),CreateWindowEX();四,显示及更新窗口。如:ShowWindow(),UpdateWindow();二:VC++掌握的基础

①使用VC编程除了良好的C基础外还需要掌握两方面: ②消息本身。不同消息所代表的用户操作和应用程序的状态。

③对于某个特定的消息来说,要让OS执行某个特定的功能去响应消息。

二.1消息的分类:标准消息,命令消息,通告消息。

[标准消息]:除WM_COMMAND之外,所有以WM_开头的消息。

[命令消息]:来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。

通过标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。

[通告消息]:由控件产生的消息,如按钮的单击。

1)从CWnd派生的类,可以接收到[标准消息] [命令消息]和[通告消息]。2)从CCmdTarget派生的类,只能可以接收到[命令消息]和[通告消息]。

三:两种函数调用约定(__stdcall 和 __cdecl)

#define CALLBACK

__stdcall

//__stdcall 标准调用预定,是PASCAL 调用约定,象DELPHI使用的就是标准调用约定

#define WINAPIV

__cdecl // __cdecl 是C 语言形式的调用约定。

主要区别:函数参数传递顺序 和 对堆栈的清除上。

问题:除了那些可变参数的函数调用外,其余的一般都是__stdcall约定。但 C/C++编译默然的是__cdecl约定。所以如果在VC等环境中调用__stdcall约定的函数,必须要在函数声明的时加上__stdcall 修饰符,以便对这个函数的调用是使用__stdcall约定(如使用DELPHI编写的DLL时候)。(VC中可通过这途径修改:project|settings..|c/c++|...)

四:关于DC句柄获取(CpaintDC/CclientDC/CwindowDC在创建时默认)

(调用这些函数)a)使用BeginPaint(),EndPaint()对。注意只能在响应WM_PAINT消息时使用。

b)使用GetDc(),ReleaseDC()对。注意他们不能在响应WM_PAINT中使用。MFC中的运用为① HDC hdc=::GetDc(m_hWnd);::ReleaseDC(m_hWnd,hdc);获得全局DC。

② CDC *pDC=GetDC();ReleaseDC(pDC);

③ CClientDC dc(this);(自动调用GetDc(),ReleaseDC()); ④ CWindowDC dc(this);(自动调用GetDc(),ReleaseDC());

五:MFC程序框架的剖析

①寻找WinMain

人口:路径:visual c++安装目录下的:vc98|MFC|SRC|APPMODUL.CPP:

寻找CWinApp构造函数:MFC|SRC|APPCORE.CPP: ②MFC程序

线

CTEApp

theApp-> CWinApp::CWinApp()->_tWinMain(){//进入程->AfxEndDeferRegisterClass(LONG fToRegister)-> PreCreateWindow(创建、显示和更新窗口)pThread->Run(消息循环)-> PumpMessage(//取消息并处理)

类的运行顺序为:C*APP->CmainFram->C*View->C*Doc

六:消息映射的三步骤:

①在头文件中声明消息响应函数原型。如:afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

②在源文件中进行消息映射。如:ON_WM_LBUTTONDOWN()③源文件中进行消息响应函数的定义。如:void CDrawView::OnLButtonDown(UINT nFlags, CPoint point){}

七:使用画笔、画刷、字体的步骤:(包括设计绘图模式SetROP2()

①CPen pen(PS_DOT,1,RGB(0,255,0));//构造画笔对象② CClientDC dc(this);③ CPen *pOldPen=dc.SelectObject(&pen);//将画笔选入DC后就可以作画了④dc.SelectObject(pOldPen);CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//构造透明画刷对象

FromHandle()将对象句柄转换为对象指针GetStockObject()取得一个以预定义的画笔、画刷、字体的句柄.类为Cpen Cbrush CFont

设计绘图模式: dc.SetROP2(R2_BLACK);(查MSDN).八:创建插入符:CDC类(文字等的输出类)

CClientDC dc(this);TEXTMETRIC tm;dc.GetTextMetrics(&tm);// 获取当前字体信息的度量

CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight);ShowCaret();// void CreateCaret(CBitmap* pBitmap);//创建位图插入符

//static void PASCAL SetCaretPos(POINT point);//设计插入符号的位置

九:创建路径层:

BOOL BeginPath();//在这作图定义路径层剪切区域BOOL EndPath();

BOOL SelectClipPath(int nMode);//调用这个函数来使当前路径层剪切区域与新剪切区域进行互操作。

应用:当作图的时候,如果想要在整幅图形其中的某个部分和其它部分有所区别,我们可以把这部分图形放到路径层当中,然后指定调用指定互操作模式调用SelectClipPath(int nMode)函数来使路径层和覆盖在其上新绘图剪切区域进行互操作,达到特殊效果。

十:设置定时器

①SetTimer(1,100,NULL);//放置定时1器并发送WM_TIMER消息

②作WM_TIMER消息响应并对Void OnTimer(UINT nIDEvent)编写代码。

十一:CMenu类

CMenu 类重要函数:CMenu*GetMenu得到窗口菜单栏对象指针。

CMenu::GetSubMenu获得指向弹出菜单对象指针

// SetMenu(CMenu* pMenu)设置新菜单或移除菜单 DrawMenuBar()//重绘菜单

//其它菜单的功能设计用MSDN查函数

十二:创建自定义菜单

①CMenu menu;//

象②menu.LoadMenu(IDR_MAINFRAME);③SetMenu(&menu);

④menu.Detach();// 这里menu对象作为一个局部对象。使用Detach()从menu对象中分离窗口菜单句柄,从而当menu对象析构的时候窗口菜单资源不随之销毁。也可将menu;定义为全局对象。

十三:对弹出式菜单项的命令更新

①给菜单项添加UPDATE_COMMAND_UI消息响应②在响应函数中调用CcmdUI类的成员函数。十四:向系统添加(右键弹出式)菜单(上下文菜单)

1系统添加法:

① Project->Add to Project->Components and Controls->Visual C++ conpenets->pop-upMenue->Insert->选择类(不能选CmainFram)其中系统增加的内容:A一个菜单资源;B,在派生View类中增加了OnContextMenu()函数

2系统添加法:①用资源管理器添加一个菜单资源②在鼠标右键消息响应函数中,加载菜单资源,并获得要显示的子菜单指针,并用该指针调用TrackPopupMenu函数便完成任务 代码如下:CMenu menu;

menu.LoadMenu(IDR_MENU1);CMenu *pPopup=menu.GetSubMenu(0);

ClientToScreen(&point);//将一个坐标点或一个矩形区域坐标转换成屏幕坐标。

pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,this);//在指定位置以指定的方式显示弹出菜单。也可对菜单项做消息响应。

2动态添加菜单法:①在CmainFram类的OnCreate()中创建Cmenu对象调用其成员函数添加、插入、删除子菜单、菜单项②手动给动态菜单项添加响应函数一:在Resource.h中可以添加资源的ID二:在头文件中写消息函数原型三在代码文件中添加消息映射和添加消息响应函数(注意手动添加要放在ClassWizard的规定的外面)

十五:集合类:

COBArray,CStringArray,CDWordArray,CPtrArray,CStringArray,CUIntArray,CWordArray

十六:在CMainFrame中截获对菜单命令的处理

由于CWnd::OnCommand 是个虚函数,可以在框架类中重写OnCommand函数,从而可以截获菜单消息使它不再往下(VIEW类)路由。例:

BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam){ int MenuCmdId=LOWORD(wParam);//取命令ID CMenu2View *pView=(CMenu2View*)GetActiveView();//获取当前VIEW类指针

if(MenuCmdId>=IDM_PHONE1 && MenuCmdIdm_strArray.GetSize())//消息范围判断

{CClientDC dc(pView);

dc.TextOut(0,0,pView->m_strArray.GetAt(MenuCmdId-IDM_PHONE1));return TRUE;//函数返回,避免调用CFrameWnd::OnCommand函数,在CFrameWnd::OnCommand中截获的消息会交由VIEW类处理}

return CFrameWnd::OnCommand(wParam, lParam);

//调用基类OnCommand函数,在CFrameWnd::OnCommand中截获的消息会交由VIEW类处理}

十七:对话框类CDialog

1.重要函数与成员变量

一:每个窗口类创建的对象的同时都拥有一个窗口句柄m_hWnd的成员变量。二:GetDlgItem(IDC)== 关联一个变量; 通过控件ID 获得控件对象指针 三:GetWindowText(CString& rString)/ /获得窗口、安键文本(char类型)四:int atoi(const char *string);itoa()// 把一个字符串与INT 类型的数值转为 五

GetDlgItemText(IDC_EDIT1,ch1,10)==GetDlgItem(IDC_EDIT1)->GetWindowText(ch1,10);在一个窗口控件中直接读取文本到字符数组中

六:INT GetDlgItemInt()//获得控件文本,并转换成数值类型 七:SetFocus()设计窗口、控件的焦点。GetFocus()

八;if(IDOK==dlg.DoModal())创建对话框后会等待用户作选择,就是DoModal、create的值。

九:对编辑框Edit控件写入内容后会发送EN_change消息,2.

问控件的六种方法:

一:GetDlgItem(IDC_EDIT2)->Get(Set)WindowText(ch2,10);二:Get(Set)DlgItemText(IDC_EDIT2,ch2)

三:Get(Set)DlgItemInt(IDC_EDIT2)

四:每个控件关联一个变量,直接对变量进行操作。调用UpdateData()对控件取设计值。

或:变量.GetWindowText(ch1,10);取得数据

五:通过SDK函数或变量的成员函数发送WM消息完成消息任务: ::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd,WM_GETTEXT,10,(LPARAM)ch1);

m_edit1.SendMessage(WM_GETTEXT,10,(LPARAM)ch1);六:直接给ID控件发送消息:

SendDlgItemMessage(IDC_EDIT1,WM_GETTEXT,10,(LPARAM)ch1);

十八:创建扩展窗口(收缩、扩展窗口)

①创建一个图表框通过ID获得其矩形的位置,并通过CRect对象记录其矩形位置。

GetDlgItem(IDC_)->GetWindowRect(&rectSeparator);GetWindowRect(&rectLarge);

②创建两个CRect对象通过点的付值记录其矩形位置收缩、扩展时的矩形位置。③SetWindowPos(NULL,0,0,rectSmall.Width(),rectSmall.Height(),SWP_NOMOVE 置窗口大小与位置

| SWP_NOZORDER);//设

//获得窗口大小十九:设计焦点事件(Tab Stop)

先对改变焦点事件做消息响应(如对回车ID_OK的响应)后

① GetFocus()->GetNextWindow()->SetFocus();//对最后一个不能判断。

②GetFocus()->GetWindow(GW_HWNDNEXT)->SetFocus();/对最后一个不能判断。

③GetNextDlgTabItem(GetFocus())->SetFocus();//最好

回车事件为窗口缺损消息由ONOK()响应,可通过对控件属性设计为缺损做消息响应以接收这个消息。廿:查看/改变对话框控件排列的秩序

在对话框资源界面中:Layout->Tab Order->改顺序。

廿一:逃跑按钮的巧妙实现

①创建多个Cbutton控件,并建立基于Cbutton类,类中包含一个本类的成员变量。

②将控件关联成这个类的一个变量,同时使自己的成员变量指向下个控件 ③ShowWindow(SW_HIDE);使自己隐藏,通过其成员变量m_pBtn->ShowWindow(SW_SHOW)使对方显示

廿二:如何制作属性页对话框和向导对话框CpropertySheet类CpropertyPage类

①创建属性页:insert->Resource->Dailog->选择后三个之一(如IDD_PROPPAGE_LARGE).②为各页添加控件并为各页创建以CpropertyPage(属性表单页类)为基类的属性表单页类.③以CPropertySheet为基类创建属性表单类,并在表单类中添加各表单页的对象。要加头文件。

④在表单类的构造函数中用AddPage(&m_prop1);添加各表页。

⑤在View中做消息响应做显示触发器。编代码:⑤.1构造表单对象(设计表单名)⑤.2调用propSheet.DoModal()或Create()显示页面。(注: 创建向导对话框在⑤.2前调用SetWizardMode()

⑥设计各页(上一步、下一步等)限制用户在不满足设定的条件时切换到其他属性页和向导页。:⑥.1 在各页中添加OnSetActive()虚函数⑥.2用表单指针调用SetWizardButtons()来设计。如:((CPropertySheet*)GetParent())->

SetWizardButtons(PSWIZB_NEXT);其响应函数为虚函数OnWizardNext/Back/Finish(查看MSDN)return –1不进入下一页。廿三:单选按钮操作方法:

①对所有单选按钮的第一个按钮属性设为Group,并为它们关联一个int类型的变量(使用时可按其编号访问)

②选择后(要按下一步或ok键)对按键作消息响应,用UpdateDate()对所选取值。

③对适当事件作消息响应通过一新的int类型的变量取这个关联的变量。

④使用选择值时作消息响应,通过变量作switch()case选择,通过str+=“程序员”等方式取值并将选择输出。

⑤使用完后在使用类的构造函数中对数组初始化

廿四:复选按钮操作方法:

①对所有复选按钮都关联一个Bool类型的变量(使用时可按其编号访问)

②选择后(要按下一步或ok键)对按键作消息响应,用UpdateDate()对所选取值。(就一个函数)

③对适当事件作消息响应通过Bool类型数组记录每个关联变量的值。

④使用选择值时作消息响应,通过Bool类型数组多次if(m_bLike[0])判断,通过str+=“程序员”等方式取值并将选择输出。

⑤使用完后在使用类的构造函数中用memset()对数组初始

廿五: 组合框操作方法:CcomboBox类

①做OnInitDialog()虚函数消息响应通过AddString()初始化选项值。

并通过((CComboBox*)GetDlgItem(IDC_COMBO2))->SetCurSel(0);负索引号值。

②对适当事件作消息响应通过引号。

int index=((CComboBox*)GetDlgItem(IDC_COMBO2))->GetCurSel();取得索

((CComboBox*)GetDlgItem(IDC_COMBO2))->GetLBText(index,m_strSalary);通过索引号将值存入字符串中。③对适当事件作消息响应通过新的CString类型变量记录这个字符串。

④使用选择值时作消息响应,通过CString类型变量以str+=“程序员”等方式直接使用。⑤使用完后在使用类的构造函数中对数组初始化

廿六:列表框操作方法:ClistBox类

①对所有复选按钮都关联一个CString类型的变量.并做OnInitDialog()虚函数消息响应通过AddString()初始化选项值。

((CListBox*)GetDlgItem(IDC_LIST1))->AddString(“北京”);

②对适当事件作消息响应通过新的CString类型变量记录关联变量的选择值。

③使用选择值时作消息响应,通过CString类型变量以str+=“程序员”等方式直接使用。④使用完后在使用类的构造函数中对数组初始化。

廿七:解决添加类成功后ClassWizard找不到其.h//.cpp文件

①在本工程目录下删除.CLW 文件;.CLW 为管理类信息的文件。②在工程中View->ClassWizard->是(输入这个文件名.CLW)

廿八:修改MFC AppWizard向导生成的框架程序窗口的大小和标题:在CMainFrame类中

在CMainFrame类中一法:在PreCreateWindow()中(窗口创建前)查MSDN的Frame-window styles

cs.cx=300;cs.lpszName=“http://”;

二法:在CMainFrame类的OnCreate()中:(窗口创建后)调用SetWindowLong()

SetWindowLong(m_hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW);

SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE)& ~WS_MAXIMIZEBOX);廿九:修改MFC AppWizard向导生成的框架程序窗口的图标:在CMainFrame类中

PreCreateWindow()一:中同窗口的创建相同:WNDCLASS wndcls;->设计->注册->修改

二cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW CS_VREDRAW,0,0,LoadIcon(NULL,IDI_WARNING));OnCreate()中三

OnCreate()中

加载系统图标:SetClassLong(m_hWnd,GCL_HICON,(LONG)LoadIcon(NULL,IDI_ERROR));

四:加载自定义图标: m_hIcons[0]=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));

SetClassLong(m_hWnd,GCL_HICON,(LONG)m_hIcons[0]);

三十:修改MFC AppWizard向导生成的框架程序窗口的背景、光标:在CView类中

PreCreateWindow()中一法:cs.lpszClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW, LoadCursor(NULL,IDC_CROSS),(HBRUSH)GetStockObject(BLACK_BRUSH),0);OnCreate()

:SetClassLong(m_hWnd,GCL_HBRBACKGROUND,(LONG)GetStockObject(BLACK_BRUSH));SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)LoadCursor(NULL,IDC_HELP));

背景

光标

卅一获得当前应用程序实例句柄的方法:

一:AfxGetInstanceHandle()二:theApp.m_hInstance三:AfxGetApp()->m_hInstance,卅一:.工具栏按钮编程和手动添加工具栏

CToolBar类 对菜单进行消息响应,对常用菜单在Resource的ToolBar中设计工具栏按钮,将其ID设计于菜单栏ID相同

手动添加工具栏查看MSDN的CToolBar类。也可查看CMainFrame::OnCreate()函数。

卅二:向应用程序导入图标资源:

将图标资源copy到本工程的.res目录下,insert->rousert->import导入图标资源

卅三:对菜单进行消息响应使自定义工具栏显示和隐藏:m_newToolBar为工具栏类对象。

1法:if(m_newToolBar.IsWindowVisible()){m_newToolBar.ShowWindow(SW_HIDE);} else{m_newToolBar.ShowWindow(SW_SHOW);}

RecalcLayout();

DockControlBar(&m_newToolBar);// 工具栏停靠函数 2法:ShowControlBar(&m_newToolBar,!m_newToolBar.IsWindowVisible(),FALSE);

卅四:对状态栏的状态指示器编程(编写时钟显示)CstatusBar类

①在String Table资源中加入ID资源并在CmainFrame的头文件中建立一个CstatusBar类对象。

②在CmainFrame类.cpp的static UINT indicators[]结构第一个ID后添加这个ID.就可显示这个String。

③在OnCreate()通过Cstring对象格式化记录要输出的内容。这里是时间.CTime t=CTime::GetCurrentTime();CString str=t.Format(“%H:%M:%S”);④ 通过

CSize sz=dc.GetTextExtent(str);取得屏幕输出要的宽度。

Int index=m_wndStatusBar.CommandToIndex(IDS_TIMER)//通过ID取得索引号并通过索引号设计窗格宽度 类对象.SetPaneInfo(1,IDS_TIMER,SBPS_NORMAL,sz.cx);⑤类对象.SetPaneText(1,str);输出内容。

⑥在OnPaint()中重写代码,当窗口重绘时再只显示。

卅五:对状态栏的指示行的编程 ①在响应的类中作消息响应。并编代码。②通过Cstring对象格式化记录要输出的内容如

CString str;

str.Format(“x=%d,y=%d”,point.x,point.y);③显示(有四种方法)一:((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);m_wndStatusBar为CstatusBar类对象

二:((CMainFrame*)GetParent())->SetMessageText(str);

三:((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(str);四str);

AFX_IDW_STATUS_BAR为系统准备的状态栏ID号;

:GetParent()->GetDescendantWindow(AFX_IDW_STATUS_BAR)->SetWindowText(卅六:进度栏的编写:CprogressCtr类

①在头文件中建立一个CprogressCtrr类对象。并在OnCreate()中通过对象创建一个进度栏。②

卅七:发送自定义消息:

①在头文件中定义消息宏:#define UM_PROGRESS

WM_USER+1 ②作消息映射③在要响应消息处通过SendMessage(UM_PROGRESS)或PostMessage(UM_PROGRESS)发送消息调用函数做要做的任务。SendMessage(UM_PROGRESS)发送消息马上调用函数

ostMessage(UM_PROGRESS)发送消息到消息队列中,并继续运行进程。

卅八:为应用程序添加启动画面

①1系统添加法:① Project->Add to Project->Components and Controls->Visual C++ conpenets->Splash Screen->Insert->选择类(不能选CmainFram)

②在Ontimer()中对显示时间做设计。如果手动添加可参看这个方法。

卅九:使用标准颜色对话框,标准字体对话框(CcolorDialog类,CfontDialog类)

颜色对话框:①做消息响应并建立控件对象,CColorDialog dlg;②创建颜色对话框并通过对象的数据成员m_cc指向的结构取的选择的颜色dlg.m_cc.Flags|=CC_RGBINIT | CC_FULLOPEN;//设计标记if(IDOK==dlg.DoModal()){

COLORREF m_clr=dlg.m_cc.rgbResult;}通过rgbResult的记录输出客户的选择。就可以在画笔、画刷、字体设计颜色。

字体对话框(雷同):①做消息响应并建立控件对象,CFontDialog dlg;②创建字体对话框并通过对象的数据成员m_cf指向的结构变量lpLogFont的字体值初始化自定义字体CFont m_font.CreateFontIndirect(dlg.m_cf.lpLogFont);就可为DC加载字体③为联系创建字体,要对m_font资源做判断,如果存在就释放资源在创建。

if(m_font.m_hObject)m_font.DeleteObject();查MSDN的类和它们的成员变量看事例。

四十:改变对话框的背景色,控件字体色、背景色(Cbutton除外)。

①做WM_CTLCOLOR消息响应,并创建一个CBRUSH对象,return这个对象来改变对话框的背景色 ②通过pWnd->GetDlgCtrlID()==ID—做判断,/用

pDC

调用SetTextColor(RGB(255,0,0));

SetBkMode(TRANSPARENT);SetBkColor(RGB(0,0,255));改变控件字体色、背景色,背景模式。

泗一:改变CButton控件字体色、背景色

①在工程中加入一个以CButton为基类的新类。并重载虚函数DrawItem();②在函数体中加入MSDN中CButton类的DrawItem()的示例代码。(改变背景色要自写代码)。

③在CButton控件中关联这个新类的变量,同时将控件属性Styles->Ower Draw选择上就可以改变字体色。改变背景色代码:有别人写的CSXBtn类和CButtonST类,以备:加载到工程中。

用CSXBtn类雷同上,CButtonST类如下:

①加载CButtonST到工程中,在CButton控件中关联这个新类的变量,重载:OnInitDialog()调用下面的函数

BOOL CSettingDlg::OnInitDialog()

{CDialog::OnInitDialog();m_btnST.SetActiveBgColor(RGB(0,0,255));m_btnST.SetActiveFgColor(RGB(255,0,0));}

泗二:在窗口中显示一幅位图。四步:

1、准备一副位图,响应WM_ERASEBKGND消息。

2、创建位图 bitmap.GetBitmap(&bmp);}

3、创建兼容DC CDC dcCompatible;dcCompatible.CreateCompatibleDC(pDC);

4、将位图选到兼容DC中

dcCompatible.SelectObject(&bitmap);在GetClientRect(&rect)取的客户矩形。

5、将兼容DC中的位图贴到当前DC中。pDC->BitBlt(rect.left,rect.top,rect.Width(), {或pDC->StretchBlt();} rect.Height(),&dcCompatible,0,0,SRCCOPY);

6、return TRUE;后也可在OnDraw()中又重绘。CBitmap

bitmap;

bitmap.LoadBitmap(IDB_BITMAP1);

{BITMAP

bmp;泗三:图形的保存和重绘

一法::

①在工程中添加一普通类,添加多个成员变量以保存图形的各要素,并添加带这几个参数的构造函数来初始化对象

②在绘图的View中建立CptrArray(或别的集合类)对象,在绘图函数中建立这个普通类的对象,没次绘图都记录这些数据并用

Add()添加到集合类对象中以保存图形。③在OnDraw()中用GetSize()取数组个数做循环,嵌套switch用GetAt(i)取图形类型重绘图形。for(int i=0;im_nDrawType)case X:}

二法:利用兼容DC实现图形的保存和重绘

①在View类中建一个CDC m_dc对象,在绘图响应函数中通过它建立一个兼容DC对象,并建一个兼容位图对象记录要保存的图片,将兼容位图选入兼容DC中,if(!CDC m_dcCompatible.m_hDC){ m_dcCompatible.CreateCompatibleDC(&dc);CRect rect;GetClientRect(&rect);CBitmap bitmap;

bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());m_dcCompatible.SelectObject(&bitmap);

m_dcCompatible.BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);/*将原始设备颜色和象素拷贝到兼容DC中*/m_dcCompatible.SelectObject(pBrush);} ②可以用兼容DC在绘图函数中作图。③在重绘函数

OnDraw()中通过兼容DC将记录的兼容位图拷贝到矩形空间。CRect rect;GetClientRect(&rect);

pDC->BitBlt(0,0,rect.Width(),rect.Height(),&m_dcCompatible,0,0,SRCCOPY);三法:CmetaFileDC 类: 查MSDN的介绍有步骤。

泗四:文件的操作,增加“打开、保存”文件对话框,注册表的读写

文件的操作:Cfile类 “打开、保存”文件对话框:CfileDialog类和m_ofn成员函数OPENFILENAME结构。

注册表的读写:查MSDN的Registry Functions

泗五:使用CArchive类对文件串行化(查MSDNCArchive类)①创建一个文件对象用于保存数据,同时创建一个CArchive ar 对象。

②通过ar>>将要输入的数据保存到文件中。同样也可通过ar<<将文件中的数据输出。

泗六:修改文挡标题的方法:

①法:在C*Doc类的OnNewDocument()中调用SetTitle()。注:在文挡、视图、框架创建是调用OnNewDocument(),所以可以添加代码设计它们。

②法:在资源String Table的IDR_MAINFRAME的第一二个n间修改字符。注:IDR_MAINFRAME包含的内容:主窗口名、文挡名、文挡类等。(查MSDN的CDOCTemplate::GetDOCString())

泗七:新类的串行化和文挡对图形的串行化处理过程:永久保存图形绘制图形:

第一步:实现新类对串行化的支持:(查MSDNCArchive类对CObject的串行化)①建立一个记录图形各要素的新类,并以CObject为基类。

②在新类中覆盖void Serialize(CArchive& ar)虚函数,并通过CArchive& ar对象实现存取。

③在新类头文件中加

DECLARE_SERIAL(新类名)的宏。

④在新类实现文件中加IMPLEMENT_SERIAL(新类名, CObject, 1)的宏。⑤在新类中重载一个不带参数的构造函数。(有初始化要素的构造函数)后这个类就支持串行化了。串行化完成。

注:本文为网友上传,旨在传播知识,不代表本站观点,与本站立场无关。若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:66553826@qq.com

上一篇:机械原理考试重点总结 下一篇:编译原理实验总结报告