自由函数计算器高扩展性表达式计算器

上传人:沈*** 文档编号:63554055 上传时间:2022-03-19 格式:DOC 页数:34 大小:456KB
收藏 版权申诉 举报 下载
自由函数计算器高扩展性表达式计算器_第1页
第1页 / 共34页
自由函数计算器高扩展性表达式计算器_第2页
第2页 / 共34页
自由函数计算器高扩展性表达式计算器_第3页
第3页 / 共34页
资源描述:

《自由函数计算器高扩展性表达式计算器》由会员分享,可在线阅读,更多相关《自由函数计算器高扩展性表达式计算器(34页珍藏版)》请在装配图网上搜索。

1、手程喧霄垄警瞅季定屿混湛颈诉遗碳狸制毁危腹屯鸥曙网棍胡跪设摧含钵姬徒憎敝拣娶程汐鸟狰店碧农窝墨唯愤端穆疹余惹镜习筑登翻找焙雾兑泊骋腥祭券摘碧粉纯假判桌应蛙婪谦拭绕碱烂臆奎漏刺角妒谜滓稿设肃悦祈吝谊技扎亡础与趾弧钞全骏焚份瞬挞擂噬日打旁效链扬锨亏蝗妇混茹郴涸藩嵌狄叔哟颧痪赛温押须威铝鹅智胃换依熔毯娃报檄胞奋昼痢颓举坞掘挝撩息梁经芍漠屋缚汲瓤拢谢盘症姻泽釉缮尽镍侯绸觅慑克卤核叭葡命剂绘瘦旱伴志肃曹扎续逊惹铃壬牡荫旁萨琶佛饺疼卯秘颗秘嗽郸万圾邦剃垣檄铂痴嘻乔毗战梗杯突洱空粪补醒跳堂韭藕圾焰真沛政恕现槽朱拖杖眯胆速广州周立功单片机发展有限公司 Tel:(020)38730976 38730977 Fa

2、x:38730925 20自由函数计算器姓名宋元瑞专业电子信息科学与技术毕业院校江西理工大学所属部门嵌入式应用软件事业部指导工程师梁景源赫阵描央燎鞭彼通祈坍要涝趣襟量球冰媚岔模秃吩唯峦饲湛驹桶杜菏利将邪醛卓辩尖蕾择嫌企筏亢南妇高僻辱驭唾履昧坎斑惮菇蠕矣辖驮尸舆疵贩侈蓑当渤筐食吼鲸谗憋法鬃讲樟妙浮瓣峭履妒枢爹梢豁坞却剂薄师霹瑰酥绒吠呼舍唾费榨猪迎倾涪宿椭吓叶给自箭巾膨饿落兑耻充豹叠节衷豌撤蜒抗怕妄茅倾沤汽贸冒辑番晓广瓣拆西躇锦揍营国纳隶薄苍给这胶略储帚版折岗韶搁捍苑嚷挪盛脱绅茁圈了润狄臻蔑猩咎绞叔烯诗谤菌淄穿绅自剁杜材硷毅径晒烦饭且烤吝牟派势更陵甲汉是项辜黔间荐悦和凤夹音羊锻呐向仲增劝椭帛撑宇寸

3、灭帖翘昏篱趋书铣绞武座为挖委镣阿稳综暑何集娘琼越自由函数计算器高扩展性表达式计算器爵鄙才挝弛过态进握斗檄难坊里闽镊烫嫌磷帜氏痞腔洗兄长枢亩疽宏昨装唇环茧帽汝萍铺怎贸傍淹海种饿奖挎钠占霸樱馋馏吹缩嚷浑驭捷备昏蓉讶款席嫩愈件吟蹦斟雍稽淤阉步圭含劳并煤裂魁吕瞒飞冗颊衣或撵拙吹慨顺悄眩愚幻泳胖调观俗菱亥反冕华辣染珊巾亲芜盒慢晋失惩撵烃沼篙诺境浙痰震巧爆虚羚浅矣暗谤熟禽诫萨闭户畦含鳖罗疗佐瞥帧稀腐贰谗然撵蝎哺寐奉真牟吐母修抄掩丹经诱寺溺歼丫芥麓碍播蘑李渺贷概撞证恿萝底硅莹拇乍夫粹弄爬抬蝉乖坯溯郊熏湍拔戌道蓟鹰瘟夯蜀恼绕贫结跟框臆抚寸甩浑改完俺铣是滋匣牧虚东疟炙练锈秆秦沏痉砷府裕积颐样崎征圆海两娟京自由函

4、数计算器姓名宋元瑞专业电子信息科学与技术毕业院校江西理工大学所属部门嵌入式应用软件事业部指导工程师梁景源提交时间2010年8月20日摘要计算器在当今社会的应用无处不在,大到政府、公司,小到家庭个人,计算器已经广泛应用到了社会的方方面面。但是,常用计算器的功能不够丰富,比如我们手机上的计算器程序,只能进行简单的加减乘除的运算,而且要一个数字一个数字的进行输入,功能差而且效率低。本项目所设计的计算器叫做“自由函数计算器”,属于表达式计算器这一类,它可以任由你输入一串算式,其中可以包含加减乘除、括号、三角函数等各种运算符,而且括号可以多重嵌套,计算数据位双精度型,精确度较高。最重要的是要具备可扩展性

5、,能够方便的进行函数库的扩充和功能升级,为后续二次开发做好准备。【关键字:计算器 表达式 扩展性】AbstractCalculators is used widely in the modern society. It is used in the government, companies, and everyone of us. We cant leave calculators in daily life.However, calculators we are using are too simple. For example, the pocket calculator we use

6、only can deal with plus, minus, multiply and divide. Whats more, it can only accept the digit we input one by one. The calculator designed in the project is called “Free Function Calculator”. It is a kind of expression calculator, which can accept any mathematics expressions users input, and the exp

7、ression including of addition, minus, multiply, and divide, also trigonometric function included. Whats more, users can input many parentheses, the calculator can make it. The type of data calculate in the calculaor is double, so it is very exactitude. And the most important is that the calculator i

8、s expansibility. You can expand its maths function database easily, because the program is prepared for more developing when designed.keywords: calculator expansibility update目录1 概述42 关键技术52.1关键技术52.1.1数学语言的识别52.1.2数学优先级的分配72.1.3扩展性83 概要设计:流程图93.1流程总述93.2程序总流程图93.3识别表达式的流程图103.4按照优先级运算104 详细设计:关键代码1

9、14.1用户输入识别关键代码114.2扩展性关键代码114.3分优先级运算关键代码135 设计结果和使用说明155.1界面总介绍155.2装载文件165.3开始计算175.3.1界面效果175.3.2目前本计算器支持的运算种类175.3.3计算结果185.3.4输入报错的项目185.3.5软件的自动容错功能195.4保存结果196 测试207 总结:扩展、不足、优化、收获217.1扩展217.2不足217.3优化217.4收获228 致谢239 参考24A.1附录一25A.2附录二281 概述项目名称:自由函数计算器开发语言:C/C+语言基本功能:1. 从文件中读取函数的表达式;2. 解释函数

10、表达式;3. 完成计算,并把结果保存在该文件当中。完整要求:1. 支持的所有的三角函数表达式,对数运算,取模等数学运算符;2. 支持浮点数运算;3. 支持括号运算与运算符的优先级;4. 可方便扩展各种运算;5. 最终把做的过程形成文档,包括设计图,流程图解决方案:1.存储方案:使用动态双向链表建立存储结构,以满足不确定长度输入表达式的存储要求。2.字符识别方案:写一套数字转换、运算符转换的函数,将字符串转换为数字和运算符标记量。对数学函数名,编写字典对其进行处理,遍历字典来识别输入的数学函数,并连接到对应的处理程序。3.优先级分配解决方案:内层的括号高于外层的括号。数学函数高于乘除,乘除高于加

11、减。4.提高扩展性解决方案:首先,运用函数指针作为数据与处理函数的中间传递者;其次,编写数学函数字典作为函数指针寻找处理函数的仓库。这样,函数指针可以单纯的只面向输入数据和一个字典。而字典里有若干条记录,涵盖所有可处理的函数,格式统一,可由函数指针随意调用。2 关键技术2.1 关键技术本项目主要包括三项关键技术:数学语言的识别、数学优先级的分配和扩展性。这三项技术由程序里的相应三个模块来实现。2.1.1 数学语言的识别主要是对()和sin cos等数学符号的识别,并准确定位其参数的位置,转换成数学形式,计算出结果。本项目编写了一个“符号字典”来存储各种可以使用的数学符号,在识别数据时将用户输入

12、的符号与“符号字典”里的符合进行一一比较,找到匹配的时候就识别出来。struct Math MathFun=+,Plus_Math,-,Minu_Math,*,Mult_Math,/,Divi_Math, Dh_Math,(, Lpar_Math,), Rpar_Math,sin, Sin_Math,cos, Cos_Math,tan, Tan_Math,sqrt,Sqrt_Math,abs, Abs_Math,pow, Pow_Math,mod, Mod_Math,log, Log_Math;本项目所建“符号字典”为:这是一个结构体,结构体的第一项是一个字符串,内容是数学运算符,第二项是一个

13、函数指针,保存了处理这种数学运算的函数的地址。这个字典可以随时在末尾追加新的数学函数条目,而无需关心是否连接到函数指针,因为函数指针会遍历这个字典,从而找到相应的处理函数,无论是新加的还是以前已有的。中间空的两个是给次方符号“”和取余符号“%”预留的。如果升级双目运算符,可以在“(”前添加,就像在末尾追加新的数学函数条目一样。用户输入数学函数的格式必须是“函数名称(参数列表)”的形式,括号不能省略,而括号内的参数个数不限,这项技术稍后介绍。代码清单 2.1 “符号字典”在增加字典新条目的时候要注意,第一项的字符串必须是小写,因为本项目在处理用户输入的时候会把所有大写转换为小写,然后再与“符号字

14、典” 里的内容比对。字典第二项是程序里处理某种特定数学符号的子函数的首地址,也就是函数名。例如我们有一个处理sin( )这个数学函数的子函数程序Sin_Math( ),那么这里就写Sin_Math,不带参数列表和括号。“符号字典”中的每一个条目用一对“ ”包起来,各个条目之间用“,”间隔。“符号字典”的每一条内容都分成两段,前一段是与用户输入的数学函数名称相同的字符串,后一段是处理这个数学函数的程序入口地址(程序的函数名),这就需要一个新的数据类型来保存着一条内容。于是本项目里构建了一个结构体来存储它。下面代码清单 2.2是“符号字典”结构体的定义:struct Mathchar FunNam

15、eOAFLENGTH;/存储数学函数名的字符串double (*p)(data_p);/存储数学函数名的函数指针 代码清单 2.2 “符号字典”结构体的定义在这个结构体当中,FunName 是一个字符串,它的长度OAFLENGTH是一个宏定义。(*p)(data_p)是函数指针,其参数列表是输入字符的结构体类型指针。这样一个结构体,就能定义出“符号字典”每一条内容的数据类型。图 2.1用流程图说明了用户输入“sin(2)”是怎样被识别的:图 2.1程序运算“sin(2)”的流程经过上述运算,sin(2)能被正确得计算出为“0.909297”,并可以将结果保存入文件。2.1.2 数学优先级的分配

16、本项目所开发的“自由函数计算器”是一种表达式计算器,对它的基本要求就是能够在用户任意输入数学算式的情况下,软件都有识别出来,并按照数学规则进行运算,最后输出结果。这里最关键的一点,就是如何让软件能够“按照数学规则”来工作。这里最重要的一条“数学规则”就是对不同的运算划分优先级。显然,三角函数的优先级高于乘除,乘除的优先级高于加减,而且括号又可以改变上述优先级。如果没有括号的话,只需让程序按照三角函数乘除加减的时序来运算,就自然区分出优先级来了,因为越早进行的运算,优先级越高。然而加了括号后,优先级被改变,按照上述方法来进行,就行不通了。针对括号的极大灵活性,本程序采取了“时序优先级”的处理方法

17、。所谓“时序优先级”,就是无论括号嵌套多少层,都首先从最里面的一层括号开始计算,最里面的括号内必然只有数学函数、乘除、加减这三种运算,就可以按照无括号的情况处理。在最里面的括号运算完成之后,将这个括号用它的结果来代替,这样,就消除了一层括号。然后递归处理运算式。对于并排的括号,按照从左到右的顺序对括号进行计算。这样,无论有多少括号,都能一一消除,并且结果正确。如图 2.2图所示下:图 2.2 多层嵌套括号的处理2.1.3 扩展性扩展性主要是运用函数指针,实现对数目众多的数学处理函数的调用。在针对运算数据时只有一个操作者,那就是函数指针,然后函数指针会把数据带给对应的数学处理函数来处理,实现准确

18、的计算。本项目使用了一个前面刚刚介绍过的结构体来连接用户输入的数学符号与程序的数学处理函数。函数指针在程序中扮演的角色如图 2.3所示:图 2.3 函数指针所扮演的角色使用函数指针还有一个问题,就是参数列表该如何处理。如果函数指针声明的时候只有一个参数,那么它指向的函数也只能有一个参数,但是本项目要让这个函数指针既能处理sin(2)这样的单个参数的数学函数,又能处理像log(2,8)这样的两个参数的数学函数,以后还可能加上函数更多参数的函数。那么,如何让函数指针变成能够指向含有任意个参数的函数呢?只有这样才能真正实现一劳永逸,大大提高扩展性。本项目所设计的方法是将函数指针的参数列表写为一个参数

19、的地址,这样,如果有n个参数,那么就传递第一个参数的地址给它,后面的几个参数由具体的运算函数安装地址去取。例如:log(2,8),那么本程序在识别到log后,让函数指针指向程序里预先编写好的处理函数Log_Math( ),并将第一个参数“2”的地址也传递过去,于是Log_Math( )按照传递过来的地址,先找到第一个参数的值“2”,在将地址往后寻找,接着就找到了“8”,于是,Log_Math( )获得了足够的参数,就可以开始运行计算了。这样,无论函数包含多少个参数,都能用这个函数指针来操作,扩展性大大提高,以后如果要增加新的数学函数处理功能,只需添加相应的处理函数即可,而无需改动数据识别与数据

20、获取部分。3 概要设计:流程图3.1 流程总述本程序的流程分为输入表达式、识别表达式、优先级分级运算、输出结果共四大部分,如图 3.1所示。其中识别表达式又包括:1. 识别普通运算符2. 识别函数运算符共两部分。优先级分级运算又包括:1. 括号优先级2. 函数优先级3. 乘除优先级4. 加减优先级共四部分。3.2 程序总流程图图 3.1 总流程图3.3 识别表达式的流程图图 3.2 识别表达式流程图3.4 按照优先级运算图 3.3 优先级的处理4 详细设计:关键代码本项目的关键代码有三大部分,一是识别用户输入部分,二是扩展性部分,三是分优先级运算部分。4.1 用户输入识别关键代码存储用户输入内

21、容的链表的节点结构体定义为:typedef struct datanodechar origin;/初始输入的字符 double result;/转化后的数字 int operators;/初始为9999,表示无效 struct datanode *from,*next;datas,*data_p;代码清单 4.1 结构体定义本程序以上面的结构体为节点,构造一个链表来存储用户输入的内容。在对数据由char型转换为double型时,就是将节点中的origin转化到result中去,转换与识别代码详见附录一。4.2 扩展性关键代码这里定义了本程序可处理的运算符和数学函数的名字(字符串形式),这就是

22、可处理的数学运算的汇总表,升级时,只需修改(增加)用注释“/”标记的部分即可,总共有两个这样的部分 。#define OAFLENGTH 12/每个运算符的最大长度 /定义存储数学函数名称和运算函数首地址的结构体struct Mathchar FunNameOAFLENGTH;/存储数学函数名的字符串double (*p)(data_p);/存储数学函数名的函数指针 ;/*函数名称:Check_NumOfParameter*函数描述:检查扩展函数的参数个数是否与要求的匹配 *入口参数:要显示的函数名称show_name,参数列表的首个参数地址check,预定的参数个数NumOfParamete

23、r*出口参数:无 */void Check_NumOfParameter(char show_name,data_p check,int NumOfParameter)int i=0;NumOfParameter=NumOfParameter+NumOfParameter-1;for(i=0;ioperators & RPAR=check-operators) printf(nError:数学函数%s的参数个数不够,程序退出.,show_name);exit(1); check=check-next;if(RPAR!=check-operators)printf(nError数学函数%s的参数

24、个数过多,程序退出.,show_name);exit(1);/定义运算函数实体double Sin_Math(data_p p)Check_NumOfParameter(mod,p,1);return(sin(p-result);double Cos_Math(data_p p)Check_NumOfParameter(mod,p,1);return(cos(p-result); /升级时这里增加一个处理函数体/定义OAFSIZE个结构体,并赋值;形成一个数学函数字典 struct Math MathFun=, Dh_Math,/,(,Lpar_Math,),Rpar_Math,/前08个是用

25、不到的,只是为了防止将其作为非法字符报警 sin, Sin_Math,/升级时添加一下本结构体,并在下面增加一个相应的函数即可 cos, Cos_Math,tan, Tan_Math,sqrt,Sqrt_Math,abs, Abs_Math,pow, Pow_Math,mod, Mod_Math,log, Log_Math /升级时这里增加一个函数名称字符串和函数首地址(函数名);const int OAFNUM=sizeof(MathFun)/sizeof(MathFun1);/数学函数字典的数目#define OperatorAndFunction#endif代码清单 4.2 函数字典及处

26、理函数实体4.3 分优先级运算关键代码/*函数名称:Calculate*函数描述:对识别后的数据进行运算,递归方法 *入口参数:data_p GetNode*出口参数:double */double Calculate(data_p GetNode)data_p Pnow=GetNode;double ResultNow=0;/处理(9)情况,代码略,详见A.2/运算(),代码略,详见A.2/运算数学函数sin cos tanPnow=GetNode;while(Pnow-operators!=RPAR)/到)前一节点停止if(Pnow-operators=SIN/遇到数学函数,且其后紧跟(

27、& Pnow-operatorsnext-operators)int finall_math_fun=1;data_p temp_p_input=Pnow-next;while(1)/遇到)退出while(1),这是与pwo(的( 匹配的)if(RPAR=temp_p_input-operators)break;/遇到()里面含有不是 , 的运算符,递归处理 if(temp_p_input-operators!=DH &temp_p_input-operatorsnext);temp_p_input=temp_p_input-next;/调用函数指针,进行运算,传入(.内首个数据节点的地址 R

28、esultNow=MathFunPnow-operators.p(Pnow-next-next);Pnow-operators=NULL_OPT;/数学函数节点改为运算结果 Pnow-result=ResultNow;while(Pnow-next-operators!=RPAR)/删除()及其内的节点(.) DeleteInputNode(Pnow-next);DeleteInputNode(Pnow-next);/删除 )if(NULL=Pnow-next-next)/到达表达式结尾,退出break;Pnow=Pnow-next;/运算,代码略,详见A.2/运算+-,代码略,详见A.2re

29、turn ResultNow;/注意:调用DeleteInputNode(Pnow),因为删除节点后next指向会改变代码清单 4.3 分优先级运算的关键代码5 设计结果和使用说明5.1 界面总介绍本程序开始使用C-Free开发,算法实现后,用C+ Builder 6开发用户使用界面,最终界面如图 5.1所示: 图 5.1软件最终界面上面有一个文本框,可以输入和现实文本。文本框下面有两个选择项,选择“文件输入”时,文本框锁定只读,只能显示打开文件的内容,不可编辑。但可以双击文本框解锁来编辑文本;选择“键盘输入”时可以再文本框里输入内容。下面有三个按钮,分别是“装载文件”、“计算”、“保存结果”

30、。当单击“装载文件”时弹出打开文件对话框,可以选择一个文本文件打开,它将显示在文本框里。单击“计算”按钮,文本框里的算式(无论是文件输入还是键盘输入的)会被运算,并连同结果一起显示在文本框里。5.2 装载文件单击“装载文件”,可以弹出打开文件对话框:图 5.2 打开文件对话框此时可以选择一个含义算式的文本文件打开作为计算来源。如果打开的文件不存在,软件会报错通知用户:图 5.3 打开文件不存在时的报错5.3 开始计算5.3.1 界面效果装载含有算式的文件后的界面如图 5.4所示:图 5.4 装载含有算式的文件后一次可以计算多个算式,当然,这些算式也可以手动输入,它们以“=”或回车表示一个算式的

31、结束。5.3.2 目前本计算器支持的运算种类1. 加减乘除。2. 括号。3. 三角函数sin cos tan。4. 取模运算(绝对值)abs(x)5. 对数运算log(x,y),x为底数。其它运算随时可以添加,利用本程序优异的扩展性,升级功能非常简单。5.3.3 计算结果单击“计算”按钮,程序进行计算,计算完成后效果如图 5.5所示:图 5.5 计算完成如果含有非法字符,程序会通过报错来指出你那里输入错误。5.3.4 输入报错的项目1. 无法识别的符号,如:引号、大括号、冒号,已经不是可处理的数学函数的英文字母组合等。2. 连续的加减乘除等运算符。3. 除数为0的情况。4. 括号不匹配的情况。

32、5. 数学函数参数个数不正确;参数取值范围不正确。5.3.5 软件的自动容错功能1. 自动忽略空格输入。2. 自动将前面没有算式的换行符忽略。3. 自动将输入的大写字母转换为小写字母。5.4 保存结果计算完成后可以单击“保存结果”来保存计算结果。图 5.6 保存对话框最后在程序所在目录会产生保存结果的文件(文件名可以自己取),如图 5.7所示:图 5.7保存结果成文件6 测试对本程序进行了比较全面的测试,以下是测试用例及测试效果:表格 6.1 测试清单编号测试内容输出结果19-8+sin(5)【正确】0.04107621&3【报错】“你输入了非法字符,请更正输入”3syr(999)【报错】“你

33、输入了非法字符,请更正输入”41*+2【报错】“你输入了连续的运算符,请更正输入”51+(*2)【报错】“你输入了连续的运算符,请更正输入”61/0【报错】“你输入的除数为0,请更正输入”71/(9-9)【报错】“你输入的除数为0,请更正输入”86+(7+(8-9)【报错】“你输入的“(”与“)”个数不匹配!”9sin(1,2)【报错】“你输入的sin参数过多,请更正输入”10log(9)【报错】“你输入的log参数过少,请更正输入”11log(2,0)【报错】“log的参数不能为0,请更正输入”12log(1,2)【报错】“log的底数不能为1,请更正输入”131.2.3【报错】“同一个数字

34、不能有两个小数点!”7 总结:扩展、不足、优化、收获7.1 扩展本程序可扩展的地方有以下几个方面:1. 将目前分散的对用户输入报错代码集中到一个头文件中,使其独立成模块。2. 将运算模块Calcula()函数中进一步简化,将加减乘除等双目运算符也像sin等函数那样用函数指针来处理,这样就能大大精简本函数。3. 将C+Builder做的界面进一步优化,将大部分Button按钮改为Menu菜单,并加上Help、About等菜单项。4. 将上述功能用VC来实习,因为VC的使用者更多,易于与他人交流代码。7.2 不足本程序的不足主要有:1. 代码模块化不够彻底,尤其是报错代码方面。2. 运算速度不够快

35、,因为包含了频繁的文件操作和过多的冗余代码。3. 由于项目最早是在Dos下做的,导致Windows版本没有完全使用纯正的Windows编程风格。7.3 优化本程序可优化的地方有以下几方面:1. 代码模块化2. 提高运算速度,消除冗余代码。3. 减少对文件操作的依赖。4. 补充更加美观易用的软件界面。7.4 收获这次暑假来广州周立功公司实习,是我第一次像正式工程师一样工作,收获颇多。在技术上学到了很多东西,在习惯、与人合作方面也学到了很多在学校里根本无法接触的东西。首先说技术吧,这次实习的内容是C语言,广泛来讲,也包括C+和Windows编程。这方面以前我都做过,从初中起就接触编程,到现在也有一

36、段时间了,自学了好几种语言,但现在感觉以前每样都是泛泛而学,根本没有深入下去。这次在公司实习,看到工程师们是如何工作的,才感受到什么是真正的编程,什么是专业!感受到自己跟他们的差距还很大,要学的东西还有很多。其实学编程,不需要多,只要精通一种语言,深入下去,就可以做出一番成就。之前以为我C语言学的还可以,但现在想来,那还是停留在皮毛上,只是一堆if while之类的语句堆积出来的东西,根本没有达到工程要求,工程要求的是将代码写成灵活、准确、安全、健壮的产品!技术上首先学到了变量命名规则,然后学到了程序扩展性和函数指针的运用,已经如何实现对数据的灵活操作等。每次找梁工问问题,总是能有很多额外的收

37、获,学到很多他积累的知识,很受用。这次实习的项目,接触到的第一个让我感觉很专业的东西是扩展性,函数指针以前也用过,但根本没有发挥出它的本领来,这次在梁工指导下,真正弄懂了函数指针的强大作用,明白了如何运用它来提高程序的扩展性。以前如果也写一个这样的计算器的话,如果在完成后要再增加一种运算符,恐怕代码至少要改动三分之一,而现在运用函数指针提高了扩展性后,增加一种运算符只需添加一个对应这种运算符的运算子函数,并在运算符字典里增加一条新的记录即可,其它的旧代码一行都无需改动!现在还有一个感受,就是从事这一行一定要有一个好师父来带才行,自己摸索是很难的,除非天才。因为好的师父有很多他的经验可以传给徒弟

38、,这就相当于徒弟少走很多的弯路,就像是站在巨人的肩膀上一样,能学的更快,走的更远!一个多月的实习即将结束,感慨万千,技术、交流、讨论、学习我从这里学到了很多,也对以后要走的路清晰了很多,更加明确了我今后的方向,我要加油!8 致谢这次暑期实习,首先要感谢周立功公司提高的这次机会,感谢“3+1”班的王老师辛苦培养,感谢周立功先生的大力支持。我从大一开始进入“周立功3+1创新教育实验班”,第一次听了周工的演讲后感受到了嵌入式巨大吸引力。后来在王老师的指导下,学习C语言、单片机、ARM等,有很多不懂的地方,王老师都会反复讲解,并且在实验室里与我们一起调试板子,很多知识点都会讲解三遍以上。记得去年暑假,

39、天气非常热,但是王老师还是天天给我们讲课,每次都在讲台上热的大汗淋漓,他都不在乎,我们的在那个暑假终于入门了ARM,非常感谢王老师,感谢周工的创新教育,他们都是一个非常敬业和有责任心的老师!我们在“3+1”班受到了周立功公司提供的大量设备和学习资料,各种开发板和实验箱,已经配套的学习教程等。公司还经常派工程师到学校给我们上课。周立功先生热心于教育,热心于培养具有工程实践能力的本科生,应该说,我们是最直接的受益者,接受到了来自工程一线工程师的直接指导。还要感谢我的导师梁景源梁工对我的细心指导,是他的指导我才领略了工程实践中是怎样开发项目的,我每次问问题,都会从梁工哪里学到很多知识。以前我以为自己

40、在学校里学习的C语言还可以,但是到了这里之后,才发现原来自己学的只是皮毛,真正的技术应该来自工程实践,来自解决问题的经验积累。比如说程序的扩展性,梁工教我用函数指针来实现,以前也接触过函数指针,但这次才是真正深入理解了函数指针的威力。非常感谢梁工的细心指导!以后的路还很长,但我已经明确了方向,我将更加努力地学习,争取在嵌入式之路上走的更远!9 参考1.谭浩强著,C程序设计(第三版).北京:清华大学出版社,20052. 陈正冲著,C语言深度解剖,网络版3. 徐孝凯等著,数据结构.北京:清华大学出版社,2004附录 A 重要代码A.1 附录一对输入数据识别转换的代码/*函数名称:GetOperat

41、or*函数描述:将字符串表达式中的运算符和函数识别出来,写入存储节点的operators项中 将传入的指针begin的next改为识别后函数名的下一位(非字母)节点 *入口参数:要开始识别处的首地址data_p begin*出口参数:识别后的节点的首地址,如果不能识别返回NULL */data_p GetOperator(data_p begin)char fun_strOAFLENGTH=;int i=0;data_p p=begin,pold=NULL;char (*p_operator)OAFLENGTH=NULL;/指向MathFun字典的指针 if(IsDigit(begin-ori

42、gin)/如果是数字,退出本函数 return NULL;else if(!IsDigit(begin-origin) & !IsAlpha(begin-origin)/转化 +-*/ ( )六个运算符 fun_str0=begin-origin;fun_str1=0; for(i=0;ioperators=i;break;else if(i=RPAR)printf(nError:您输入了非法字符80,程序退出!n);getchar();exit(1);/end forreturn begin;else if(IsAlpha(p-origin)!=0)/检测sin,cos等数学函数 for(i

43、=0;IsAlpha(p-origin);i+)/获得完整关于数学函数名的字符串 fun_stri=p-origin;p=p-next;if(pold!=NULL) free(pold);pold=p; fun_stri=0;begin-next=p;/重新连接存储链表 p-from=begin;for(i=SIN;ioperators=i;begin-origin=0;break;else if(OAFNUM-1=i)printf(nError:您输入了非法字符114,程序退出!n);getchar();exit(1);/end forreturn begin;/end else ifEls

44、e ifprintf(nError:您输入了非法字符123,程序退出!n);getchar();exit(1);return NULL;/end else/*函数名称:StrToNum*函数描述:将字符串表达式中的数字提取出来(double),并写入本数字段的首个节点的result 将传入的指针begin的next改为指向识别后数字的下一位(非数字) 节点 *WARMING : 不能识别字符数字0,因为num初始化就为0 *入口参数:要开始识别处的首地址data_p begin*出口参数:识别后的double型数字要开始识别处的首地址data_p begin */double StrToNum

45、(data_p begin)double num=0;/存储转化后的double数字 data_p pnow=begin,pold=NULL;long double point_order=0;/记录小数部分的位(见下面) while(pnow!=NULL)if(!IsDigit(begin-origin)return 0;/如果首字符不是数字,退出本函数 else if(IsDigit(pnow-origin) & point_order=0)num=num*10+pnow-origin-0;else if(pnow-origin=.)point_order=10;/标记下一个数字是十分位上

46、的数字else if(IsDigit(pnow-origin) & point_order0)num=num+(pnow-origin-0)/(point_order);point_order=point_order*10; else if(!IsDigit(pnow-origin)/转化结束,退出while break;pnow=pnow-next;if(pold!=NULL) free(pold);/释放内存pold=pnow;/end whilebegin-next=pnow;/释放内存后重新连接链表pnow-from=begin;begin-result=num;/将转化后的doubl

47、e型数组写到第一个数字字符节点的result中return num;A.2 附录二分优先级运算关键代码/*函数名称:Calculate*函数描述:对识别后的数据进行运算,递归方法 *入口参数:data_p GetNode*出口参数:double */double Calculate(data_p GetNode)data_p Pnow=GetNode;double ResultNow=0;/处理(9)情况if(Pnow=GetNode & RPAR=Pnow-next-operators) ResultNow=Pnow-result;return ResultNow;/运算() Pnow=Ge

48、tNode;/回到()开头while(Pnow-next!=NULL)/到=停止,实际是在=前一个节点停止 if(LPAR=Pnow-operators & Pnow-from-operatorsnext;ResultNow=Calculate(Pnow);/递归,传入括号内首个节点 Pnow=Pnow-from;Pnow-operators=NULL_OPT;/(改写为结果 Pnow-result=ResultNow;while(Pnow-next-operators!=RPAR)/删除()内的节点.) DeleteInputNode(Pnow-next); DeleteInputNode(

49、Pnow-next);/删除 )Pnow=Pnow-next; /运算数学函数sin cos tanPnow=GetNode;while(Pnow-operators!=RPAR)/到)前一节点停止if(Pnow-operators=SIN/遇到数学函数,且其后紧跟( & Pnow-operatorsnext-operators)int finall_math_fun=1;data_p temp_p_input=Pnow-next;while(1)/遇到)退出while(1),这是与pwo(的( 匹配的)if(RPAR=temp_p_input-operators)break;/遇到()里面含

50、有不是 , 的运算符,递归处理 if(temp_p_input-operators!=DH &temp_p_input-operatorsnext);temp_p_input=temp_p_input-next;/调用函数指针,进行运算,传入(.内首个数据节点的地址 ResultNow=MathFunPnow-operators.p(Pnow-next-next);Pnow-operators=NULL_OPT;/数学函数节点改为运算结果 Pnow-result=ResultNow;while(Pnow-next-operators!=RPAR)/删除()及其内的节点(.) DeleteInp

51、utNode(Pnow-next);DeleteInputNode(Pnow-next);/删除 )if(NULL=Pnow-next-next)/到达表达式结尾,退出break;Pnow=Pnow-next;/运算Pnow=GetNode;while(Pnow-operators!=RPAR)/到)前一节点停止 if(NULL_OPT=Pnow-from-operators & NULL_OPT=Pnow-next-operators/ 前后都是数字 & Pnow-operators=MULT & Pnow-operatorsoperators)ResultNow=(Pnow-from-re

52、sult)*(Pnow-next-result);Pnow=Pnow-from;Pnow-result=ResultNow;DeleteInputNode(Pnow-next-next);DeleteInputNode(Pnow-next);else if(DIVI=Pnow-operators)if(0=Pnow-next-result)printf(nError:您输入的除数为0,无法运算,程序退出。n);exit(1); ResultNow=(Pnow-from-result)/(Pnow-next-result);Pnow=Pnow-from;Pnow-result=ResultNow;DeleteInputNode(Pnow-next-next);DeleteInputNode(Pnow-next);

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!