C语言课程设计--输入一个表达式,输出其结果
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计报告
课程名称C语言程序设计
课题名称输入一个表达式,输出其结果
专业通信工程
班级通信1101
学号27
姓名皮锋
指导教师罗雅博彭祯曹燚
2012年6月29 日
湖南工程学院
课程设计任务书
课程名称C语言程序设计
课题输入一个表达式,输出其结果
专业班级通信1101
学生姓名皮锋
学号27
指导老师罗雅博彭祯曹燚
审批
任务书下达日期2012 年6 月15 日
任务完成日期2012 年6 月29日
一、设计思想
两种算法首先都要建立两个栈,一个是存放操作数的数栈OdStack,一个是存放运算符的符栈OpStack。数栈采用double型的用来存放浮点数,符栈采用char型的用来存放运算符,由于考虑到运算符有优先级的问题,所以事先做了一个Type用来存储运算符的优先级。栈建立好了之后做栈的相关操作,初始化栈,入栈,出栈,看栈顶。其中入栈要判满,出栈和看栈顶要判空。
中缀转后缀再计算的算法。
此算法的基本思路是先将中缀表达式转换成后缀表达式,之后再利用后缀表达式的算法对表达式进行计算。
首先,用一个char数组将中缀表达式读入,对数组中的每一个元素进行处理,区分哪些是数,哪些是运算符。如果是数元素(或小数点元素),则依次存入用来存储后缀表达式的char数组,直到一个整合数存完之后用空格将其与后面的元素分开。如果是运算符元素,则根据当前运算符的优先级和栈里面的运算符的优先级进行处理。如果栈内元素的优先级小于当前元素的优先级或者栈内为空,则将当前运算符入栈;如果栈内元素的优先级大于等于当前元素的,则依次将出栈元素存入后缀表达式,并用空格将其与后面的元素分开,直到栈内元素的优先级小或者栈内为空。对于左括号来说,无条件进栈,并只在有右括号出现的时候才有可能出栈。对于右括号来说,无条件让栈内元素出栈,直到左括号出栈。依次将每个元素进行处理直到中缀表达式索引完毕。至此,已经实现了将中缀表达式转换成了后缀表达式,在数组的最后加上结束符以便下一步的调用。
第二步,读出后缀表达式并进行计算。如果索引到空格则将索引标志后推1位。之后要先对char型的数字元素进行整合,从后缀表达式中依次取出数字元素(连同小数点)存入一个新的char型数组,直到一整个数取完后通过atof函数将char型转换成浮点型存入数栈,并将新数组初始化用来存储下一个数。如果是索引到运算符,则在数栈中出栈两个数字与当前运算符进行运算,先出栈的数字放在运算符后面,后出栈的数字放在运算符的前面,将运算以后的结果再次存入数栈。依次进行计算直到后缀表达式索引完毕。此时对栈内剩余元素进行操作。每在符栈出栈一个运算符,就从数栈出栈两个数进行计算,算法同上,将运算以后的结果再次存入数栈。循环操作直到符栈栈空,此时数栈出栈元素即为最后结果。
二、算法流程图
中缀转后缀再计算的算法分两个流程,第一步是中缀表达式转换成后缀表达式;
图1 中缀转后缀算法流程图
第二步是将后缀表达式进行计算输出。
三.调试分析过程描述
1.首先,设计的程序每运行一次只能进行一次计算:
int main()
{
printf(" ******欢迎进入小型计算器******\n请输入算术表达式:");
char str[N];
double result;
scanf("%s",str);
result=Calu(str);
printf("输出计算结果: %f\n",result);
}
为了改进程序,我在主函数里加了一个循环:
int main()
{
int a;
printf(" ******欢迎进入小型计算器******\n 请输入算术表达式:");
for(a=0;;a++)
{
char str[N];
double result;
scanf("%s",str);
result=Calu(str);
printf("输出计算结果: %f\n",result);
printf("〉〉");
}
}
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++;
}
else if(exp1[index1]=='e') /*
exit(0);
else
Error();
}
四.程序运行结果
五.程序源代码
#include
#include
#include
#define N 100 /*N为数栈和表达式数组容量*/
#define M 100 /*M为符栈和其他数组容量*/
typedef struct /*定义运算符类型,level为运算符等级*/ {
char Type;
int level;
}Type; /*做一个Type用来存储运算符的优先级*/ typedef struct /*定义存放操作数的数栈*/
{
double stack[N];
int top;
}OdStack;
typedef struct /*定义存放运算符的符栈*/
{
Type stack[M];
int top;
}OpStack;
void Init_OdStack(OdStack *s) /*定义初始化数栈*/
{
(*s).top=0;
} //初始化栈顶,赋等级0值
void OdPush(OdStack *s,double n) /*进数栈*/
{
if((*s).top==N-1) /*如果栈满则报错退出程序*/ Error();
else
{
(*s).stack[(*s ).top]=n; //将数栈中的值变为n
(*s).top++; //栈顶的值加1
}
}
double OdPop(OdStack *s) /*定义出数栈*/
{
if ((*s).top==0) /*如果栈空则报错退出程序*/ Error();