Kalkulator ONP w C tworzony przy użyciu stosu

0

Witam. Jestem studentem 1 roku informatyki. W ramach projektu mam za zadanie napisać kalkulator działający na bazie stosu. Program kompiluje, beż żadnych warningów, jednak nie wykonuje swojego zadania. Byłbym wdzięczny za wypisanie błędów jakie robię.

#include <stdlib.h>
#include <string.h>

struct stos
{
   int znak;
   struct stos* next;
};


//funkcja dodająca element

struct stos *push(struct stos *top, int liczba)
{
   struct stos *nowy = (struct stos *)
   malloc(sizeof(struct stos)); //rezerwacja pamieci

if(nowy != NULL) //sprawdza powodzenie rezerwacji pamieci
{
	nowy->znak=liczba; //wpisanie liczby z parametru
	nowy->next=top; //zapisanie adresu wskaznika stosu do next
	top= nowy; // nowy jest nowym szczytem - ustawienie na niego wskaznika top
}
return top;
}


//funkcja usuwająca element

int pop(struct stos **top)
{
int wynik= -1;
if(*top) // if(*top!= NULL) - to samo, sprawdza czy przekazany funkcji wskaznik stosu nie jest pusty
{
   wynik= (*top)->znak; //zapisuje wartosc z el na szczycie, ktory funkcja wyswietli na koncu
   struct stos *tmp = (*top)->next; //zapamietuje adres elementu next ze szczytowego
   free(*top); //usuniecie elementu szczytowego
   *top=tmp; // przypisanie adresu ze zmiennej tmp do szczytu stosu(nowego szczytu)	
}	
return wynik;		
}

//funkcja wyświetlajaca element

int peek(struct stos *top)
{
   if(top) //top!=NULL
    return top->znak; 
else {
   fprintf(stderr,"Stos nie istnieje.\n"); //jesli stos jest pusty to wyswietl napis
   return -1;
}
 }








int main() {
	
	
struct stos *top=NULL;

//Wprowadzenie wyrażenia
int i=0;	
char wyrazenie[]={"22+="}; // sposob wprowadzania do zmiany

//wyswietlenie wprowadzonego wyrażenia
puts("Wprowadzone wyrazenie: ");
while(wyrazenie[i])
{
   printf("%c",wyrazenie[i]);
   i++;
}

puts("\n");

//Sprawdzanie poszczególnych opcji

int j=0;
while(wyrazenie[j])//bedzie wykonywalo dopóki wyrazenia w tablicy będą różne od null
{
   if(wyrazenie[j]=='+') //dodawanie	
{
      int liczba1;
      liczba1=top->znak;
      pop(&top);
      int liczba2;
      liczba2=top->znak;
      pop(&top);
      int wynik;
      wynik=liczba1+liczba2;
      push(top,wynik);
}

    else if(wyrazenie[j]=='-') //odejmowanie	
{
      int liczba1;
      liczba1=top->znak;
      pop(&top);
      int liczba2;
      liczba2=top->znak;
      pop(&top);
      int wynik;
      wynik=liczba1-liczba2;
      push(top,wynik);
}

   else if(wyrazenie[j]=='*') //mnozenie	
{
      int liczba1;
      liczba1=top->znak;
      pop(&top);
      int liczba2;
      liczba2=top->znak;
      pop(&top);
      int wynik;
      wynik=liczba1*liczba2;
      push(top,wynik);
}

   else if(wyrazenie[j]='/') //dzielenie
{
      int liczba1;
      liczba1=top->znak;
      pop(&top);
      int liczba2;
      liczba2=top->znak;
      pop(&top);
      int wynik;
      wynik=liczba1/liczba2;
      push(top,wynik);
}

	
   else if(wyrazenie[j]=='=') //koniec ciagu znakow- wyswietlenie ostatniego (jedynego) elementu stosu	
{
      puts("wynik to:");
      peek(top);	
}

   else //liczba w tablicy- dodanie do stosu
{
      int do_zapisu;
      char do_zapisu1;
      wyrazenie[j]=do_zapisu1;
      do_zapisu=(int)do_zapisu1;
      push(top,do_zapisu);

}
j++;
}
	
return 0;
}
2
  1. Co to dokładnie znaczy nie wykonuje swojego zadania?
  2. Sformatuj kod.
1

Byłbym wdzięczny za wypisanie błędów jakie robię.

  • Nie formatujesz kodu, przez co jest on kompletnie nieczytelny.
  • Powtarzasz się wielokrotnie. Użyj funkcji zamiast wykonywać ten sam kod z tylko jedną różnicą - operacją.
1

**Atomem **w ONP / RPN (wolę angielski skrót, dla mnie jest intuicyjny) na pewno nie jest znak.
jest to jakaś **unia ** (podaję koncepcyjnie, potrzebuje na zewnątrz selektora), czyli dla Ciebie struct { x; union } }

union {
           int liczba;   // lub inny typ liczbowy
           char operator;
   }

Z impelmentacją stosu gwiazdka next też bym dyskutował.

0
Patryk27 napisał(a):
  1. Co to dokładnie znaczy nie wykonuje swojego zadania?
  2. Sformatuj kod.

Wyświetla tylko wpisany ciąg znaków, na tym program się kończy. Podejrzewam że ify się nie wykonują z jakiegoś powodu.

0
Th3Pr0 napisał(a):
Patryk27 napisał(a):
  1. Co to dokładnie znaczy nie wykonuje swojego zadania?
  2. Sformatuj kod.

Wyświetla tylko wpisany ciąg znaków, na tym program się kończy. Podejrzewam że ify się nie wykonują z jakiegoś powodu.

Kod jest strasznie zaplątany w niskopoziomowe historie (plus podany bez syntaxu C), zupełnie nie masz wyższego poziomu abstrakcji
NA PRZYKŁAD u Ciebie pop nie zwraca wartości.

Koło ratunkowe w postaci peek nie pomaga, tylko kieruje na nieczyste rozwiązania.

1

Zgadzam się ze wszystkim z poprzednikami, ale dla mnie perełką i prawdopodobną przyczyną błędów jest else:

else //liczba w tablicy- dodanie do stosu
{
  int do_zapisu;
  char do_zapisu1;
  wyrazenie[j]=do_zapisu1;
  do_zapisu=(int)do_zapisu1;
  push(top,do_zapisu);
}

Nie wiem co miałeś na myśli ale fragment

  char do_zapisu1;
  wyrazenie[j]=do_zapisu1;

jest totalnie bez sensu

0

Nie wiem co miałeś na myśli ale fragment

  char do_zapisu1;
  wyrazenie[j]=do_zapisu1;

jest totalnie bez sensu

Potrzebowałem rzutowania aby liczyć te chary, nie działało mi mi kiedy próbowałem rzutować element tablicy, więc spróbowałem przypisać ten element do zmiennej char i dopiero wtedy go zrzutować

0
AnyKtokolwiek napisał(a):

**Atomem **w ONP / RPN (wolę angielski skrót, dla mnie jest intuicyjny) na pewno nie jest znak.
jest to jakaś **unia ** (podaję koncepcyjnie, potrzebuje na zewnątrz selektora), czyli dla Ciebie struct { x; union } }

union {
           int liczba;   // lub inny typ liczbowy
           char operator;
   }

Z impelmentacją stosu gwiazdka next też bym dyskutował.

Tutaj kompletnie nie zrozumiałem :(

1

Dziwny ten Twój kod, nie potrafię go prześledzić, łatwiej napisać od nowa tę, w sumie łatwą funkcję, (stos, źródło: https://www.geeksforgeeks.org/implement-a-stack-using-singly-linked-list/)
Jest trochę niefajnie :) , bo stos jest globalną zmienną, ale to już łatwo poprawić.

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

struct Node{
    int data;
    struct Node * link;
};
struct Node * top;


void push(int data){

    struct Node * temp = malloc(sizeof(struct Node));
    if (!temp){
        printf("\nHeap Overflow\n");
        exit(1);
    }
    temp->data = data;
    temp->link = top;
    top = temp;
}


int isEmpty(){
    return top == NULL;
}


int peek() {
    if (!isEmpty())
        return top->data;
    else
    exit(1);
}

void pop(){
    struct Node * temp;
    if (top == NULL) {
        printf("\nStack Underflow\n");
        exit(1);
    }
    else {
    temp = top;
    top = top->link;
    temp->link = NULL;
    free(temp);
    }
}

void display() {
    struct Node * temp;
    if (top == NULL) {
        printf("\nStack Underflow\n");
        exit(1);
    }
    else {
        temp = top;
        while (temp != NULL) {
            printf("%d ", temp->data);
            temp = temp->link;
        }
    }
}

int evalONP(char s []) {
    // teraz trzeba stworzyć stos, ale używam globalnego top i to jest przykre:)
    for (int i = 0; i < strlen(s); ++i) {
        if (isdigit(s[i])) {
            int x = s[i] - '0';
            push(x);
        }
        if (s[i] == '+' || s[i] == '-'){
            int x = peek();
            pop();
            int y = peek();
            pop();
            if (s[i] == '+')
                push(x + y);
            if (s[i] == '-')
                push(y - x);
        }
    }
    int r = peek();
    pop();
    free(top);
    return r;
}
int main() {
    char expr [] = "22+3-";
    printf("%d\n", evalONP(expr)); // -> 1
    return 0;
}


3

Maksymalnie prosto, maksymalnie niebezpiecznie


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

typedef double opr(double a,double b);

double add(double a,double b) { return a+b; }
double sub(double a,double b) { return a-b; }
double mul(double a,double b) { return a*b; }
double ddv(double a,double b) { return a/b; }

struct { char op; opr *fun; } oprtb[]=
{
   { '+', &add },
   { '-', &sub },
   { '*', &mul },
   { '/', &ddv },
};
const size_t oprtbsize=sizeof(oprtb)/sizeof(*oprtb);

typedef struct _OnpStack
{
   double data[16];
   size_t pos;
} OnpStack;

void push(OnpStack *stack,double value)
{
   stack->data[stack->pos++]=value;
}

double pop(OnpStack *stack)
{
   return stack->data[--stack->pos];
}

int operation(OnpStack *stack,char ch)
{
   int i;
   for(i=0;i<oprtbsize;++i)
   {
      if(oprtb[i].op==ch)
      {
         double b=pop(stack);
         double a=pop(stack);
         push(stack,oprtb[i].fun(a,b));
         return 1;
      }
   }
   return 0; // brak takiej operacji
}

double calc(char *text)
{
   char ch,*ptr;
   OnpStack stack={{0},0};
   while(*text)
   {
      char ch=*text;
      if(isspace(ch)) ++text;
      else
      {
         double value=strtod(text,&ptr);
         if(ptr>text)
         {
            push(&stack,value);
            text=ptr;
         }
         else
         {
            operation(&stack,ch); // sprawdzić czy znaleziono taki operator
            ++text;
         }
      }
   }
   double value=pop(&stack); // sprawdzić czy po operacji stos pusty
   return value;
}

int main()
{
   printf("3*(-5+7) = %lf\n",calc("3 -5 7 + *"));
   return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1