主题:[讨论]求站内高手帮忙看下程序中的错误,急急急!!!
xpz445094213xpz
[专家分:0] 发布于 2010-04-06 16:15:00
/*我编的这个程序是用链栈求表达式的值,但是有错误没能找出来,求站内大侠指点,可加QQ445094213随时指导,希望经常交流学习心得*/
[code=c]
请填写代码
[/code]
/*此为头文件*/
#include<stdio.h>
#include<malloc.h>
typedef struct node
{
char data;
struct node *next;
}LinkStackNode,*LinkStack;
void InitStack(LinkStack *S)
{
*S=(LinkStack)malloc(sizeof(LinkStackNode));
(*S)->next=NULL;
}/*链栈初始化*/
LinkStack Push(LinkStack top,char x)
{
LinkStackNode *temp;
temp=(LinkStackNode *)malloc(sizeof(LinkStackNode));
if(temp==NULL)return 0;
temp->data=x;
temp->next=top->next;
top->next=temp;
return top;
}/*链栈元素的入栈*/
LinkStack Pop(LinkStack top,char *x)
{
LinkStackNode *temp;
temp=top->next;
if(temp==NULL)return 0;
top->next=temp->next;
*x=temp->data;
free(temp);
return top;
}/*链栈元素的出栈*/
/*以下为算法实现代码*/
#include<stdio.h>
#include"stack.h"
char GetTop(LinkStack S)
{
if(S->next!=NULL)return (S->next->data);
else return 0;
}/*取栈顶元素函数*/
int In(char ch)
{
if(ch>='0' && ch<='9')
return 0;
else
return 1;
} /*判断读入的字符是否是运算数*/
int GetNumber(char a)
{
int n=0;
do{
n=n*10+(a-'0');
a=getchar();
}while(!In(a));
return n;
} /*将读入的运算数各位数码转化成十进制数*/
char Compare(char s,char a)
{
int i,j;
char A[5]={'+','-','*','/','#'};
char B[5][5]={'>','>','<','<','>'
,'>','>','<','<','>'
,'>','>','>','>','>'
,'>','>','>','>','>'
,'<','<','<','<','='};
for(i=0;i<5;i++)
if(s==A[i])
break;
for(j=0;j<5;j++)
if(a==A[j])
break;
return B[i][j];
} /*比较运算符优先级*/
int Execute(int a,char op,int b)
{
switch(op)
{
case '+':return a+b;break;
case '-':return a-b;break;
case '*':return a*b;break;
case '/':return a/b;break;
}
} /*对a和b进行op运算*/
int ExpEvaluation()
{
char ch,op,a,b;
char n,v;
LinkStack OVS,OPTR;
InitStack(&OVS);
InitStack(&OPTR);
Push(OPTR,'#');
printf("请输入一个表达式串(以#结尾):");
ch=getchar();
while(ch!='#'||GetTop(OPTR)!='#') /*当读入的字符和OPTR栈顶字符韵味#时结束运算*/
{
if(!In(ch))
{
n=GetNumber(ch);
Push(OVS,n);
}
else
switch(Compare(GetTop(OPTR),ch))
{
case '<': /*栈顶运算符优先级比刚读入运算符优先级低时*/
Push(OPTR,ch); /*将刚读入的运算符进运算符栈*/
ch=getchar(); /*继续读入下一个运算符*/
break;
case '>':
case '=': /*栈顶运算符优先级比刚读入运算符优先级高或相等时*/
Pop(OPTR,&op); /*退栈得到当前最优先运算符*/
Pop(OVS,&b); /*退栈得到op第二个运算数*/
Pop(OVS,&a); /*退栈得到op第一个运算数*/
v=Execute(a,op,b); /*对a和b进行op运算*/
Push(OVS,v);
break;
}
}
v=GetTop(OVS);
return v;
}
main()
{
printf("表达式的值是%d",ExpEvaluation());
}
最后更新于:2010-04-07 07:35:00
回复列表 (共14个回复)
沙发
rtygbwwwerr [专家分:910] 发布于 2010-04-06 17:42:00
主要问题出在ExpEvaluation()中的这一行
n=GetNumber(ch);
而楼主的GetNumber函数是这样定义的:
int GetNumber(char a)
{
int n=0;
do{
n=n*10+(a-'0');
a=getchar(); //这里虽然改变了a的值,但由于使用的是传值调用不会改变实
//参ch的值
}while(!In(a));
return n;
}
应把参数类型改为char &a这样传入实参ch的值就会同步改变了。
板凳
xpz445094213xpz [专家分:0] 发布于 2010-04-07 07:28:00
n=n=GetNumber(&ch);和函数体GetNumber(*a);都改过了,但还是不行
其实最新我用的就是这种改变形参值的形式,但是我并不是要返回ch的值,因为每次只能输入一个字符,但是如果输入的是一个两位数或者三位数或者更高的位数,那么就只能每输入一个数就n=n*10+(*a);*a=getchar();,最终返回的并不是ch,而是return n;也就是说并不需要改变ch的值,所以就没有用改变形参值的形式
3 楼
雪光风剑 [专家分:27190] 发布于 2010-04-07 08:20:00
我觉得这段程序我不太能理解你为什么要用这样的思路实现……
又要逐字符的读,又是在函数里进行连续处理,这样造成了很多处理问题……
不能读个完整字符串然后对这个字符串进行逐字符分析么…………
4 楼
rtygbwwwerr [专家分:910] 发布于 2010-04-07 09:39:00
楼主注意了,这里有个问题,如果不同步改变ch的值,程序将无限循环。
比如我输入 1+2# ,程序执行是这样的:
1.由于是数字所以执行分支if(!In(ch)){...},然后第一趟循环结束。但是ch的值(仍然为1)没有被改变,所以第二次循环时将重复执行分支if(!In(ch)){...},然后是第三次循环继续重复...
5 楼
rtygbwwwerr [专家分:910] 发布于 2010-04-07 09:42:00
以下是我修改后的程序,经调试可以运行:
/*此为头文件*/
#include<stdio.h>
#include<malloc.h>
typedef struct node
{
char data;
struct node *next;
}LinkStackNode,*LinkStack;
void InitStack(LinkStack *S)
{
*S=(LinkStack)malloc(sizeof(LinkStackNode));
(*S)->next=NULL;
}/*链栈初始化*/
LinkStack Push(LinkStack top,char x)
{
LinkStackNode *temp;
temp=(LinkStackNode *)malloc(sizeof(LinkStackNode));
if(temp==NULL)return 0;
temp->data=x;
temp->next=top->next;
top->next=temp;
return top;
}/*链栈元素的入栈*/
LinkStack Pop(LinkStack top,char *x)
{
LinkStackNode *temp;
temp=top->next;
if(temp==NULL)return 0;
top->next=temp->next;
*x=temp->data;
free(temp);
return top;
}/*链栈元素的出栈*/
char GetTop(LinkStack S)
{
if(S->next!=NULL)return (S->next->data);
else return 0;
}/*取栈顶元素函数*/
int In(char ch)
{
if(ch>='0' && ch<='9')
return 0;
else
return 1;
} /*判断读入的字符是否是运算数*/
int GetNumber(char* a)
{
int n=0;
do{
n=n * 10 + (*a-'0');
*a=getchar();
}while(!In(*a));
return n;
} /*将读入的运算数各位数码转化成十进制数*/
char Compare(char s,char a)
{
int i,j;
char A[5]={'+','-','*','/','#'};
char B[5][5]={'>','>','<','<','>'
,'>','>','<','<','>'
,'>','>','>','>','>'
,'>','>','>','>','>'
,'<','<','<','<','='};
for(i=0;i<5;i++)
if(s==A[i])
break;
for(j=0;j<5;j++)
if(a==A[j])
break;
return B[i][j];
} /*比较运算符优先级*/
int Execute(int a,char op,int b)
{
switch(op)
{
case '+':return a+b;break;
case '-':return a-b;break;
case '*':return a*b;break;
case '/':return a/b;break;
}
} /*对a和b进行op运算*/
int ExpEvaluation()
{
char ch,op,a,b;
char n,v;
LinkStack OVS,OPTR;
InitStack(&OVS);
InitStack(&OPTR);
Push(OPTR,'#');
printf("Please input a char(end of '#'):");
ch=getchar();
while(ch!='#'||GetTop(OPTR)!='#')
{
if(!In(ch))
{
n = GetNumber(&ch);
Push(OVS,n);
}
else
{
switch(Compare(GetTop(OPTR),ch))
{
case '<': /*栈顶运算符优先级比刚读入运算符优先级低时*/
Push(OPTR,ch); /*将刚读入的运算符进运算符栈*/
ch=getchar(); /*继续读入下一个运算符*/
break;
case '>':
case '=': /*栈顶运算符优先级比刚读入运算符优先级高或相等时*/
Pop(OPTR,&op); /*退栈得到当前最优先运算符*/
Pop(OVS,&b); /*退栈得到op第二个运算数*/
Pop(OVS,&a); /*退栈得到op第一个运算数*/
v=Execute(a,op,b); /*对a和b进行op运算*/
Push(OVS,v);
break;
}
}
//ch=getchar();
}
v=GetTop(OVS);
return v;
}
main()
{
printf("表达式的值是%d",ExpEvaluation());
}
6 楼
rtygbwwwerr [专家分:910] 发布于 2010-04-07 09:48:00
还有,楼主把node中的data定义为char类型,将导致计算结果在-128 ~ 127之间,超过这个值将会溢出。
7 楼
xpz445094213xpz [专家分:0] 发布于 2010-04-07 18:19:00
有个问题我想问一下,为什么用头文件就不能运行处结果,而把头文件放入整个程序中可以运行处结果
8 楼
rtygbwwwerr [专家分:910] 发布于 2010-04-07 22:03:00
lz的意思是?
9 楼
xpz445094213xpz [专家分:0] 发布于 2010-04-08 10:52:00
我的意思是说,我原先的代码是把
#include<stdio.h>
#include<malloc.h>
typedef struct node
{
char data;
struct node *next;
}LinkStackNode,*LinkStack;
void InitStack(LinkStack *S)
{
*S=(LinkStack)malloc(sizeof(LinkStackNode));
(*S)->next=NULL;
}/*链栈初始化*/
LinkStack Push(LinkStack top,char x)
{
LinkStackNode *temp;
temp=(LinkStackNode *)malloc(sizeof(LinkStackNode));
if(temp==NULL)return 0;
temp->data=x;
temp->next=top->next;
top->next=temp;
return top;
}/*链栈元素的入栈*/
LinkStack Pop(LinkStack top,char *x)
{
LinkStackNode *temp;
temp=top->next;
if(temp==NULL)return 0;
top->next=temp->next;
*x=temp->data;
free(temp);
return top;
}/*链栈元素的出栈*/
放入头文件,然后在算法实现是再调用这个头文件#include"stack.h"
为什么这样做得不出结果,而把"stack.h"头文件里的内容和算法实现的代码放在一起时能够运行呢
10 楼
rtygbwwwerr [专家分:910] 发布于 2010-04-08 11:05:00
lz用的什么编译器
我来回复