C语言用栈实现表达式求值,实在不知道程序问题出在哪了?
//用栈实现表达式求值
#include <iostream.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <process.h> // exit()
#include <float.h>
#define STACK_INIT_SIZE 100 //栈的最大长度
#define STACKINCREMENT 10 //栈的长度的增量
typedef struct //定义float数字栈类型
{
float *base;
float *top;
int stacksize;
}SqStack_float;
typedef struct //定义char字符栈类型
{
char *base;
char *top;
int stacksize;
}SqStack_char;
char opnd[10]={ '0 ', '1 ', '2 ', '3 ', '4 ', '5 ', '6 ', '7 ', '8 ', '9 '};//操作数字符集合
char optr[7]={ '+ ', '- ', '* ', '/ ', '( ', ') ', '# '}; //运算符字符集合
char priority[7][7]= //优先权集合
{ { '> ', '> ', ' < ', ' < ', ' < ', '> ', '> '},
{ '> ', '> ', ' < ', ' < ', ' < ', '> ', '> '},
{ '> ', '> ', '> ', '> ', ' < ', '> ', '> '},
{ '> ', '> ', '> ', '> ', ' < ', '> ', '> '},
{ ' < ', ' < ', ' < ', ' < ', ' < ', '= ', '@ '},
{ '> ', '> ', '> ', '> ', '@ ', '> ', '> '},
{ ' < ', ' < ', ' < ', ' < ', ' < ', '@ ', '= '} };
//函数声明
void InitStack(SqStack_float &S); //初始化一个数字栈
void InitStack(SqStack_char &S); //初始化一个字符栈
void Push(SqStack_float S,float e); //将数字e进栈
void Push(SqStack_char S,char e); //将字符e进栈
void Pop(SqStack_float S,float e); //数字e出栈
void Pop(SqStack_char S,char e); //字符e出栈
float GetTop(SqStack_float S); //返回数字栈栈顶元素
char GetTop(SqStack_char S); //返回字符栈栈顶元素
int In(char e); //判断字符e是否属于字符集合
char Precede(char e,char c); //比较两个字符的优先级,并返回
float Operate(float a,char e,float b); //将a和b进行e字符代表的运算,并返回
bool IsLegal(char a[]); //判断输入的表达式是否合法
void main()
{
SqStack_char OPTR; InitStack(OPTR); Push(OPTR, '# ');
SqStack_float OPND; InitStack(OPND);
char c= ' ',x= ' ',theta= ' ';
float a=0.0,b=0.0,e=0.0;
int i;
char expr[80];
gets(expr);
while(!IsLegal(expr)) //判断直到输入的表达式合法
{
gets(expr);
}
printf( "程序运行到这里1\n ");
c=expr[0]; i=0;
while(GetTop(OPTR)!= '# ')
{
printf( "程序运行到这里2\n ");
if(In(c)==1)
{
e=atof(&c);
while(In(c)==1) //判断数字位数是否超过个位
{
e=10*e+atof(&c);
i++; c=expr[i];
}
Push(OPND,e);
//printf( "ddd\n ");
//i++;
//c=expr[i];
}
printf( "程序运行到这里3\n ");
if(In(c)==0)
{
switch(Precede(GetTop(OPTR),c))
{
case ' < ':
Push(OPTR,c); i++; c=expr[i];
break;
case '= ':
Pop(OPTR,x); i++; c=expr[i];
break;
case '> ':
Pop(OPTR,theta);
Pop(OPND,b);Pop(OPND,a);
Push(OPND,Operate(a,theta,b));
break;
}
}
}
printf( "%f ",GetTop(OPND));
printf( "程序运行到这里4\n ");
}
void InitStack(SqStack_float &S) //初始化一个数字栈
{
S.base=(float*)malloc(STACK_INIT_SIZE*sizeof(float));
//if(!S.base) exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
//return S;
}
void InitStack(SqStack_char &S) //初始化一个数字栈
{
S.base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));
//if(!S.base) exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
//return S;
}
void Push(SqStack_char S,char e) //在字符栈中字符e进栈
{
if(S.top-S.base> =S.stacksize)
{
S.base=(char*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));
//if(!S.base)exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
}
void Push(SqStack_float S,float e) //在数字栈中数字e进栈
{
if(S.top-S.base> =S.stacksize)
{
S.base=(float*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(float));
//if(!S.base)exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
}
void Pop(SqStack_char S,char e) //在字符栈中字符e出栈
{
if(S.top==S.base) cout < < "空栈不能删除! " < <endl;
else e=*--S.top;
}
void Pop(SqStack_float S,float e) //在数字栈中数字e出栈
{
if(S.top==S.base) cout < < "空栈不能删除! " < <endl;
else e=*--S.top;
}
char GetTop(SqStack_char S) //返回字符栈栈顶元素
{
//if(S.top==S.base)
char e=*(S.top-1);
return e;
}
float GetTop(SqStack_float S) //返回数字栈栈顶元素
{
//if(S.top==S.base)
float e=*(S.top-1);
return e;
}
int In(char e) //判断字符e是否属于运算符字符、操作数字符集合
{
int i;
for(i=0;i <7;i++)
{
if(e==optr[i]) return 0;//属于运算符字符集合
}
for(i=0;i <7;i++)
{
if(e==opnd[i]) return 1;//属于操作数字符集合
}
return -1;
}
char Precede(char e,char c) //比较两个字符的优先级
{
int i,j,k;
for(k=0;k <7;k++)
{
if(e==optr[k]) i=k;
if(c==optr[k]) j=k;
}
return priority[i][j];
}
float Operate(float a,char e,float b) //运算并返回结果
{ float value;
switch(e)
{
case '+ ':
value=a+b; break;
case '- ':
value=a-b; break;
case '* ':
value=a*b; break;
case '/ ':
value=a/b; break;
default: break;
}
return value;
}
bool IsLegal(char a[]) //判断表达式是否合法
{
int i,j;
for(i=0,j=i+1;a[j]= '# ';i++,j=i+1)
{
if(In(a[i])!=0&&In(a[i])!=1)
{
printf( "表达式不合法,请重新输入\n ");
return false;
}
if((a[i]== '+ '||a[i]== '- '||a[i]== '* '||a[i]== '/ ')&&(a[j]== ') '||a[j]== '# '))
{
printf( "表达式不合法,请重新输入\n ");
return false;
}
if(a[i]== '( '&&(a[j]== '+ '||a[j]== '- '||a[j]== '* '||a[j]== '/ '||a[j]== '# '))
{
printf( "表达式不合法,请重新输入\n ");
return false;
}
}
return true;
}
IsLegal函数执行有问题,当第一个字符非法时能判断出来,但是若第一个字符合法,后面的字符不管是什么,都无法判断。
如果,屏蔽这一段,main函数的执行也有问题,程序调用Precede函数失败,编译时,黄色箭头指向Precede函数的return priority[i][l];语句,同时,系统说evaluate.exe遇到问题需要关闭
和同学讨论N久,实在无能为力了,请高手帮看一下,感激~~
[解决办法]
先问一下,用的什么编译器。c语言和c++混着了
[解决办法]
char Precede(char e,char c) //比较两个字符的优先级
{
int i,j,k;
for(k=0;k <7;k++)
{
if(e==optr[k]) i=k;
if(c==optr[k]) j=k;
}
return priority[i][j];//如果e,c不存在与optr[k]中,i,j将不会被赋值而直接使用了。
}
bool IsLegal(char a[]) //判断表达式是否合法
{
int i,j;
for(i=0,j=i+1;a[j]= '# ';i++,j=i+1) //你用a[j]= '# '来判断循环是否继续执行??
………………
}
[解决办法]
还没仔细看代码
楼主先改改一些地方
比如楼上说的,判断循环那里