在 Stack Top 上推送任何超过 127 的数字后代码停止工作

Code stops working after pushing any number over 127 on Stack Top

C 语言程序!

为了我的家庭作业,我必须编写一个程序,使用 ADT Stack 查找前缀中给定的算术表达式的值。输入是一个字符串,例如'- + 5 12 * 7 3',输出将是'-4'。

我解决了作业,我认为一切正常。但出于某种原因,当我将数字压入堆栈顶部时,如果该数字大于或等于 128,或小于或等于 -128,则一旦压入堆栈,该数字就会完全改变。比如我把129压入栈中,当我从栈顶取数的时候,已经变成了-127.

该程序有超过 150 行代码,所以我不知道如果我 post 在这里编辑它会有多大帮助,我只是想知道是否有人知道为什么会这样。

(这里是我的程序的简要思路:输入是一个字符串,其中数字和运算符用空格分隔。

计算中缀的程序是这样的:从字符串末尾的字符开始,从尾到头。如果 char 是数字,首先找到整数(直到空白)然后将其压入堆栈(作为 int,而不是 char)。如果 char 是运算符,则从堆栈中删除最后两个数字并对它们执行操作,然后将其压回堆栈。堆栈中的最后一个数字是结果。

我知道这真的很模糊,所以如果整个程序能提供更多帮助,我会post。所有的操作都是正确的,我检查了一下,具体是我把它们放到stack上就出问题了。另外,我使用指针实现了字符串。)

编辑:我将输出改为“-4”,而不是“4”。我的错!

编辑:代码:(另外,我使用 int 作为我的数据类型。)

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>

typedef struct _element{
    int c;
    struct _element *next;
}element;

typedef element *stack;

void StMakeNull(stack *Sp){
    *Sp=NULL;
}

int StEmpty(stack S){
    if(S==NULL) return 1;
    else return 0;
}

void StPush(stack *Sp, char d){
    element *temp;
    temp=(*Sp);
    (*Sp)=(element*)malloc(sizeof(element));
    (*Sp)->c=d;
    (*Sp)->next=temp;
}

void StPop(stack *Sp){
    if(StEmpty(*Sp)) exit(202);
    else{
        element *temp;
        temp=(*Sp);
        (*Sp)=(*Sp)->next;
        free(temp);
    }
}

char StTop(stack S){
    if(StEmpty(S)) exit(202);
    return S->c;
}

int Jel_broj(char c){
    int d=c;
    if(d>=48 && d<=57)
        return 1;
    return 0;
}

int Jel_operator(char c){
    if(c=='+') return 1;
    else if(c=='-') return 2;
    else if(c=='*') return 3;
    else if(c=='/') return 4;
    else if(c=='^') return 5;
    return 0;
}

int pot(int n, int k){
    int l=1;
    while(k>0){
        l*=n;
        k--;
    }
    return l;
}

void izracunaj(char* niz, int n){
    int broj=0, pomocni, j, nn, b1, b2;
    stack S;
    StMakeNull(&S);
    while(n>=0){
        if(Jel_broj(niz[n])){
            broj=0; j=0; nn=n;
            while(Jel_broj(niz[nn])){
                j++;
                nn--;
            }
            nn=j;
            while(Jel_broj(niz[n-j+1])){
                pomocni=niz[n-j+1];
                broj=broj*10+(pomocni-'0');
                j--;
            }
            StPush(&S, broj);
            n=n-nn+1;
        }
        else if(Jel_operator(niz[n])){
            if(Jel_operator(niz[n])==1){
                b1=StTop(S);
                StPop(&S);
                b2=StTop(S);
                StPop(&S);
                StPush(&S, b1+b2);
            }
            else if(Jel_operator(niz[n])==2){
                b1=StTop(S);
                StPop(&S);
                b2=StTop(S);
                StPop(&S);
                StPush(&S, b1-b2);
            }
            else if(Jel_operator(niz[n])==3){
                b1=StTop(S);
                StPop(&S);
                b2=StTop(S);
                StPop(&S);
                StPush(&S, b1*b2);
            }
            else if(Jel_operator(niz[n])==4){
                b1=StTop(S);
                StPop(&S);
                b2=StTop(S);
                StPop(&S);
                StPush(&S, b1/b2);
            }
            else if(Jel_operator(niz[n])==5){
                b1=StTop(S);
                StPop(&S);
                b2=StTop(S);
                StPop(&S);
                StPush(&S, pot(b1,b2));
            }
        }
        n--;
    }
    printf("%d", StTop(S));
}

int main(){
    char *niz=NULL;
    int n=0;
    char c;
    while(1){
        scanf("%c", &c);
        if(c=='\n'){
            niz=(char*)realloc(niz, (++n)*sizeof(char));
            niz[n-1]='[=10=]';
            break;
        }
        niz=(char*)realloc(niz, (++n)*sizeof(char));
        niz[n-1]=c;
    }
    izracunaj(niz,n-2);
    return 0;
}

规则说 post 代码片段是有充分理由的:不看代码就很难确定问题。以后,总是 post 要看的东西(并遵守代码片段的规则)。

但在这种情况下,即使没有它,我也能很好地猜测发生了什么:8 位类型的有符号溢出。您的堆栈使用 signed char (或等效)数据类型,或者您正在某处强制转换为这样的值。可能是您使用的整数解析?

您可能将这些值存储为 int,但是当您将它们放入和取出堆栈时,它们会被截断为 char 值。

void StPush(stack *Sp, char d)
char StTop(stack S)