Реализовать на языке C модуль для работы со стеком элементов.
Строго заданный интерфейс:
#include <stddef.h> // size_t
static const size_t INVALID = ~((size_t)0);
void * stack_create(size_t itemSize);
void stack_destroy(void * stack, void(*destroy)( void * ));
void * stack_init(void * stack, size_t itemSize, void(*destroy)(void*));
void stack_clear(void * stack, void(*destroy)( void * ));
size_t stack_count(const void * stack);
void * stack_push(void * stack);
void stack_pop(void * stack, void(*destroy)( void * ));
void * stack_peek(const void * stack);
size_t stack_first(const void * stack);
size_t stack_next(const void * stack, size_t item_id);
size_t stack_stop(const void * stack);
void * stack_current(const void * stack, size_t item_id);
INVALID
-- код ошибки для невалидных ситуаций.stack_create
-- Создать новый пустой стек. Размер элемента -- itemSize
байт.stack_destroy
-- Удалить существующий стек. Если указана функция destroy
, то вызвать её для каждого удаляемого элемента.stack_init
-- Инициализировать стек новыми параметрами.
Если stack
содержит элементы, то сначала удалить все элементы, потом инициализировать стек с учетом новых параметров.
Размер элемента -- itemSize
байт.
Если указана функция destroy
, то вызвать её для каждого удаляемого элемента.stack_clear
-- Удалить все элементы из стека. Если указана функция destroy
, то вызвать её для каждого удаляемого элемента.stack_count
-- Количество элементов в стеке. В случае, если stack
равен NULL
, возвращает INVALID
константу.stack_push
-- Добавить элемент на вершину стека. В случае успеха, функция возвращает указатель на добавленный элемент, иначе -- NULL
.stack_pop
-- Удалить элемент с вершины стека. Если указана функция destroy
, то вызвать её для удаляемого элемента.stack_peek
-- Подсмотреть элемент с вершины стека, не удаляя его. В случае успеха, функция возвращает указатель на верхний элемент, иначе -- NULL
.stack_first
-- Идентификатор для элемента с вершины стека. Идентификатор может стать невалидным при модификации стека.stack_next
-- По идентификатору текущего элемента получить идентификатор следующего элемента стека.stack_stop
-- Идентификатор, получаемый при попытке обратиться к элементу за пределами стека.stack_current
-- Получить указатель на элемент стека по его идентификатору.//Пример использования
#include <string.h>
#include <assert.h>
#include <math.h>
#include "stack.h"
typedef struct {
int array[8];
float d_variable;
} Value;
int main(int argc, char* argv[])
{
//Создаем стек с элементами типа Value;
void* stack = stack_create(sizeof(Value));
assert(0 == stack_count(stack));
assert(stack_stop(stack) == stack_first(stack));
//Создаем объект для стека
Value value = { {1, 2, 3, 4, 5, 6, 7, 8}, 0.f };
//Добавляем новый элемент в стек
Value* insertedValue = (Value*)stack_push(stack);
//Инициализируем добавленный элемент
*insertedValue = value;
Value* item = (Value*)stack_peek(stack);
for (size_t i = 0; 8 > i; ++i) {
assert(item->array[i] == value.array[i]);
}
assert(fabsf(item->d_variable - value.d_variable) < 1e-10f);
assert(stack_next(stack, stack_first(stack)) == stack_stop(stack));
stack_destroy(stack, NULL);
return 0;
}