//Стек, реализованный с помощью структуры "Узел", которая хранит значение 
//(в нашем примере типа int) и указатель на следующий узел. 
//Это неэффективная реализация, которая требует удаления и выделения 
//памяти под узел при каждом вызове операции push и pop. 
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
 
#define STACK_OVERFLOW  3
#define STACK_UNDERFLOW 4
 
/**
Узел ссылается на предыдущий элемент стека.
Если узел ссылается на NULL, то это последний элемент стека
*/
typedef struct Node {
    int value;
    struct Node *next;
} Node;
 
/**
Создаём новый узел и делаем его вершиной стека.
*/
void push(Node *head, int val) {
    Node *tmp = NULL;
    if (!(tmp = (Node*) malloc(sizeof(Node)))) {
        exit(STACK_OVERFLOW);
    }
    tmp->next  = head->next;
    tmp->value = head->value;
    head->value = val;
    head->next  = tmp;
}
 
/**
Возвращаем значение текущей вершиныи удаляем её
*/
int pop(Node **head) {
    Node *tmp = (*head)->next;
    int val = (*head)->value;
    if ((*head)->next == NULL) {
        exit(STACK_UNDERFLOW);
    }
    free(*head);
    (*head) = tmp;
    return val;
}
 
/**
Удаляем все вершины
*/
void freeList(struct Node **head) {
    Node *tmp = NULL;
    while ((*head)->next) {
        tmp = (*head)->next;
        free(*head);
        (*head) = tmp;
    }
}
 
/**
Для того, чтобы получить последний элемент, необходимо
по цепочке пройти до него
*/
Node* getLast(struct Node *head) {
    Node* tmp;
    tmp = head -> next;
    while (tmp) {
        tmp = tmp -> next;
    }
    return tmp;
}
 
void main(){
    Node *head = NULL;
    int i;
     
    head = (Node*)malloc(sizeof(Node));
    head -> next = NULL;
 
    push(head, 100);
    push(head, 300);
    printf("%d\n", pop(&head));
    push(head, 200);
    push(head, 1000);
 
    while (head->next) {
        printf("%d\n", pop(&head));
    }
 
    free(head);
    getch();
}