严蔚敏视频 笔记08
例五 表达式求值
限于二元运算符的表达式定义:
表达式::=(操作数)+(运算符)+(操作数)
操作数::=简单变量|表达式
简单变量::=标识符|无符号整数
OP S1 S2 前缀表示法
S1 OP S2 中缀表示法
S1 S2 OP 后缀表示法
结论:
1)操作数之间的相对次序不变
2)运算符的相对次序不同
3)中缀式丢失了括弧信息,致使运算的次序不确定
4)前缀式的运算规则为:
连续出现的两个操作数和在它们之前紧靠它们的运算符构成一个最小表达式
5)后缀式的运算规则为:
运算符在式中出现的顺序恰为表达式的运算顺序
连续出现的两个操作数和在它们之后紧靠它们的运算符构成一个最小表达式
利用栈求后缀式
如何从原表达式求得后缀式:
每个运算符的运算次序要由它之后的一个运算符来定,在后缀式中,优先数高的运算符领先于优先数低的运算符。
从原表达式求得后缀式的规律为:
1)设立操作数栈
2)设表达式的结束符为“#”,预设运算符栈的栈底为“#”
3)若当前字符是操作数,则直接发送给后缀式
4)若当前运算符的优先数高于栈顶运算符,则进栈
5)否则,退出栈顶运算符发送给后缀式
6)“(”对它前后的运算符起隔离作用,“)”可视为自相应左括弧开始的表达式的结束符
void transform(char suffix[],char exp[])
例六 实现递归
当在一个函数的运行期间调用另一个函数时,在运行该被调用函数之前,需先完成三件事:
将所有的实参、返回地址等信息传递给被调用函数保存
为被调用函数的局部变量分配存储区
将控制转移到被调用函数的入口
从被调用函数返回调用函数之前,应该完成:
保存被调函数的计算结果
释放被调函数的数据区
依照被调函数保存的返回地址将控制转移到调用函数
多个函数嵌套调用的规则是:
后调用先返回 此时的内存管理实行“栈式管理”
递归过程指向过程中占用的数据区,称为递归工作栈
每一层的递归参数合成一个记录,称为递归工作记录
栈顶记录指示当前层的执行情况,称为当前活动记录
栈顶指针称为当前环境指针
典型递归
void hanoi(int n,char x,char y,char z) {
if(n==1) move(x,1,z);
else {
hanoi(n-1,x,z,y);
move(x,n,z);
hanoi(n-1,y,x,z);
}
}