递归与goto<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
written by leezy_2000
记得刚开始学习C时,老师和教材都有明训:“千万不要乱用goto语句,否则将导致程序可读性极度下降。但能够极大提高效率地情况,可以考虑使用。”抱着不求有功,但求无过地心思,goto一度被我扔到了垃圾篓。后来随着阅读代码量地增加,我发现goto至少在两个方面可起到改善程序地作用。一是出错处理,二是用来模仿递归。用来做出错处理,在某些特定的场合可以,增强阅读性。用来仿真递归,可以极大的提高程序的性能,但无疑会降低程序的可读性。这篇文章讨论后者。
我们来看一段代码:
求n—0范围内,所有整数的累加。
unsigned add( unsigned num)
{
if(num != 0) return num+add(num-1);
else return 0;
}
使用的时候有:
unsigned c=100;
cout<< add(c) <<endl;
这段程序简单的很,就是用递归求解,没什么好说。当然效率不会高,尤其num比较大的时候。这种影响是由于过于频繁的函数调用导致的。
现在我们来归纳一下这次递归调用的特征:
1. 由于递归函数原型一致,所以堆栈中存放的数据类型一致。也就是相当于一个数组。
2. 先压栈,增长堆栈大小,达到某个临界条件,开始出栈。并对出栈数据进行累加。出栈的次数当然同压栈的次数一致。
为了降低函数调用对性能的影响,我们来仿真这个过程。看如下程序和注释。
unsigned stack[100];//模拟堆栈,假设n为100
bool goback=false; //临界条件
int i=0; //计数
int p=c; //p=100
int num=0; //和
//相当于递归函数的入口
recurse:
if( p!=0)//进栈
{
stack[i++] = p--;
goto recurse;
}
else goback=true; //达到临界条件了
//出栈,求和,从递归中返回
if( --i >=0 )
{
num +=stack[i];
goto recurse;
}
这样实现,在空间和时间上都会有较佳的改善,当然前提是要用在恰当的地方。
最后说明一下,这个方法不是我发明的。Microsoft C/C++运行时库中的qsort就是用这种办法实现的。
分享到:
相关推荐
1. **递归算法与非递归算法** 递归算法是一种解决问题的方法,它通过在函数内部调用自身来实现。在给定的标题中,`fun1` 函数就是一个递归算法的例子。当 `n=0` 时,`F(n)` 的值为 1;当 `n>0` 时,`F(n)` 等于 `n...
这里的`t1`, `t2`, `t3`是临时变量,`&&`是逻辑与运算,`!`是逻辑非运算,`goto`是跳转指令,`L0`和`L1`是标签。 通过递归下降法,我们逐层解析条件表达式,判断是否满足循环条件,然后执行循环体内的语句,并在...
LL(1)文法的解析过程是自顶向下,非递归的方式进行,这使得解析器的实现相对简单,且效率较高。 在非递归文法模拟中,我们通常会使用一个分析表来指导解析过程。这个分析表由两部分组成:ACTION表和GOTO表。ACTION...
递归下降法的优势在于它简单直观,易于理解和实现,且对于左递归和右递归的处理相对直接。 例如,一个简单的WHILE语句可能如以下形式: ``` WHILE condition DO statement ``` 对应的递归下降解析函数可以这样设计...
同时,三地址码是与特定机器无关的,方便进行进一步的优化和目标代码生成。 在课程设计过程中,你可能会经历以下步骤: 1. 分析IF-ELSE条件语句的语法结构,并建立相应的上下文无关文法。 2. 设计递归下降解析器...
在实际的编译器实现中,递归下降法通常与四元式结合使用。首先,递归下降法解析源代码,生成抽象语法树(AST)。然后,遍历AST并输出对应的四元式,为后续的优化和代码生成阶段做准备。对于FOR循环,这个过程涉及...
为了更好地理解这个问题,我们可以设想一个一维数组p,其长度与皇后数量N相等。数组中的每个元素p[k]对应于棋盘的第k+1行的皇后位置,表示该皇后所在的列号。这样,通过数组p我们就能追踪每一行皇后的位置,进而判断...
本主题主要关注如何使用递归下降法来解析IF-ELSE条件语句,并将其转换为三地址代码表示。这是一种编译器前端处理技术,有助于将高级语言转化为机器可理解的形式。 首先,让我们了解递归下降法。递归下降解析是一种...
本文将深入探讨如何使用递归下降法和四元式来翻译`for`循环,以及这背后的理论与实践。 **递归下降法**是一种编译器设计技术,主要用于解析语法结构。它通过定义一系列的递归函数来匹配输入的词法单元,每个函数...
- **递归原理**:递归的关键在于正确地识别出基本情况与递归情况。在本例中,基本情况是当目录为空时直接删除;递归情况是对每个非空子目录重复执行删除操作。 - **文件系统访问**:通过`Dir`函数获取目录内容、`...
在IF-ELSE条件下,可以生成如“IF cond THEN goto label1 ELSE goto label2”的四元式,其中cond是条件表达式,label1和label2分别对应于IF和ELSE分支的目标。这种方式简化了指令集架构的复杂性,使得翻译更加灵活。...
源代码中,每个函数都对应文法规则的一个分支,并使用`goto`语句来实现递归和重复匹配。例如,`EE_function`和`TT_function`使用循环结构(通过标签和`goto`)来处理加法和乘法的连续出现。在主函数`main()`中,用户...
它以屏幕中心为原点,通过简单的指令如`forward`、`left`、`right`、`penup`、`pendown`、`goto`、`home`和`circle`等,可以方便地创建各种图形。 例如,绘制五角星的代码可能如下: ```python import turtle def...
S.code := gen(S.begin':') || gen(E.true':') || S1.code || gen('goto'S.begin) | 这里的语义规则主要负责生成四元式,用于表示DO-WHILE循环的操作逻辑。 #### 3. 语法分析方法及中间代码形式的描述 ####...
递归的核心思想是将大问题分解成与原问题形式相同的小问题来解决。具体步骤如下: 1. 将除了最底层的一个圆盘外的所有圆盘从 A 柱移动到 B 柱,用 C 柱作为辅助。 2. 将最底层的圆盘从 A 柱移动到 C 柱。 3. 将 B ...
7. **中间代码生成**:程序中WHILE语句的三地址代码表示,如`if B goto L else goto Lnext`,以及算术表达式的三地址表示,如`E1:= (E2) F`。每个子程序根据文法规则生成对应的三地址代码。 8. **程序流程**:程序...
例如,初始化可能为`t0 = start`,测试可能为`if (t0 ) goto L1`,更新可能为`t0 = t0 + step`,循环体则对应于标签`L1:`后的指令。这种表示方式便于优化和目标代码生成。 4. **编译器设计流程**:在编译FOR循环时...
4. 循环回跳(例如,`(goto, loopCond, condExp)`,从循环体结束处跳回到条件判断) 5. 结束循环(例如,`(label, afterLoop)`,标记循环结束后的位置) 在这个过程中,递归下降解析器生成的抽象语法树(AST)会被...