Код перестает работать после нажатия любого числа свыше 127 в стеке - PullRequest
0 голосов
/ 29 ноября 2018

Программа на C!

Для домашней работы мне нужно было создать программу, которая находит значение арифметического выражения, заданного в префиксе, с помощью стека ADT.Входные данные представляют собой строку, например «- + 5 12 * 7 3», а выходные данные будут «-4».

Я решил домашнюю работу и решил, что все работает нормально.Но по какой-то причине, когда я помещаю число в верхнюю часть стека и если число больше или равно 128, или меньше или равно -128, число полностью изменяется после того, как оно помещено в стек.Например, если я нажимаю 129 в стеке, когда я получаю число сверху, оно меняется на -127.

Программа содержит более 150 строк кода, поэтому я не знаю, насколько полезным будетесли бы я разместил это здесь, мне просто любопытно, если у кого-то есть идея, почему это происходит.

(Вот краткая идея моей программы: input - это строка, в которой числа и операторы разделены пробелами.

Программа, которая оценивает инфикс, выглядит так: начинайте с символа вконец строки и переходите от конца к началу. Если char - это число, сначала найдите целое число (до пробела), а затем поместите его в стек (как int, а не как char). Если char - оператор, удалите последние двачисла из стека и выполнить операцию над ними, а затем поместить их обратно в стек. Последним числом в стеке является результат.

Я знаю, что это действительно расплывчато, поэтому, если вся программа поможет больше, я будуопубликуйте его. Все операции правильные, я проверил, проблема возникает, когда я помещаю их в стек. Кроме того, я реализовал строку, используя указатели.)

РЕДАКТИРОВАТЬ: вместо «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]='\0';
            break;
        }
        niz=(char*)realloc(niz, (++n)*sizeof(char));
        niz[n-1]=c;
    }
    izracunaj(niz,n-2);
    return 0;
}

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Возможно, вы храните значения как int, но они усекаются до char значений, когда вы помещаете их в стек и выводите из него.

void StPush(stack *Sp, char d)
char StTop(stack S)
0 голосов
/ 29 ноября 2018

Правила гласят, что нужно опубликовать фрагмент кода по уважительной причине: трудно определить проблему, не увидев код.В будущем ВСЕГДА публикуйте что-то, чтобы посмотреть (и следовать правилам для фрагментов кода).

Но в этом случае, даже без этого, у меня есть довольно хорошее предположение о том, что происходит: переполнение со знаком8-битный тип.Либо в вашем стеке используется тип данных signed char (или эквивалентный), либо вы приводите где-нибудь такое значение.Возможно целочисленный разбор, который вы используете?

...