1、计算机程序中的错误可以根据其被检测到的时间进行分类,如果是在编译时被检测到,还可以根据编译器的哪个部分检测到它们来分类。使用命令式语言,给出以下每种错误的示例。(a) 词法错误,由扫描器检测 (b) 语法错误,由解析器检测 (c) 静态语义错误,由语义分析检测 (d) 动态语义错误,由编译器生成的代码检测 (e) 编译器既无法捕获也难以生成代码来捕获的错误(这应该是违反语言定义的错误,而不仅仅是程序漏洞)
以下以C语言为例给出各类错误示例:
(a) 词法错误:
在代码中使用未定义的字符,比如写了一个非标准字符作为标识符的一部分,像
int 变量名@;
这里的 @ 会被扫描器检测为词法错误。
(b) 语法错误:
语句缺少必要的符号,例如
if (a > 5
缺少右括号 ) ,解析器在分析语法结构时会检测到该错误。
(c) 静态语义错误:
函数调用时参数类型不匹配,如定义函数
void func(int a);
调用时写成
func(3.14);
语义分析阶段会检测出这种错误。
(d) 动态语义错误:
除零错误,例如
int a = 5;
int b = 0;
int c = a / b;
只有在程序运行到这一行时才会发现该错误。
(e) 编译器难以捕获的错误:
程序访问了未初始化的指针所指向的内存,例如
int *p;
*p = 10;
编译器很难在编译时确定指针是否被初始化,也难以生成代码来捕获这种错误。
2、有一个计算最大公约数的程序如下:int main() { int i = getint(), j = getint(); while (i != j) { if (i > j) i = i % j; else j = j % i; } putint(i); } 该程序计算的结果与常规计算最大公约数的程序结果是否相同?如果不同,能否修正它?在什么情况下你认为其中一个会更快?
该程序计算的结果相同。它使用了模运算( % )来替代原程序中的减法运算。
在大多数情况下,使用模运算的程序会更快,尤其是当输入的数字较大时,因为模运算可以更快地缩小数字的大小,减少循环的次数。而原程序使用减法,在数字较大时,需要更多的迭代次数才能得到结果。
3、跟踪对输入12和8的最大公约数程序的解释过程。语法树节点按什么顺序被访问?
以下是调整为 Markdown 格式的文本内容:
解释器从语法树的根节点开始,按顺序访问以下节点:
- 第一个
:=节点,调用getint函数获取输入值 12 并赋值给i; - 第二个
:=节点,调用getint函数获取输入值 8 并赋值给j; -
while节点,计算其左子节点!=的值,判断i和j是否不相等; - 如果
!=结果为真,递归遍历while节点右子节点(if子树); - 重复步骤 3 和 4,直到
!=结果为假; - 最后访问最终的
call节点并输出结果。
4、编写一个从双向链表基类派生的双端队列(deque,发音为“deck”)抽象类。
以下是一个基于双向链表基类派生的双端队列抽象类的实现示例:假设存在一个双向链表类 doubly_linked_list ,它包含必要的方法,如 append 、 prepend 、 remove_head 、 remove_tail 等。
class deque : public doubly_linked_list {
public:
// 从尾部入队
void enqueue_back(int v) {
append(new list_node(v));
}
// 从头部入队
void enqueue_front(int v) {
prepend(new list_node(v));
}
// 从尾部出队
int dequeue_back() {
if (empty()) throw new list_err("attempt to dequeue from empty deque");
list_node* p = tail();

最低0.47元/天 解锁文章
2541

被折叠的 条评论
为什么被折叠?



