表达式解析原理
众所周知,表达式的解析,实际上就是一个递归的预算逻辑,有递归必然有堆栈的调用,因此堆栈的大小决定表达式的复杂程度,但是即便设置更大的堆栈,也会因为代码写的不合理导致资源的大幅度浪费,因此了解解析算法会写出更加优秀的代码;
如下代码:
void f1(int a){
int b;
b=(a+1)+(a+(a+(a+(a+(a+(a+1))))));
return b;
}
int a=0;
a=a+f1(a+f1(a+1));//注意此行函数参数内表达式又含有函数
echo(a);
在代码解析中,凡事遇见括号,即将括号内的表达式作为一个新式子来进行计算,这就是一个典型的递归算法,因此需要占用堆栈;而作为函数参数的表达式又含有函数,也就是函数的递归,这样双重递归会造成占用更多的堆栈算法,因此执行结果:
ERROR:表达式太长! @ADDR:41;comn:255
像此类问题,我们建议将代码修改如下:
void f1(int a){
int b;
b=(a+1)+(a+(a+(a+(a+(a+(a+1))))));
return b;
}
int a=0;
int b;
b=f1(a+1); //使用临时变量来暂存函数结果
a=a+f1(a+b);//避免函数参数表达式内含有函数
echo(a);
也就是说将函数参数套函数的方式改成先将函数赋值给一个临时变量,然后再调用,这样就将原先表达式的堆栈先释放出来;
当然,以上演示代码在实际中不会出现那么多括号嵌套,利用临时变量先计算一部分括号内表达式也可以减少表达式堆栈资源的占用;
总结
a=xx+func1(a1,func2(b1,b2));
//含有函数套函数的表达式,建议拆开写,养成这样的习惯
//修改成:
b=func2(b1,b2);
a=xx+func1(a1,b);
表达式参数配置
//以下是SHMICTRL-V1/V2/V3系列芯片对应的配置:
#define DEF_ExpressMaxNodeNum 16 //表达式最长有多少项
#define DEF_ExpressMaxCheng 16 //表达式最大迭代层数
- 第一个参数限制表达式最多的项目数,也就是说a+b这个式子有2项,一般来说我们不会书写16个项目的表达式,如果超过,建议使用临时变量拆分复杂表达式;
- 第二个参数就是堆栈预留空间,可以理解为括号的层数,但此层数还受函数的限制,详细可参见上面的阳历代码说明。