====== 13 - ADT - zásobník ======
Příklad kromě samotné implementace abstraktního datového typu ukazuje, jak rozdělit program do více modulů, v tomto případě knihovny pro práci se zásaobníkem a hlavního programu.
===== Deklarace rozhraní - stack.h =====
typedef struct
{
int *data;
int cursor;
} stack;
void stack_init (stack **);
void stack_push (stack *, int);
void stack_pop (stack *, int *);
int stack_empty (stack *);
void stack_print (stack *);
void stack_destroy (stack *);
===== Implementace - stack.c =====
#include
#include
#include "stack.h"
void stack_init (stack ** a)
{
*a = malloc(sizeof(stack));
(*a)->kurzor = 0;
(*a)->data = NULL; // malloc(0)
}
void stack_destroy (stack * a)
{
if (a->cursor > 0)
free(a->data);
free(a);
}
void stack_push (stack * a, int item)
{
int * b = a->data;
b = realloc(a->data, sizeof(int)*(a->cursor+1));
if (b != NULL)
a->data = b;
a->data[a->kurzor++] = item;
printf("-> %i\n", item);
}
void stack_pop (stack * a, int * item)
{
*item = a->data[--(a->cursor)];
printf("<- %i\n", *item);
int * b = a->data;
b = realloc(a->data, sizeof(int)*(a->cursor));
if (b != NULL)
a->data = b;
}
void stack_print (stack *a)
{
for (int i = 0; i < a->cursor; i++)
{
printf("== %i\n", a->data[i]);
}
}
int stack_empty (stack *a)
{
return a->cursor == 0;
}
===== Hlavní program - main.c =====
#include "stack.h"
#include
int main()
{
stack * zasobnik;
int b;
stack_init(&zasobnik);
stack_push(zasobnik, 10);
stack_push(zasobnik, 20);
stack_push(zasobnik, 30);
stack_pop(zasobnik, &b);
stack_print(zasobnik);
while(!stack_empty(zasobnik))
{
stack_pop(zasobnik, &b);
}
stack_destroy(zasobnik);
return 0;
}
===== Kompilace =====
$ clang main.c stack.c -o zasobnik
$ zasobnik
-> 10
-> 20
-> 30
<- 30
== 10
== 20
<- 20
<- 10
Alternativně lze vytvořit knihovnu v podobě binárního souboru, který lze k hlavnímu programu při překladu přilinkovat. Tento způsob je vhodný pro případ, kdy například není žádoucí distribuce zdrojového kódu knihovny a distribuuje se pouze binární soubor a hlavičkový soubor s deklaracemi rozhraní. K vytvoření knihovny slouží program [[https://linux.die.net/man/1/ar|ar]].
$ clang -c -o stack.o stack.c
$ ar rcs libstack.a stack.o
$ clang main.c libstack.a -o zasobnik
Použití knihovny je vhodné také v případě, že ji budeme opakovaně používat. Knihovna se zpravidla nemění, takže již není znovou kompilována a zkracuje se doba kompilace. Knihovnu a hlavičkový soubor je dobré dát do vhodných adresářů, např. ''/usr/local/lib'' a ''/usr/local/include''. Překlad by pak mohl vypadat třeba takto:
$ clang main.c -lstack -o zasobnik