首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

C语言用栈实现表达式求值,实在不知道程序有关问题出在哪了

2012-02-10 
C语言用栈实现表达式求值,实在不知道程序问题出在哪了?//用栈实现表达式求值#include iostream.h#includ

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]= '# '来判断循环是否继续执行??
………………
}

[解决办法]
还没仔细看代码
楼主先改改一些地方
比如楼上说的,判断循环那里

热点排行