====== 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