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

有关四则运算的疑问,该如何处理

2012-03-21 
有关四则运算的疑问看了整整一夜,也没有找出来这段代码的错误在哪里?提示错误好像和事实上的差距很大,顺着

有关四则运算的疑问
看了整整一夜,也没有找出来这段代码的错误在哪里?
提示错误好像和事实上的差距很大,顺着那个提示什么也没有发现,改来改去还是不行;觉得函数的定义顺序和安排位置有问题,换来换去,错误提示变了,还是找不到下手的地方.
求助,请火眼金睛来帮忙看一下,错误在什么地方!!!谢谢
代码如下:
#include   <stdio.h>
#include   <stdlib.h>
#include   <string.h>
#include <malloc.h>
#define   TRUE   1
#define   FALSE   0
#define   OK   1
#define   ERROR   0
#define   OVERFLOW   -2
typedef   int   Status;
#define   STACK_INIT_SIZE   100   //存储空间初始分配量
#define   STACKINCREMENT   10     //存储空间分配增量
#define   OPSETSIZE   7;
typedef   struct{
float   *base;
float   *top;
int   stacksize;
}   StackFloat;
typedef   struct{
char   *base;
char   *top;
int   stacksize;
}   StackChar;
Status   InitStack   (StackFloat   &OPND){
OPND.base=(float   *)malloc(STACK_INIT_SIZE*sizeof(float));
if(!OPND.base)   exit(OVERFLOW);//存储分配失败
OPND.top=OPND.base;
OPND.stacksize=STACK_INIT_SIZE;
return   OK;
}//InitStack
Status   InitStack   (StackChar   &OPTR){
OPTR.base=(char   *)malloc(STACK_INIT_SIZE*sizeof(char));
if(!OPTR.base)   exit(OVERFLOW);//存储分配失败
OPTR.top=OPTR.base;
OPTR.stacksize=STACK_INIT_SIZE;
return   OK;
}//InitStack
float   GetTop(StackFloat   S){
//若栈不为空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
if(S.top==S.base)   return   ERROR;
float   e=*(S.top-1);
return   e;
}//GetTop
char   GetTop(StackChar   S){
//若栈不为空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
if(S.top==S.base)   return   ERROR;
char   e=*(S.top-1);
return   e;
}//GetTop
Status   Push(StackFloat   S,float   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;
return   OK;
}//Push
Status   Push(StackChar   S,char   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;
return   OK;
}//Push
Status   Pop(StackFloat   S,float   e){
//若栈不为空,则删除S的栈顶的元素,用e返回其值,并返回OK;否则返回ERROR
if(S.top==S.base)   return   ERROR;
e=*--S.top;
return   OK;
}//Pop
Status   Pop(StackChar   S,char   e){
//若栈不为空,则删除S的栈顶的元素,用e返回其值,并返回OK;否则返回ERROR
if(S.top==S.base)   return   ERROR;
e=*--S.top;
return   OK;
}//Pop

int   main()
{
unsigned   char   Prior[7][7]   =   {           //   表3.1     算符间的优先关系
        '> ', '> ', ' < ', ' < ', ' < ', '> ', '> ',
    '> ', '> ', ' < ', ' < ', ' < ', '> ', '> ',
    '> ', '> ', '> ', '> ', ' < ', '> ', '> ',
    '> ', '> ', '> ', '> ', ' < ', '> ', '> ',


    ' < ', ' < ', ' < ', ' < ', ' < ', '= ', '   ',
    '> ', '> ', '> ', '> ', '   ', '> ', '> ',
    ' < ', ' < ', ' < ', ' < ', ' < ', '   ', '= '
};
char   OPSET[OPSETSIZE]={ '+ '   ,   '- '   ,   '* '   ,   '/ '   , '( '   ,   ') '   ,   '# '};

bool   In(char   Test,char*   TestOp)   {
      bool   Find=false;
      for   (int   i=0;   i <   OPSETSIZE;   i++)   {
            if   (Test   ==   TestOp[i])   Find=   true;
      }
      return   Find;
}


Status   ReturnOpOrd(char   op,char   *TestOp)   {
      int   i;
      for(i=0;   i <   OPSETSIZE;   i++)   {
            if   (op   ==   TestOp[i])   return   i;
      }
}

char   precede(char   Aop,   char   Bop)   {
      return   Prior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)];
}

char   EvaluateExpression(char*   MyExpression)   {     //   算法3.4
      //   算术表达式求值的算符优先算法。
      //   设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合。
      StackChar     OPTR;         //   运算符栈,字符元素
      StackFloat   OPND;         //   运算数栈,实数元素
      char   TempData[20];
      float   Data,a,b;
      char   theta,*c,x,Dr[2];
     
      InitStack   (OPTR);
      Push   (OPTR,   '# ');
      InitStack   (OPND);
      c   =   MyExpression;
      strcpy(TempData, "\0 ");
      while   (*c!=   '# '   ||   GetTop(OPTR)!=   '# ')   {
            if   (!In(*c,   OPSET))   {
              Dr[0]=*c;
              Dr[1]= '\0 ';
                  strcat(TempData,Dr);
                  c++;
                  if(In(*c,OPSET))   {
                        Data=(float)atof(TempData);
                        Push(OPND,   Data);
                        strcpy(TempData, "\0 ");
                  }
            }   else   {       //   不是运算符则进栈
                  switch   (precede(GetTop(OPTR),   *c))   {  


                        case   ' < ':       //   栈顶元素优先权低
                                  Push(OPTR,   *c);    
                                  c++;
                                  break;
                        case   '= ':       //   脱括号并接收下一字符
                                  Pop(OPTR,   x);      
                                  c++;
                                  break;
                        case   '> ':       //   退栈并将运算结果入栈
                                  Pop(OPTR,   theta);
                                  Pop(OPND,   b);    
                                  Pop(OPND,   a);                                            
                                  Push(OPND,   Operate(a,   theta,   b));  
                                  break;
                  }   //   switch
            }
      }   //   while
      return   GetTop(OPND);
}   //   EvaluateExpression

float   Operate(float   a,unsigned   char   theta,   float   b)   {
      switch(theta)   {
            case   '+ ':   return   a+b;
            case   '- ':   return   a-b;
            case   '* ':   return   a*b;
            case   '/ ':   return   a/b;
            default   :   return   0;
      }  
}
//float   Operate(float   a,   unsigned   char   theta,   float   b);
//bool   In(char   Test,char*   TestOp);
//char   precede(char   Aop,   char   Bop);


printf( "请输入一个四则运算表达式:\n ");
char*   MyExpression=new   char[2*OPSETSIZE];
scanf( "%s ",MyExpression);
EvaluateExpression(MyExpression);
return   0;
}





[解决办法]
下面的程序可以编译,但逻辑上肯定有错,自已慢慢的去追踪调试.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW_ -2
typedef int Status;
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
#define OPSETSIZE 7//;
typedef struct{
float *base;
float *top;
int stacksize;
} StackFloat;
typedef struct{
char *base;
char *top;
int stacksize;
} StackChar;
Status InitStack (StackFloat &OPND){
OPND.base=(float *)malloc(STACK_INIT_SIZE*sizeof(float));
if(!OPND.base) exit(OVERFLOW);//存储分配失败
OPND.top=OPND.base;
OPND.stacksize=STACK_INIT_SIZE;
return OK;
}//InitStack
Status InitStack (StackChar &OPTR){
OPTR.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));
if(!OPTR.base) exit(OVERFLOW);//存储分配失败
OPTR.top=OPTR.base;
OPTR.stacksize=STACK_INIT_SIZE;
return OK;
}//InitStack
float GetTop(StackFloat S){
//若栈不为空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
if(S.top==S.base) return ERROR;
float e=*(S.top-1);
return e;
}//GetTop
char GetTop(StackChar S){
//若栈不为空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
if(S.top==S.base) return ERROR;
char e=*(S.top-1);
return e;
}//GetTop
Status Push(StackFloat S,float 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;
return OK;
}//Push
Status Push(StackChar S,char 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;
return OK;
}//Push
Status Pop(StackFloat S,float e){
//若栈不为空,则删除S的栈顶的元素,用e返回其值,并返回OK;否则返回ERROR
if(S.top==S.base) return ERROR;
e=*--S.top;
return OK;
}//Pop
Status Pop(StackChar S,char e){
//若栈不为空,则删除S的栈顶的元素,用e返回其值,并返回OK;否则返回ERROR
if(S.top==S.base) return ERROR;
e=*--S.top;
return OK;
}//Pop

char EvaluateExpression(char* MyExpression) ;
bool In(char Test,char* TestOp);
Status ReturnOpOrd(char op,char *TestOp);
char precede(char Aop, char Bop);
float Operate(float a,unsigned char theta, float b);

unsigned char Prior[7][7] = { // 表3.1 算符间的优先关系
'> ', '> ', ' < ', ' < ', ' < ', '> ', '> ',
'> ', '> ', ' < ', ' < ', ' < ', '> ', '> ',
'> ', '> ', '> ', '> ', ' < ', '> ', '> ',
'> ', '> ', '> ', '> ', ' < ', '> ', '> ',
' < ', ' < ', ' < ', ' < ', ' < ', '= ', ' ',
'> ', '> ', '> ', '> ', ' ', '> ', '> ',


' < ', ' < ', ' < ', ' < ', ' < ', ' ', '= '
};
char OPSET[OPSETSIZE]={ '+ ' , '- ' , '* ' , '/ ' , '( ' , ') ' , '# '};

int main()
{
printf( "请输入一个四则运算表达式:\n ");
char* MyExpression=new char[2*OPSETSIZE];
scanf( "%s ",MyExpression);
EvaluateExpression(MyExpression);
return 0;
}


bool In(char Test,char* TestOp) {
bool Find=false;
for (int i=0; i < OPSETSIZE; i++) {
if (Test == TestOp[i]) Find= true;
}
return Find;
}


Status ReturnOpOrd(char op,char *TestOp) {
int i;
for(i=0; i < OPSETSIZE; i++) {
if (op == TestOp[i])
return i;
}
return -1;//未匹配
}

char precede(char Aop, char Bop) {
return Prior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)];
}

char EvaluateExpression(char* MyExpression) { // 算法3.4
// 算术表达式求值的算符优先算法。
// 设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合。
StackChar OPTR; // 运算符栈,字符元素
StackFloat OPND; // 运算数栈,实数元素
char TempData[20];
float Data,a,b;
char theta,*c,x,Dr[2];

InitStack (OPTR);
Push (OPTR, '# ');
InitStack (OPND);
c = MyExpression;
strcpy(TempData, "\0 ");
while (*c!= '# ' || GetTop(OPTR)!= '# ') {
if (!In(*c, OPSET)) {
Dr[0]=*c;
Dr[1]= '\0 ';
strcat(TempData,Dr);
c++;
if(In(*c,OPSET)) {
Data=(float)atof(TempData);
Push(OPND, Data);
strcpy(TempData, "\0 ");
}
} else { // 不是运算符则进栈
switch (precede(GetTop(OPTR), *c)) {
case ' < ': // 栈顶元素优先权低
Push(OPTR, *c);
c++;
break;
case '= ': // 脱括号并接收下一字符
Pop(OPTR, x);
c++;
break;
case '> ': // 退栈并将运算结果入栈
Pop(OPTR, theta);
Pop(OPND, b);
Pop(OPND, a);
Push(OPND, Operate(a, theta, b));
break;
} // switch
}
} // while
return GetTop(OPND);
} // EvaluateExpression

float Operate(float a,unsigned char theta, float b) {
switch(theta) {
case '+ ': return a+b;
case '- ': return a-b;
case '* ': return a*b;
case '/ ': return a/b;
default : return 0;
}
}
[解决办法]
//* * * * * * * * * * * * * * * * * * * * * * * *
//*CHAPTER :3 (3_2) *
//*PROGRAM :表达式求值 *
//*CONTENT :堆栈的应用 *
//* * * * * * * * * * * * * * * * * * * * * * * *
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#define MAX 10 //定义堆栈最大容量
void push_opnd(char);//操作数堆栈入栈操作
float pop_opnd(); //操作数堆栈出栈操作
void push_optr(char);//操作符堆栈入栈操作
char pop_optr(); //操作符堆栈出栈操作
char relation(char,char);//比较两个操作符的优先级
float operate(float,char,float);//运算
float opnd[MAX]; //操作数堆栈


char optr[MAX]; //操作符堆栈
int topd=0; //栈顶指针初始化
int top=0;
char symb[30]; //表达式字符串
int main()
{int i=0;
char sy;
float a,b;
// textbackground(3); //设定屏幕颜色
// textcolor(15);
// clrscr();
//---------------------程序解说-----------------------
printf( "本程序实现表达式求值的操作。可以进行加减乘除运算。\n ");
printf( "这是堆栈应用的一个例子\n ");
//----------------------------------------------------
printf( "请输入表达式(以#结束):\n例如: 3*(3+2)/5#\n ");
push_optr( '# ');
gets(symb); //输入表达式,以#为结束符
while((symb[i]!= '# ')||(optr[top]!= '# '))
{if((symb[i]!= '+ ')&&(symb[i]!= '- ')&&(symb[i]!= '* ')&&(symb[i]!= '/ ')
&&(symb[i]!= '( ')&&(symb[i]!= ') ')&&(symb[i]!= '# ')&&(symb[i]!= ' '))
{push_opnd(symb[i]);i++;} //如果当前字符不是操作符,则入操作数栈,字符串指针加一
else switch(relation(optr[top],symb[i])) //若是操作符,比较其和操作符栈的栈顶元素的优先级
{case ' < ':push_optr(symb[i]);i++;break; //若栈顶元素优先级低,则当前字符入栈,指针加一
case '= ':sy=pop_optr();i++; break; //若优先级相等,必为两个配对的括号,退栈,指针加一
case '> ':sy=pop_optr();b=pop_opnd(); //若优先级高,则栈顶元素退栈,进行运算
a=pop_opnd();
topd=topd+1;
opnd[topd]=operate(a,sy,b); //把运算结果入栈
break;
case ' ':printf( "语法错误!\n ");exit(0);
}
}
printf( "运算结果=%1.2f\n ",opnd[topd]);
// system( "pause ");
printf( "程序结束,按任意键退出!\n ");
getch();
return 0;
}
void push_opnd(char ch)
{int ch_i;
ch_i=ch- '0 '; //把字符换算成数字,并入操作数栈
topd++;
opnd[topd]=ch_i;
}
float pop_opnd()
{//操作数栈出栈
topd=topd-1;
return opnd[topd+1];
}
void push_optr(char ch)
{//操作符入栈
top++;
optr[top]=ch;
}
char pop_optr()
{//操作数出栈
top--;
return optr[top+1];
}
char relation(char sym1,char sym2)
{//比较两个操作符的优先级
int i;
char chl[2];
int ind[2];
char re[7][7]={ '> ', '> ', ' < ', ' < ', ' < ', '> ', '> ',
'> ', '> ', ' < ', ' < ', ' < ', '> ', '> ',
'> ', '> ', '> ', '> ', ' < ', '> ', '> ',
'> ', '> ', '> ', '> ', ' < ', '> ', '> ',
' < ', ' < ', ' < ', ' < ', ' < ', '= ', ' ',
'> ', '> ', '> ', '> ', ' ', '> ', '> ',
' < ', ' < ', ' < ', ' < ', ' < ', ' ', '= '};
chl[0]=sym1;
chl[1]=sym2;
for(i=0;i <=1;i++)
{switch(chl[i])
{case '+ ':ind[i]=0;break;
case '- ':ind[i]=1;break;
case '* ':ind[i]=2;break;
case '/ ':ind[i]=3;break;
case '( ':ind[i]=4;break;
case ') ':ind[i]=5;break;
case '# ':ind[i]=6;break;
default:printf( "Error!\n ");return( '0 ');
}
}
return(re[ind[0]][ind[1]]);
}
float operate(float a,char sym,float b)
{//进行运算
float re;
switch(sym)
{case '+ ':re=a+b;break;
case '- ':re=a-b;break;


case '* ':re=a*b;break;
case '/ ':re=a/b;break;
default:printf( "Error!\n ");return(0);
}
return re;
}


以上代码我编译通过的,你可以看看.

热点排行