回 帖 发 新 帖 刷新版面

主题:[讨论]求站内高手帮忙看下程序中的错误,急急急!!!

/*我编的这个程序是用链栈求表达式的值,但是有错误没能找出来,求站内大侠指点,可加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());
    
}

回复列表 (共14个回复)

沙发


主要问题出在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的值就会同步改变了。

板凳


n=n=GetNumber(&ch);和函数体GetNumber(*a);都改过了,但还是不行
其实最新我用的就是这种改变形参值的形式,但是我并不是要返回ch的值,因为每次只能输入一个字符,但是如果输入的是一个两位数或者三位数或者更高的位数,那么就只能每输入一个数就n=n*10+(*a);*a=getchar();,最终返回的并不是ch,而是return n;也就是说并不需要改变ch的值,所以就没有用改变形参值的形式

3 楼

我觉得这段程序我不太能理解你为什么要用这样的思路实现……
又要逐字符的读,又是在函数里进行连续处理,这样造成了很多处理问题……

不能读个完整字符串然后对这个字符串进行逐字符分析么…………

4 楼

楼主注意了,这里有个问题,如果不同步改变ch的值,程序将无限循环。
比如我输入 1+2# ,程序执行是这样的:
1.由于是数字所以执行分支if(!In(ch)){...},然后第一趟循环结束。但是ch的值(仍然为1)没有被改变,所以第二次循环时将重复执行分支if(!In(ch)){...},然后是第三次循环继续重复...

5 楼

以下是我修改后的程序,经调试可以运行:
/*此为头文件*/
#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 楼

还有,楼主把node中的data定义为char类型,将导致计算结果在-128 ~ 127之间,超过这个值将会溢出。

7 楼


有个问题我想问一下,为什么用头文件就不能运行处结果,而把头文件放入整个程序中可以运行处结果

8 楼

lz的意思是?

9 楼


我的意思是说,我原先的代码是把
#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 楼

lz用的什么编译器

我来回复

您尚未登录,请登录后再回复。点此登录或注册