Get清风C语言课程设计输入一个表达式输出其结果文档格式.docx
《Get清风C语言课程设计输入一个表达式输出其结果文档格式.docx》由会员分享,可在线阅读,更多相关《Get清风C语言课程设计输入一个表达式输出其结果文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
如果是数元素〔或小数点元素〕,那么依次存入用来存储后缀表达式的char数组,直到一个整合数存完之后用空格将其与后面的元素分开。
如果是运算符元素,那么根据当前运算符的优先级和栈里面的运算符的优先级进行处理。
如果栈内元素的优先级小于当前元素的优先级或者栈内为空,那么将当前运算符入栈;
如果栈内元素的优先级大于等于当前元素的,那么依次将出栈元素存入后缀表达式,并用空格将其与后面的元素分开,直到栈内元素的优先级小或者栈内为空。
对于左括号来说,无条件进栈,并只在有右括号出现的时候才有可能出栈。
对于右括号来说,无条件让栈内元素出栈,直到左括号出栈。
依次将每个元素进行处理直到中缀表达式索引完毕。
至此,已经实现了将中缀表达式转换成了后缀表达式,在数组的最后加上结束符以便下一步的调用。
第二步,读出后缀表达式并进行计算。
如果索引到空格那么将索引标志后推1位。
之后要先对char型的数字元素进行整合,从后缀表达式中依次取出数字元素〔连同小数点〕存入一个新的char型数组,直到一整个数取完后通过atof函数将char型转换成浮点型存入数栈,并将新数组初始化用来存储下一个数。
如果是索引到运算符,那么在数栈中出栈两个数字与当前运算符进行运算,先出栈的数字放在运算符后面,后出栈的数字放在运算符的前面,将运算以后的结果再次存入数栈。
依次进行计算直到后缀表达式索引完毕。
此时对栈内剩余元素进行操作。
每在符栈出栈一个运算符,就从数栈出栈两个数进行计算,算法同上,将运算以后的结果再次存入数栈。
循环操作直到符栈栈空,此时数栈出栈元素即为最后结果。
二、算法流程图
中缀转后缀再计算的算法分两个流程,第一步是中缀表达式转换成后缀表达式;
图1中缀转后缀算法流程图
第二步是将后缀表达式进行计算输出。
三.调试分析过程描述
1.首先,设计的程序每运行一次只能进行一次计算:
intmain()
{
printf("
******欢送进入小型计算器******\n请输入算术表达式:
"
);
charstr[N];
doubleresult;
scanf("
%s"
str);
result=Calu(str);
输出计算结果:
%f\n"
result);
}
为了改良程序,我在主函数里加了一个循环:
inta;
for(a=0;
;
a++)
〉〉"
2.为了人性化原那么,想什么时候退出计算就退出计算,我对程序又进行了改良,输入字母e退出计算:
if(exp1[index1]=='
('
)
tempsign.Type=exp1[index1];
tempsign.level=-1;
OpPush(&
OpStack,&
tempsign);
index1++;
else
if(exp1[index1]=='
)'
{
while(OpPeek(&
OpStack).level!
=-1){
exp2[index2]=OpPop(&
OpStack).Type;
index2++;
exp2[index2]='
'
index2++;
}
OpPop(&
OpStack);
index1++;
elseif(exp1[index1]=='
e'
)/*exit(0);
else
Error();
四.程序运行结果
五.程序源代码
#include<
stdio.h>
stdlib.h>
#defineN100/*N为数栈和表达式数组容量*/
#defineM100/*M为符栈和其他数组容量*/
typedefstruct/*定义运算符类型,level为运算符等级*/
charType;
intlevel;
}Type;
/*做一个Type用来存储运算符的优先级*/
typedefstruct/*定义数栈*/
doublestack[N];
inttop;
}OdStack;
typedefstruct/*定义符栈*/
Typestack[M];
}OpStack;
voidInit_OdStack(OdStack*s)/*定义初始化数栈*/
{
(*s).top=0;
}//初始化栈顶,赋等级0值
voidOdPush(OdStack*s,doublen)/*进数栈*/
if((*s).top==N-1)/*如果栈满那么报错退出程序*/
(*s).stack[(*s).top]=n;
//将数栈中的值变为n
(*s).top++;
//栈顶的值加1
doubleOdPop(OdStack*s)/*定义出数栈*/
if((*s).top==0)/*如果栈空那么报错退出程序*/
Error();
(*s).top--;
//栈顶的值减1
return(*s).stack[(*s).top];
//返回数栈中的值
voidInit_OpStack(OpStack*s)/*定义初始化符栈*/
voidOpPush(OpStack*s,Type*sign)/*定义进符栈*/
if((*s).top==M-1)/*如果栈满那么报错退出程序*/
(*s).stack[(*s).top]=*sign;
TypeOpPop(OpStack*s)/*定义出符栈*/
if((*s).top==0)/*栈空那么报错退出程序*/
//返回符栈的值
TypeOpPeek(OpStack*s)/*定义看符栈顶*/
Typeren;
if((*s).top==0)/*判栈空,空那么赋等级0值*/
ren.level=0;
//运算优先级为等级0值
returnren;
return(*s).stack[(*s).top-1];
intError()/*报错函数*/
输入错误!
\n"
exit
(1);
intCom(chartempch)/*定义运算符等级*/
/*给不同运算符定级*/
switch(tempch)
case'
+'
:
-'
level=1;
break;
*'
/'
level=2;
returnlevel;
//返回运算符等级
doubleOper(doublea,doubleb,chartempch)/*定义运算过程*/
doubleren;
switch(tempch)/*对不同运算符执行运算并返回结果*/
ren=b+a;
ren=b-a;
ren=b*a;
ren=b/a;
doubleCalu(char*exp1)//
OdStackOdStack;
/*定义数栈*/
OpStackOpStack;
/*定义符栈*/
Typetempsign;
/*定义Type型运算符*/
charexp2[N],tempexp[M],tempch;
/*定义后缀表达式数组exp2,整合数组tempexp,tempch为运算符*/
intindex1,index2,tempindex;
/*index1为主要索引,index2为次要索引,tempindex为附加索引*/
doublenumber,a,b,c;
/*number为整合数,a、b、c为运算数*/
Init_OdStack(&
OdStack);
/*初始化数栈*/
Init_OpStack(&
/*初始化符栈*/
index1=0;
/*初始化索引,附加索引*/
index2=0;
tempindex=0;
tempexp[0]='
\0'
/*初始化整合数组*/
while(exp1[index1]!
='
)/*处理初始表达式转化成后缀表达式*/
if((exp1[index1]>
0'
&
exp1[index1]<
9'
))/*处理数字元素*/
while((exp1[index1]>
)||exp1[index1]=='
.'
)
exp2[index2]=exp1[index1];
/*连续的数字元素不分开并依次存入后缀表达式*/
/*结束后用空格将其与后面的元素分开*/
else//不是数字或小数点元素
{
||exp1[index1]=='
)//是运算符/*处理运算符元素*/
tempsign.level=Com(tempsign.Type);
/*求运算符等级*/
while(OpPeek(&
OpStack).level>
=tempsign.level)/*当栈中符的等级大于当前等级时那么取出符存入后缀表达式*/
/*每两个运算符之间用空格分开*/
OpPush(&
/*结束后将当前运算符入栈*/
)/*如果是左括号那么无条件进栈*/
/*进栈后等级为-1,以便遇到右括号出栈*/
)/*右括号规那么*/
=-1)/*遇到右括号那么不断出栈存入后缀表达式直到寻到左括号*/
/*直到遇到左括号将左括号出栈*/
exit(0);
else/*如果输入了非法字符那么报错退出程序*/
=0)/*原表达式结束后对栈进行操作直到栈空*/
if(OpPeek(&
OpStack).level==-1)/*如果有为用掉的左括号那么报错退出程序*/
;
/*最后结束后缀表达式*/
/*索引归零,开始计算结果*/
while(exp2[index1]!
='
)/*循环直到后缀表达式结束*/
if((exp2[index1]>
exp2[index1]<
))/*整合数并入栈*/
while((exp2[index1]>
)||exp2[index1]=='
)/*用附加索引判断数的长度并整合入整合数组*/
tempexp[tempindex]=exp2[index1];
tempindex++;
tempexp[tempindex]='
/*结束整合数组*/
if(tempexp[0]!
)/*如果整合数组有值那么转换成浮点型存入数栈*/
number=atof(tempexp);
OdPush(&
OdStack,number);
/*入栈后初始化整合数组和附加索引以便下次整合*/
if(exp2[index1]=='
)/*判断空格,有那么跳过*/
while(exp2[index1]=='
)
||exp2[index1]=='
)/*对加减乘除进行运算*/
a=OdPop(&
b=OdPop(&
tempch=(exp2[index1]);
c=Oper(a,b,tempch);
OdStack,c);
/*将计算结果放入数栈*/
returnOdPop(&
OdStack);
/*弹出结果*/
******欢送进入小型计算器******\n字母e结输入束计算!
\n请输入算术表达式:
/*定义数组以存储表达式*/
/*定义result以存储结果*/
/*计算表达式并返回结果值*/
六.总结
通过对本次程序的学习和编写,了解了关于电脑对计算表达式的计算过程,并且学会了从中缀变成后缀的方法。
在本次编写的时候遇到了不少问题和麻烦,通过对C语言的复习和对算法的分析,最终也一一解决。
也是这次的编写让我更加认识到算法的重要性和算法的趣味性,特别是中缀转后缀如直接计算的差异表达了算法的开展历程和一个好的算法对于程序的关键性。
通过本次编写也意识到了清晰的程序结构对于以后的更新和更改都有很重要的意义,方便的利用函数体来定义一些算法比直接在主函数中设置算法要好的多。
更关键的是了解到了栈的性质和用途,一些适当的问题使用栈不仅仅可以迎刃而解,有时还能够起到事倍功半的效果。
从栈的构建、定义到入栈、出栈、看栈顶等的操作编写,大幅度提高了个人的编程能力,体会到了不同的结构在程序中所起到的不同的作用。
同时也更加关注了程序的容错机制和简介模式。
计算机与通信学院课程设计评分表
设计内容:
C语言程序设计
项目
评价
课程设计期间表现情况
课程设计内容完成情况
课程设计辩论成绩
课程设计报告完成质量
综合成绩
日期:
2021年6月30日