软考 – 软件设计师 – 二轮复习(2) – 程序设计语言(持续更新)
文章目录
前言
考试时间:每年5月、11月,软件设计师每年都会开考。
考试条件:三不限
考试形式: 一共两门
计算机于软件工程基本知识--120分钟--机考--选择题--75分(45及格)
软件设计--120分钟--机考--简答题(4道必做,1道二选一做)--75分(45及格)
两门都得一次性及格才算通过,一共4小时考试时间。
推荐博客:http://t.csdnimg.cn/5VzY5
推荐bilibli博主:zst_2001
本博客二轮复习资源免费下载:https://download.csdn.net/download/weixin_44399264/89687484
一、编译、解释、基本控制结构
二、数据类型
数据类型的作用:
1、便于为数据合理分配存储单元;
2、便于对参与表达式计算的数据对象进行检查;
3、便于规定数据对象的取值范围及能够进行的运算。
三、变量和常量、逻辑表达式(短路:&&、||、!)
常量不可以修改,没有分配存储单元
变量可以修改,有分配存储单元
四、传值调用与传引用调用
传值调用:
1、将【实参】的【值】传递给【形参】,【实参】可以是【变量、常量和表达式】;
2、【不可以】实现形参和实参间【双向传递】数据的效果。
传引用(地址)调用:
1、将【实参】的【地址】传递给【形参】,【形参必须有地址】,【实参】不能是【常量(值),表达式】。因为只有变量才会分配
存储单元;
2、【可以】实现形参和实参间【双向传递】数据的效果,即改变形参的值同时也改变了实参的值。
1、采用引用的方式,则a(f) = x的值;
2、先走f()代码,a = 5,c=g(a);
3、g(a)中,m=x(址)*m = 10;x(址) = a(f) = m-1 = 9;c = x(址) + m = 19;
4、则可知a(f) = 9,c = 19,则值为28,选择D
错误原因:看到形式参数就以为是按值传递,没看题目
五、符号表
符号表: 不断收集、记录和使用源程序中一些相关符号的类型和特征等信息,并将其存入符号表中。
记录源程序中各个字符的必要信息,以辅助语义的正确性检查和代码生成。
六、词法、语句、语义 、目标代码生成
词法分析:
输入:源程序;
输出:记号流
词法分析阶段的主要作用是:分析构成【程序的字符】;
语法分析:
输入:记号流;
输出:语法树(分析树)
语法分析阶段可以发现程序中所有的语法错误
语法分析阶段的主要作用是:对各条【语句的结构】进行合法性分析;
语义分析:
输入:语法树(分析树)
语义分析阶段的主要作用是进行【类型分析】和【检查】
【语法分析阶段】【可以发现】程序中的所有【语法错误】
【语义分析阶段】【不能发现】程序中【所有的语义错误】
【语义分析阶段可以发现静态语义错误】
【不能发现动态语义错误】,【动态语义错误运行时才能发现】
目标代码生成:
目标代码生成阶段的工作与具体的机器【密切相关】
寄存器的分配工作处于【目标代码生成阶段】
七、程序异常和错误
八、中间代码
知识点:
1、常见的中间代码有:【后缀式、三地址码、三元式、四元式和树(图)】等;
2、中间代码【与具体的机器无关】(不依赖具体的机器);
3、可以将不同的高级程序语言翻译成同一种中间代码,【中间代码可以跨平台】;
4、因为与具体的机器无关,使用中间代码有利于进行与【机器无关的优化处理】和【提高编译程序的可移植性】。
九、正规式
十、有限自动机–NFA、DFA
知识点:
有限自动机是【词法分析】的一个工具,它能正确地识别正规集;
【确定的有限自动机(DFA)】:对每一个状态来说识别字符后只有一个转移状态;
【不确定的有限自动机(NFA)】:对每一个状态来说识别字符后有一个以上的转移状态。
有限自动机:
1、开始、结束是对应的标识即可,中间无论走到哪个节点都无所谓(但是节点得能走通,不能走到某个节点卡死了)。也就是说
aaaaa,开始节点在a,结束节点在a就行了,【而不是只要走到a就结束】。
2、开始节点是a,结束节点是b,则一串字符串必须以a节点开始走到b结束。
3、有限自动机需要纠结的是开始是不是在a节点,结束是不是在b节点,中间节点会不会卡死就好。
知识点:
NFA:非确定有限自动机
DFA:确定有限自动机
NFA在同一状态,可以有多条出边,DFA在同一状态,只能有一条出边;
NFA的初态可以具有多个,DFA的初态是唯一的;
NFA在同一状态,可以有多条出边:比如这个图就是NFA,因为0可以通过输入一个字符a到达本身,还可以通过a到达1,这就是在同一状态0下输入a有多条出边;
十一、正规式有限自动机
1、先看起点,起点A有两条线,第一条线1*,第二条线0指向B;
2、再看终点前一个节点B,该点有两条线,第一条线0*,第二条线1指向C,可知指向C的最后一个字符一定是1,而指向C的前一个节点B的结果
只有0,则表示可知指向C的最后字符一定是01;
3、又发现开始的1*,0*可以随意组合,所以选择A;
A和C的比较:
1. (0|1)*01
描述:这个表达式表示一个字符串,该字符串可以是以0或1开头的任意长度的0和1的序列(包括空序列,因为*表示0次或多次),但必须以01
结尾。
有限自动机行为:对应的有限自动机将接受所有以01结尾的二进制字符串,包括那些以0或1开头的空字符串或任意长度的0和1的混合字符串,
只要它们以01结束。
2. 1*(0)*01
描述:这个表达式看起来有些不常见,因为它直接以1开头,然后是一个或多个0(也可以没有,因为表示0次或多次),最后以01结尾。然而,
需要注意的是,这个表达式实际上并不要求字符串必须以1开头,因为运算符前面的部分(1)是可以重复0次的。但由于后续有(0)*和01,
实际使用中更常见的理解是,字符串必须至少包含一个1,之后是任意数量的0(包括0个),并以01结尾。
有限自动机行为:对应的有限自动机将接受所有至少包含一个1,随后是任意数量(包括0个)的0,并以01结尾的二进制字符串。这个描述在理解
上需要一些注意,因为初始的1可以是可选的(尽管理论上是这样,但在实际应用中通常会假设至少有一个1),但后续的(0)*和01部分是
必需的。
区别总结:
开头部分:(0|1)*01允许字符串以0或1开头,甚至可以是空字符串;而1*(0)*01在逻辑上要求至少有一个1(尽管从语法的严格意义上讲,
初始的1可以省略,但后续的(0)*和01限制了这一点)。
中间部分:两者都允许在开头和结尾之间插入任意数量的0和1(尽管1*(0)*01的初始部分在实际使用中通常被视为至少包含一个1),但重点在
于结尾。
结尾部分:两者都要求以01结尾。
因此,主要区别在于开头部分的可能性,其中(0|1)*01提供了更大的灵活性,而1*(0)*01在逻辑上(尽管在语法上存在细微差别)更倾向于
要求字符串至少包含一个1。
1、先看起点,起点只有指向后面的1条线,必须输入a,才能往下走,则开始字符必定是单个a字符;
2、再看终点前一个节点,该点只有指向后面的1条线,必须输入a,才能走到终点,则结束字符必定是单个a字符;
3、最后看中间,并且忽略单个出现的空格符,则中间的b可以出现无数个,b*;
所以结果为ab*a,选择A
十二、文法
知识点:
1、大多数程序设计语言地语法规则用【上下文无关】文法描述
2、一个文法产生的句子是从【文法开始符号】出发推导出的【所有终结符号串】。
这种题目做法:
1、秒掉不可能的选项:文法推到中不存在的推到关系,比如:()、\等;
2、把剩下的选项带入推导式子看看能不能推出来;
秒题:
B:文法中推导没有括号,排除;
C:id表示的是单个字母的变量,而C中有个常量2,排除;
D:文法中推导没有除号,排除。
十三、中、后缀表达式
中缀表达式:运算符喜欢放中间;
中缀转后缀计算方法:
1、根据优先级计算,将a?b格式转ab?,并且将新转出来字符串作为整体带入原式;
2、同优先级的,按照从右到左规则,继续将a?b,转为ab?,并且将新转出来字符串作为整体带入上次一转出来的式子。
3、重复下去,得到后缀表达式;
后缀表达式(逆波兰式):运算符喜欢放后面;
后缀转中缀计算方法:
1、从左向右开始数,数到第一个符号(+-*/),将其作为后缀ab?的?号,则其前面两个数分别为ab,则后缀ab?元素齐全,将ab?转为a?b,
将取得的a?b作为整体带入原式,替换掉原来的字符串组合;
2、继续向后面数符号(+-*/),当又数到符号位,将其作为后缀ab?的?号,则其前面两个数分别为ab,则后缀ab?元素齐全,将ab?转为
a?b,并作为整体带入步奏1最后得到的式子,替换掉其原来的字符串组合。
3、继续向后面数符号(+-*/),重复上述操作,得到后缀表达式
优先级:() > * / > + -,逻辑与 > 逻辑或;
优先级相同:从右向左
Tips:如果有加减后,又碰到*/,记得给之前的+-带上();
下面就是中缀式转后缀式方法:
1、根据优先级,先转()里面的数字(3+4)符合a?b,将其转为ab?,则为34+,将34+堪为整体替代掉原有的(3+4),得到图2;
2、根据优先级相同从右向左原则,图3将34+看为整体a,/看为?,5看作b,则将其后缀排序为ab?为34+5/,将其看为整体,替代原有的34+/5得到图4;
3、继续操作下去得到图9.
后缀式转中缀式可以用【栈】推导,如下图:
但是一般来说不这么推导,都用以下方法推导:
错题/例题:
1、上面题目是中缀推导后缀:根据优先级,将a?b转为ab?,同优先级的从右到左;
2、上面题目优先级排序:() > > >⋀ > ⋁
3、解题(【】表示的是看为整体):a⋀b⋁c⋀(b⋁x>0) --> a⋀b⋁c⋀(b⋁【x0>】) --> a⋀b⋁c⋀【bx0>⋁】--> a⋀b⋁【cbx0>⋁⋀】
--> 【ab⋀】⋁【cbx0>⋁⋀】 --> ab⋀cbx0>⋁⋀⋁
第一个选项:B
第二个选项解析:
1、逆波兰式(后缀表达式)转中缀表达式,解法是从左向右读取字符,当读取到+-*/的字符时候,将其看为?,其之前的两个字符分别为ab,
则规则ab?都有了,将其转为a?b并且作为整体替换掉原有表达式中对应部分,重复此操作...
2、ab-cd+* --> 【a-b】cd+* --> 【a-b】【c+d】* (这边前两个都是+-,优先级低于*/,则+-与要加上() ) -->
【(a-b)】*【(c+d)】 --> (a-b)*(c+d);
选择C
十四、语法树推导中、后缀表达式
考法:
1、给算术表达式 ---> 语法树; 解法:对每个选项树进行中序遍历,与题目给的算术表达式对比;
2、给语法树 ---> 求算数表达式;解法:对语法树进行中序遍历,得出算术表达式;
上题:
A:(a+b)*(c-d);
B: (a+(b-c))*d;
C: (a-(b+c))*d;
D: a*((b+c)-d)
选择B
题中未提及什么表达式的就是按照中序表达式分析,简单算数表达式需要加上()
十五、杂题精选
【编译】是【将高级语言源程序翻译成机器语言程序】(汇编形式或机器代码形式),反编译是编译的逆过程。【反编译通常不能】把可执行文件
还原成高级语言源代码,只能转换成【功能上等价】的汇编程序。
自顶向下语法分析方法:递归下降分析法、预测分析法。
自底向上语法分析方法:移进—归约分析法、LR分析法