Cześć :)
Robię teraz takie oto zadanie:
Napisz program, który pozwoli użytkownikowi na wykonywanie podstawowych operacji na stosie. W tym celu zaimplementuj stos w oparciu o następujące struktury oraz funkcje:
struct stack_t
{
int head;
int capacity;
int *data;
};
gdzie:
head - indeks pierwszej wolnej pozycji na stosie,
capacity - pojemność tablicy przydzielonej na stos,
data - wskaźnik na tablicę do przechowywania elementów stosu.
Przygotuj następujące funkcje, umożliwiające obsługę stosu:
int stack_init(struct stack_t **stack, int N);
int stack_push(struct stack_t *stack, int value);
int stack_pop(struct stack_t *stack, int *err_code);
void stack_display(const struct stack_t *stack);
void stack_free(struct stack_t *stack);
Deklaracje wszystkich funkcji oraz struktur umieść w pliku nagłówkowym stack.h, a definicje w pliku stack.c.
int stack_init(struct stack_t **stack, int N);
Funkcja przydziela pamięć na strukturę stack_t oraz tablicę N elementów i inicjuje jej pola odpowiednimi wartościami.
Funkcja zwraca wartość:
1 w przypadku przekazania błędnych danych,
2 w przypadku niepowodzenia alokacji pamięci lub
0 w przypadku sukcesu.
int stack_push(struct stack_t *stack, int value);
Funkcja dodaje element o wartości value do stosu stack. Jeżeli zabraknie miejsca w tablicy na dodanie nowej wartości value to funkcja powinna podwoić pojemność tablicy.
Funkcja zwraca:
0 w przypadku sukcesu,
1 w przypadku błędnych danych wejściowych lub
2 jeżeli nie uda się przydzielić pamięci (w takim przypadku nie powinna modyfikować tablicy).
int stack_pop(struct stack_t* stack, int *err_code);
Funkcja usuwa ostatnio dodany element ze stosu stack zwracając jego wartość. W przypadku błędu zwracana wartość jest nieistotna.
Do zmiennej err_code, o ile to możliwe, zapisany powinien zostać kod błędu:
0 w przypadku sukcesu,
1 w przypadku błędnych danych wejściowych,
2 jeżeli stos jest pusty.
void stack_free(struct stack_t* stack);
Funkcja zwalnia całą pamięć przydzieloną na stos. W przypadku błędnych danych funkcja nie podejmuje żadnej akcji.
void stack_display(const struct stack_t* stack);
Funkcja wyświetla wszystkie elementy ze stosu stack, w jednym wierszu, oddzielone spacjami. Pierwszym wyświetlonym elementem ma być ostatni dodany na stos.
W przypadku błędnych danych funkcja nie podejmuje żadnej akcji.
Napisz program, który pozwoli użytkownikowi na wykonywanie podstawowych operacji na stosie. Na początek program powinien zaalokować pamięć na stos, początkowo przyjmij pojemność stosu na 10 elementów.
Jeżeli udało się utworzyć listę, program powinien zapytać użytkownika o wybór operacji (liczba całkowita):
0 - Zakończenie działania prosgramu.
1 - Dodanie elementu do stosu; program pobiera od użytkownika wartość całkowitą, która ma zostać położona na stos.
2 - Zdjęcie elementu ze stosu; program powinien wyświetlić wartość zdjętego elementu.
Jeżeli stos jest pusty program powinien wyświetlić komunikat Stack is empty.
3 - wyświetlenie wartości wszystkich elementów znajdujących się na stosie.
Jeżeli stos jest pusty program powinien wyświetlić komunikat Stack is empty.
W przypadku podania innej wartości program powinien wyświetlić komunikat Incorrect input data i kontynuować działanie.
Jeżeli nie uda się zaalokować żądanego obszaru pamięci program powinien wyświetlić komunikat Failed to allocate memory i zwrócić kod błędu 8.
W przypadku wprowadzenia przez użytkownika błędnych znaków program powinien bezzwłocznie zakończyć działanie z kodem błędu 1 i komunikatem Incorrect input
Na tą chwilę skupiam się, aby przeszły testy funkcyjne, bo bez funkcji nie mam po co przechodzić do rozpisywania main(). Na tą chwilę jeżeli chodzi o funkcje mam tyle:
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
int stack_init(struct stack_t **stack, int N)
{
if( stack == NULL || N <= 0 )
{
return 1;
}
*stack = (struct stack_t *) malloc (sizeof(struct stack_t ) );
if( *stack == NULL )
{
return 2;
}
struct stack_t * point_on_struct;
point_on_struct = *stack;
( point_on_struct->data) = (int *) malloc (sizeof(int) * N);
if( (point_on_struct->data) == NULL )
{
//free(point_on_struct);
free(*stack);
*stack = NULL;
return 2;
}
( point_on_struct -> capacity) = N;
( point_on_struct -> head ) = 0;
return 0;
}
int stack_push(struct stack_t *stack, int value)
{
if( stack == NULL )
{
return 1;
}
if( stack->head == 0 )
{
stack->data = (int *) realloc(stack->data,(stack->capacity) * 2);
if( stack->data == NULL )
{
free(stack);
stack = NULL;
return 2;
}
}
int i = 0;
i = stack->head;
int * pointer_on_data = stack->data;
*(pointer_on_data + i) = value;
int * pointer_on_head = &(stack->head);
*pointer_on_head = *pointer_on_head + 1;
return 0;
}
int stack_pop(struct stack_t *stack, int *err_code)
{
return 0;
}
void stack_display(const struct stack_t *stack)
{
if( stack == NULL )
{
}
else
{
int i = (stack -> head) - 1;
while( i >= 0 )
{
int * pointer = stack->data;
printf("%d ", *(pointer + i) );
i--;
}
}
}
void stack_free(struct stack_t *stack)
{
if( stack == NULL )
{
}
else
{
free( (stack->data) );
free(stack);
stack = NULL;
}
}
O ile ze stack_init nie było problemów, o tyle nie do końca wiem na co powinno wskazywać stack->head w funkcji stack_push, gdy stos jest pełny (dzięki temu będę wiedział, czy mam robić realloc-a na dwa razy więcej miejsca). Myślałem, że być może gdy stos jest pełny pokazuje na element o 1 większy od capacity. To jednak chyba nie to. Na pytanie do prowadzącego dostałem taką odpowiedź:
Dzień dobry,
proszę się przyjrzeć opisowi pól head i capacity:
head - indeks pierwszej wolnej pozycji na stosie,
capacity - pojemność tablicy przydzielonej na stos,
Skoro head wskazuje na pierwszą wolną pozycję na stosie, to na co będzie wskazywał, kiedy stos będzie pełny?
De facto czytałem to kilka razy pod rząd i dalej nie rozumiem co autor zadania chciał mi przekazać w ostatnim zdaniu. Domyślacie się może o co chodzi?