有关四则运算的疑问
看了整整一夜,也没有找出来这段代码的错误在哪里?
提示错误好像和事实上的差距很大,顺着那个提示什么也没有发现,改来改去还是不行;觉得函数的定义顺序和安排位置有问题,换来换去,错误提示变了,还是找不到下手的地方.
求助,请火眼金睛来帮忙看一下,错误在什么地方!!!谢谢
代码如下:
#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;
}
以上代码我编译通过的,你可以看看.