本文主要是介绍软考:软件设计师 — 17.程序设计语言与语言处理程序基础,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
十七. 程序设计语言与语言处理程序基础
1. 程序设计语言概述
(1)编译程序与解释程序
编译型语言 | 解释型语言 | ||
共同点 | 高级程序语言 | ||
有词法分析、语法分析、语义分析过程 | |||
不同点 | 翻译程序 | 编译器 | 解释器 |
是否生成目标代码 | 生成 | 不生成 | |
目标程序能否直接执行 | 直接执行 | 边解释边执行 | |
翻译程序是否参与执行 | 编译器不参与执行 | 解释器参与执行 | |
执行效率 | 效率高 | 效率低 | |
灵活性与可移植性 | 灵活性差,可移植性差 | 灵活性好,可移植性强 |
例题:
以下关于高级程序设计语言实现的编译和解释方式的叙述中,正确的是()。
A.编译程序不参与用户程序的运行控制,而解释程序则参与。
B.编译程序可以用高级语言编写,而解释程序只能用汇编语言编写。
C.编译方式处理源程序时不进行优化,而解释方式则进行优化。
D.编译方式不生成源程序的目标程序,而解释方式则生成。
解析:
A 项正确。编译程序和解释程序都可以用高级程序设计语言编写实现,B 项错误。编译与解释两种方式都进行优化,C 项错误。编译方式生成源程序的目标程序,而解释方式不生成,D 项错误。
(2)多种程序设计语言特点
- Fortran 语言(科学计算,执行效率高)
- Pascal 语言(为教学而开发,表达能力强,类似于 Delphi)
- C 语言(指针操作能力强,高效)
- Lisp 语言(函数式程序语言,符号处理,人工智能)
- C++ 语言(面向对象,高效)
- Java 语言(面向对象,中间代码,跨平台)
- C# 语言(面向对象,中间代码,.Net)
- Prolog 语言(逻辑推理,简洁性,表达能力,数据库和专家系统)
- Python 语言(解释型,面向对象,胶水语言)
- PHP 语言(服务器端执行,嵌入 HTML 文档的脚本语言)
- JavaScript 语言(被广泛应用于 Web 应用开发的脚本语言)
例题1:
以下关于脚本语言的叙述中,正确的是()。
A.脚本语言是通用的程序设计语言
B.脚本语言更适合应用在系统级程序开发中
C.脚本语言主要采用解释方式实现
D.脚本语言中不能定义函数和调用函数
解析1:
脚本语言不是通用的程序设计语言,常用于脚本设计,不适合应用在系统级程序开发中。脚本语言主要采用解释方式实现,可以定义和调用函数。因此 C 项正确。
例题2:
()是一种函数式编程语言。
A.Lisp B.Prolog C.Python D.Java/C++
解析2:
Lisp 是一种函数式编程语言;Prolog 常用于逻辑推理;Python 是一种解释型语言,胶水语言;Java/C++ 是面向对象的语言。
(3)程序设计语言的基本成分
包括数据、运算、控制和传输。
数据成分:常量和变量、全局量和局部量、数据类型。
其中,数据类型有:
- 基本类型:整型、字符型、实型、布尔型。
- 特殊类型:空类型。
- 用户定义类型:枚举类型。
- 构造类型:数组、结构、联合。
- 指针类型:type *。
- 抽象数据类型:类类型。
运算成分:指明允许使用的运算符合及运算规则。
控制成分:顺序结构、选择结构、循环结构。
传输成分:指明语言允许的数据传输方式,如赋值处理、数据的输入和输出等。
例题:
在程序运行过程中,()时涉及整型数据转换为浮点型数据的操作。
A.将浮点型变量赋值给整型变量
B.将整型常量赋值给整型变量
C.将整型变量与浮点型变量相加
D.将浮点型常量与浮点型变量相加
解析:
涉及到类型强制转换,A 项中会强转成整型,B 项中不涉及浮点型数据,C 项正确,会将整型数据转换成浮点型,D 项不涉及整型数据。
(4)函数调用方式
函数的定义:返回值类型 + 函数名 + (形参列表),如:
int FunctionExample(int x, float y){
… 函数体 …
}
函数的声明:函数应该先声明后引用。返回值类型 + 函数名(参数类型表)
函数的调用:
传递方式 | 特点 |
传值调用 | 形参取的是实参的值,形参的改变不会导致调用点所传的实参的值发生改变。 |
引用调用 | 形参取的是实参的地址,即实参存储单元的地址引用,因此形参值的改变也会导致实参值的改变。 |
在引用调用中,*x 和 *y 就相当于是 a 和 b 的别名,指向的是 a b 的实际地址,因此它们的改变也会导致实参 a b 的改变。
例题1:
常用的函数参数传递方式有传值和传引用两种,则()。
A.在传值方式下,形参与实参之间互相传值。
B.在传值方式下,实参不能是变量。
C.在传引用方式下,修改形参实质上改变了实参的值。
D.在传引用方式下,实参可以是任意的变量和表达式。
解析1:
在传值方式下,只能将实参的值传给形参,反之则不可以;实参也可以是变量,如 a b;在传引用方式下,对形参的修改也会影响实参,但实参只可以是任意的变量不能是表达式,因此 C 项正确。
例题2:
函数 t()、f() 的定义如下所示,若调用函数 t 时传递给 x 的值为 5,并且调用函数 f 时,第一个参数采用传值方式,第二个参数采用传引用方式,则函数 t 的返回值为()。
A.33 B.22 C.11 D.负数
解析2:
在函数 t 中,x = 5,a = 16,然后进到函数 f。函数 f 中, 实参 x 的值传递给形参 r,为 5,并且为传值方式,形参的改变不会影响实参,实参 a 的值传递给形参 s,为 16,并且为传引用方式,形参的改变会影响实参。在 f 中,x = 33,s = 38,r = 32,此时的 x 为函数 f 中局部变量 x,与 t 中的 x 不同。最后返回 a-x,其中 a = s = 38,x = 5,结果为 33,选 A。
例题3:
在程序的执行过程中,系统用()实现嵌套调用(递归调用)函数的正确返回。
A.队列 B.优先队列 C.栈 D.散列表
解析3:
系统用栈记录函数调用的返回,包括在中断过程中,也是用栈实现调用。
2. 编译程序基本原理
(1)编译过程概述
编译程序的功能是把某高级语言书写的源程序翻译成与之等价的目标程序。
在编译过程中,中间代码生成与代码优化阶段是可省略的。
- 词法分析:
从左到右逐个扫描源程序中的字符,识别其中如关键字(保留字)、标识符、常数、运算符以及分隔符等。词法分析的输入是源程序,输出是记号流。
如:VAR X,Y,Z:real;
X:=Y+Z*60;
词法分析结果为:
- 语法分析
根据语法规则将单词符号分解成各类语法单位,并分析源程序是否存在语法上的错误。包括:语言结构出错、if…end if 不匹配、缺少分号、括号不匹配、表达式缺少操作数等。如果源程序中没有语法错误,语法分析后就能正确地构造出其语法树,否则指出语法错误,并给出相应的诊断信息。语法分析的输入是词法分析的输出,即记号流。
词法分析与语法分析本质上都是对源程序的结构进行分析。
- 语义分析
进行类型分析和检查,主要检测源程序是否存在静态语义错误。包括:运算符和运算类型不符合,如取余时用浮点数等。语法分析会生成相应的语法树和符号表。
- 错误管理
错误类型 | 特点 |
动态错误(动态语义错误) |
|
静态错误 |
|
例题1:
编译器和解释器是两种基本的高级语言处理程序。编译器对高级语言源程序的处理过程可以划分为词法分析、语法分析、语义分析、中间代码生成、代码优化、目标代码生成等阶段,其中,()并不是每个编译器都必需的,与编译器相比,解释器()。
A.词法分析和语法分析
B.语义分析和中间代码生成
C.中间代码生成和代码优化
D.代码优化和目标代码生成
A.不参与运行控制,程序执行的速度慢
B.参与运行控制,程序执行的速度慢
C.参与运行控制,程序执行的速度快
D.不参与运行控制,程序执行的速度快
解析1:
编译过程中中间代码生成和代码优化不是每个编译器都必需的;与编译器相比,解释器参与运行控制,所以程序执行速度慢。因此选择 CB 项。
例题2:
在以阶段划分的编译器中,()阶段的主要作用是分析构成程序的字符及由字符按照构造规则构成的符号是否符合程序语言的规定。
A.词法分析 B.语法分析 C.语义分析 D.代码生成
解析2:
典型词法分析阶段的作用,输入源程序,输出记号流。
例题3:
将编译器的工作过程划分为词法分析、语义分析、中间代码生成、代码优化和目标代码生成时,语法分析阶段的输入是()。若程序中的括号不匹配,则会在()阶段检查出该错误。
解析3:
语法分析阶段的输入是词法分析阶段的输出,即记号流;程序中的括号不匹配,会在语法分析阶段检查出来。因此选 AB。
例题4:
语法指导翻译是一种()方法。
A.动态语义分析 B.中间代码优化 C.静态语义分析 D.目标代码优化
解析4:
语法指导翻译是一种静态语义分析方法。
例题5:
将高级语言源程序先转化为一种中间代码是现代编译器的常见处理方式。常用的中间代码有后缀式、()、树等。
A.前缀码 B.三地址码 C.符号表 D.补码和移码
解析5:
常用的中间代码有后缀式、三地址码(四元式)、树等。
例题6:
某程序运行时陷入死循环,则可能的原因是程序中存在()。
A.词法错误 B.语法错误 C.动态的语义错误 D.静态的语义错误
解析6:
程序运行时陷入死循环,可能是程序中存在动态的语义错误。
例题7:
在对高级语言源程序进行编译或解释处理的过程中,需要不断收集、记录和使用源程序中一些相关符号的类型和特征等信息,并将其存入()中。
A.哈希表 B.符号表 C.堆栈 D.队列
解析7:
相关符号等内容均存入符号表中。
(2)文法
文法是描述语言语法结构的规则。
一个形式文法是一个有序四元组 G= (V,T,S,P),其中:
- V:非终结符。不是语言组成部分,不是最终结果,可理解为占位符。
- T:终结符。是语言的组成部分,是最终结果。
- S:起始符。是语言的开始符号。
- P:产生式。用终结符替代非终结符的规则。
正则闭包:(也就是所有幂的组合)。
闭包:(在正则闭包的基础上,加上 )。
例如 ,而
常见的程序设计语言的文法类型为上下文无关文法。
语法推导树:
例:文法 G = ({a,b},{S,A},S,P),其中:
S —> aAS|a;A—>SbA|SS|ba。
构造句型 aabAa 的推导树。
在该文法中,大写字母代表非终结符,因为还可以继续推导,小写字母代表终结符。
1.S —> aAS 2.S —> a 3.A —> SbA 4.A —> SS 5.A —> ba
根据文法 G,起始符为 S,且句型 aabAa 开头为 a,因此首先需要由 S —> aAS;第二个字符为 a,如果由 A —> ba,则不成立,因此只能是 A —> SbA 或 A —> SS;先看 A —> SbA,可由 S —> a,这样就有 aabA,再由第一步中的 S —> a,可得到句型 aabAa。如果是 A —> SS,则无法推导出 aabAa 句型。
例题:
简单算术表达式的结构可以用下面的上下文无关文法进行描述(E为开始符号),()是符合该文法的句子。
E —> T|E+T;T —> F|T*F;F —> -F|N;N —> 0|1|2|3|4|5|6|7|8|9
A.2--3*4 B.2+-3*4 C.(2+3)*4 D.2*4-3
解析:
首先可以排除 C 项,因为题干中给出的文法不涉及括号。先看 A 项,由 E 出发,不涉及 + 号,因此可得 E —> T,又有 3*4,因此 T —> T*F,但 2 只能由 N 推导得出,因此如果 T —> T*F ,则无法得到 2,所以 A 项不正确,无法得到。再看 B 项,涉及到 + 号,因此 E —> E+T,继续推导,E —> T —> F —> N —> 2,此时有 2+,T —> T*F,有 T —> F —> -F —> -N —>-3,再 * F —> N —> 4,所以 B 项可以推导得出,选项 B 正确。再看 D 项,E —> T,T —> T*F,这样可以得到 2*4,但无法推导出后面的 -3,因此 D 项也无法得到。
(3)正规式与正规集
语言中具有独立含义的最小语法单位是符号(单词),如标识符、无符号常数与界限符等,词法分析的任务是把构成源程序的字符串转换成单词符号序列。词法规则可用 3 型文法(正规文法)或正规表达式描述,它产生的集合是语言基本字符集 (字母表)上的字符串的一个子集,称为正规集。
正规表达式和正规集:
正规式 | 正规集 | 举例 |
ab | 字符串 ab 构成的集合 | {ab} |
a|b | 字符串 a、b 构成的集合 | {a,b} |
a* | 由 0 或多个 a 构成的字符串集合 | {空,a,aa,aaa,…,(n个a)} |
(a|b)* | 所有字符 a 和 b 构成的串的集合 | {空,a,b,ab,aab,abb,baa,…} |
a(a|b)* | 以 a 为首字符的 a、b 字符串的集合 | {a,aa,ab,aab,aba,aaab,aaba,…} |
(a|b)*abb | 以 abb 结尾的 a、b 字符串的集合 | {abb,aabb,babb,abaabb,…,} |
例题:
由字符 a、b 构成的字符串中,若每个 a 后面至少跟一个 b,则该字符串集合可用正规式表示为()。
A.(b|ab)* B.(ab*)* C.(a*b*)* D.(a|b)*
解析:
每个 a 后至少有一个 b,而如果 b 本身带 *,则代表可以为空,也就是不取 b,因此可以排除 BC 选项。D 项中,是所有字符 a 和 b 构成的串的集合,也包括空集、a、b,因此 D 项也错误。只有 A 项正确,要么只取 b,要么就取到 ab,即每个 a 后面至少跟一个 b,只有 A 项可以。
(4)有限自动机
有限自动机是一种识别装置的抽象概念,它能准确地识别正规集,有限自动机分为两类:确定的有限自动机和不确定的有限自动机。
确定的有限自动机(DFA):
不确定的有限自动机(NFA):
与有限自动机的区别在于有向弧上的标记可以是 ,代表空集。
例题1:
某确定的有限自动机(DFA)的状态转换图如下图所示(A 是初态,C 是终态),则该 DFA 能识别()。
A.aabb B.abab C.baba D.abba
解析1:
从 A 出发到 B 只有 a,所以先排除 C 项;由 B 到 C 只有 b,再排除 A 项;BD 两项均能走通,但 A 是初态,C 是终态,最终状态应该是 C,而 D 项的终态是 B,因此只有 B 项正确。
例题2:
下图所示为一个不确定有限自动机(NFA)的状态转换图。该 NFA 可识别字符串()。
A.0110 B.0101 C.1100 D.1010
解析2:
NFA 相比 DFA 多了条件为空集的情况。从 0 出发到 1 只有 0,因此可以先排除 CD 项。B 项中,第二个条件为 1 ,第三个条件为 0,因此只能是 4 到 5,而结尾就缺少了 1 的条件,因此 B 项不成立,A 项正确。状态转换为: 0 - 1 - 2 - 3 - 2 - 3 - 4 - 5
例题3:
某有限自动机的状态转换图如下所示,与该自动机等价的正规式是()。
A.(0|1)* B.(0|10)* C.0*(10)* D.0*(1|0)*
解析3:
在有限自动机状态转换图中,双圈代表终态。 A 项代表所有 0 和 1 构成串的集合,其中包括 01,而 01 会使得上图的状态到 q1,不满足终态条件,因此不符合。同理,D 项也是,包含 01,不符合题干状态。假设考虑某一状态条件为 01010000,B 项是满足的,而 C 项不满足,因为其无法表示多个 0 结尾的状态条件,而题干给出的状态中是包含此类条件的,因此 C 项不正确,选 B。
(5)后缀表达式
前缀表达式(+ab);中缀表达式(a+b);后缀表达式(ab+)
例如:表达式(a-b)*(c+5)的后缀表达式为:
后缀表达式也称为逆波兰式,它可以理解为左右根的顺序。通常会结合栈进行计算。从表达式来看,就是先计算括号的内容,最后是乘法,因此其后缀表达式为 a b - c 5 + *
例题1:
下图为一个表达式的语法树,该表达式的后缀形式为()。
A.x 5 y + * a / b - B.x 5 y a b * + / - C.- / * + x 5 y a b D.x 5 + * y + a / b -
解析1:
根据左右根的顺序可知,A 项正确。
例题2:
表达式采用逆波兰式表示时,利用()进行求值。
A.栈 B.队列 C.符号表 D.散列表
解析2:
后缀表达式利用栈进行计算求值。
程序设计语言基础部分的内容至此结束,后续如果有补充或修改会直接添加。
这篇关于软考:软件设计师 — 17.程序设计语言与语言处理程序基础的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!