[Ansi C] Implementacja stosu (na liście)

0

Witam,
Zaimplementowałam stos na liście, jednak mam problem - program się kompiluje bez błędów, ale po uruchomieniu od razu się wywala (gdy wywołuję funkcję pop):

typedef struct wezel
{
   int liczba;
   struct wezel * nast;
} Wezel;

void MakeEmpty(Wezel* stos)
{
     stos=NULL;
}
//**********************************************
bool Push(Wezel* stos, int x)
{
     Wezel* biezacy;
     if((biezacy=(Wezel*)malloc(sizeof(Wezel)))==NULL)
        return false;
     else
     {  
        stos->liczba=x;
        biezacy->nast=stos;
        stos=biezacy;
         
     }  
     return true;
}
//**********************************************
int top(Wezel* stos)
{
    if(stos==NULL)
       printf("Stos jest pusty! /n");
    else
       return (stos->liczba);
}
//**********************************************
int pop(Wezel* stos)
{
    int zwroc;
    Wezel* tmp;
    zwroc=stos->liczba;
    tmp=stos;
    stos=tmp->nast;
    free(tmp);
    return zwroc;
}

Czy mógłby ktoś mi pomóc, bo nie mam pojęcia co jest źle. Dziękuję z góry:)

0

Co robi funkcja MakeEmpty ? Przeciez stos ustawi sie na null samoczynnie jak zdejmiesz ostatni element (bo on przeciez wskazuje na Null ;]

A gdzie sprawdzasz czy stos nie jest pusty?
Możesz dopisać sobie funkcje

bool empty(Wezel* stos)
{
return stos;
}

Albo sprawdzać przed wywołaniem pop() if(stos) bo próba zdjęcia czegoś z NULLa źle sie skończy ;]
"Z pustego stosu i Salomon nie zdejmie" jak mawia jeden z moich wykładowców ;P

0

Hej,
funkcja MakeEmpty ma za zadanie zainicjalizowac pusty stos - wyzerowac wskaźnik na poczatku (ćwiczeniowiec mi tak kazał).

Jakoś dziwnie napisałeś ta funkcje empty, jak ona ma sprawdzac czy stos jest pusty jak zwracasz wskaznik na stos, a tak w ogóle to funkcja ma zwracac bool???
ja bym to zrobila tak:

bool IsEmpty(wezel *stos)
{
     if(stos==NULL)
        return true;
     else
        return false;
}

A tak w ogóle to tak czy siak mi ten program sie wywala, bo w sumie nie probowalam wczesniej zdejmowac z pustego stosu. Moze wkleje tu caly program:

typedef struct wezel {
        int liczba;
        wezel * nast;
        };
        
void makeempty(wezel* stos)
{
     stos=NULL;
}
bool IsEmpty(wezel *stos)
{
     if(stos==NULL)
        return true;
     else
        return false;
}
//**********************************************
bool push(wezel* stos, int x)
{
     wezel* biezacy;
     if((biezacy=(wezel*)malloc(sizeof(wezel)))==NULL)
        return false;
     else
     {  
        stos->liczba=x;
        biezacy->nast=stos;
        stos=biezacy;
         
     }  
     return true;
}
//**********************************************
int top(wezel* stos)
{
    if(stos==NULL)
       cout<<"Stos jest pusty!"<<endl;
    else
       return (stos->liczba);
}
//**********************************************
int pop(wezel* stos)
{
    if(IsEmpty(stos))
       cout<<"Stos jest pusty!"<<endl;
    
    int zwroc;
    wezel* tmp;
    zwroc=stos->liczba;
    tmp=stos;
    stos=tmp->nast;
    free(tmp);
    return zwroc;
}
//**********************************************
bool czy_cyfra(char i)
{
     if(i>47 && i<58)
        return true;
     else
        return false;
}
//**********************************************
int char_na_int(char i)
{
    if(czy_cyfra(i))
    {
       i=i-48;
       return i;
    }
} 
//**********************************************

main()
{
      wezel stos1;
      char i;
      int a,b,tmp=0;
      
      makeempty(&stos1);
      
      
      cout<<"Wpisz pierwsza liczbe. Dowolny inny znak różny od cyfry - KONIEC"<<endl;
      i=getchar();
      while(czy_cyfra(i))
      {
        
        i= char_na_int(i);
         push(&stos1,i);
         i=getchar();
      }
      
cout << pop(&stos1);
}

W mainie oczywiście obcielam troche, bo ten program ma sluzyc innym celom, niz tylko zrobienia stosu:P ale niestety kompiluje się ok, ale wywala sie, i to na tym pop-ie najprawdopodobniej.

Dziękuję za pomoc

0

Napisz może w prostszy sposób:

struct wezel {
	wezel *nast;
	int liczba;
};

bool push(wezel* &stos, int x)
{
	wezel* nowy;
	nowy = (wezel*)malloc(sizeof(wezel));
	if (!nowy) return false;

	nowy->liczba = x;
	nowy->nast = stos;
	stos = nowy;
	return true;
}

int pop(wezel* &stos)
{
	int x = 0;
	if (stos)
	{
		x = stos->liczba;
		wezel *old = stos;
		stos = stos->nast;
		free(old);
	}
	return x;
}

int main()
{
	wezel* stos = 0;
	push(stos, 5);
	push(stos, 7);

	cout << pop(stos);
	cout << pop(stos);
	cout << pop(stos);
	cout << pop(stos);
}
0

hej dziekuje ci bardzo - działa oczywiście;-)
Czyli jak zwykle dalej mam problem z wskaźnikami...

Mam jeszcze jedno ostatnie pytanie, pierwszy raz spotykam się z takim zapisem:

int pop(wezel* &stos)

znaczy sie gwiazdka i ampersand razem;-) co to w ogóle jest?? referencja?? czy jeszcze cos innego?

0

To jest referencja do wskaźnika.

0

już wszystko wiem! i dlaczego program mi nie dzialal;-) dzieki :D

0

A tak przy okazji, co do tej funkcji sprawdzajacej czy stos jest pusty, to ona nie zwracała wskaźnika tylko bool właśnie ;]
W c++ prawie wszystko mozna skonwertować na bool w ten sposób że jak wartość jest równa 0 to jest false, a jak różna od 0 to true.
Więc moja funkcja zwracała false jak stos byl pusty, a true jak coś na nim leżało ;)

0

sapero:
bool push(wezel* & stos, int x)
w ANSI C ?
oj, oj.. :)

autorze: zmien to sobie na ** i popraw reszte, zamin pokazesz to 'cwiczeniowcowi'..
oraz poza wlaczeniem sobie we flagach kompilacji zgodnosci z ansi, nazywaj pliki .c a nie .cpp czy .cc...

0
x = stos->liczba;
wezel *old = stos;

Czy przypadkiem nie jest tak, że w ANSI C zmienne muszą być robione na początku bloku??

0

A od kiedy w ANSI C jest bool?

0
manfredek napisał(a)
x = stos->liczba;
wezel *old = stos;

Czy przypadkiem nie jest tak, że w ANSI C zmienne muszą być robione na początku bloku??

jest

@autorze zmień sobie rozszerzenie pliku na *.c (zamiast *.cpp), bo nadal jedziesz w C++

0

@crayze, a nie sądzisz, że to było pytanie retoryczne?

0

Jeszcze cout zauważyłem... Komuś się języki poplątały?

Oj. Nie lubię C, ale masz gotowca (zgodny z ANSI C /a przynajmniej kompiluje się pod GCC z opcją -ansi/):

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

typedef struct tagNode
{
  int val;
  struct tagNode* next;
} node;

void push(node** stack, int data)
{
  node* nowy;
  nowy = (node*)malloc(sizeof(node));

  nowy->val = data;
  if(*stack)
  {
    nowy->next = *stack;
  }
  else
  {
    nowy->next = 0;
  }
  *stack = nowy;
}

int top(node** stack, int* retval)
{
  if(*stack)
  {
    *retval = (*stack)->val;
    return 1;
  }
  return 0;
}

void pop(node** stack)
{
  if(*stack)
  {
    node* ptr;
    ptr = *stack;
    *stack = (*stack)->next;
    free(ptr);
  }
}

int empty(node** stack)
{
  return !(*stack);
}

int main()
{
  node* stos = 0;
  int data;
  int i;
  push(&stos, 69);
  push(&stos, 666);
  for(i = 1; ;i++)
  {
    if(!top(&stos, &data))
      break;
    printf("%d: %d\n", i, data);
    pop(&stos);
  }
  printf("Stos jest %s.\n", (empty(&stos) ? "pusty" : "pełny"));
  return 0;
}

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