Основная информация об проекте (Этот же проект только на C++ клик).
В данном проекте реализована одна из самых основных структур данных Stack. Суть этой структуры данных заключается в том, что элементы этой структуры поддерживают принцип LIFO (“Last in – first out”): последним зашёл – первым вышел. Основные функции, с помощью которых мы будем работать со стеком это push_stack и pop_stack, примеры их использования будут приведены в самом конце. В реализации так же присутствует многоуровневая защита данных. Защита и грамотная работа stack 'a осуществляется благодаря нескольким простым принципам:
- Канарейки (или же канареечная защита).
- Hash (хэширование данных).
- Верификатор (анализ как достаточно распространенных так и особых случаев, для предотвращения возникновения ошибок или их устранения).
Опять же более подробно об этих принципах будет описано ближе к концу статьи. Теперь же хочется в кратце показать список (пересказ, если можно так назвать) вещей, которые может наша структура данных.
- Полиморфизм
- Тип данных double.
- Тип данных int.
- Тип данных char.
- Тип данных string.
- Тип данных float.
- Структуру stack'a.
- Канарейки_.
- Массив типа type_data (в зависимости от типа хранимых данных).
- Максимальный размер stack' a.
- Текущий размер stack' a.
- Hash stack' a.
- Конструктор stack' a.
- Проверки на возможные ошибки про вызове конструктора.
- Двойной конструктор.
- Валидность максимального размера stack' a.
- Динамическое выделение памяти.
- Заполнение данныз POISON' ом.
- Проверки на возможные ошибки про вызове конструктора.
- Деконструктор stack' a.
- Проверки на возможные ошибки про вызове деконструктора.
- Полный список находится в описании функции stack_verify.
- Уровень самой проверки варируется в зависимости от требуемого уровня защиты stack' а.
- Различные уровни защиты.
- LOW.
- MEDIUM.
- HIGH.
- Мега защита, добавляю конструктор копировая.
- Обеспечение удаления всех данных из стека (макс. размер, текущий размер, все данные из масива, хэша.)
- При помощи POISON.
- Освобождение выделенной памяти.
- Проверки на возможные ошибки про вызове деконструктора.
- push_stack
- Проверки на возможные ошибки про вызове функции.
- Полный список находится в описании функции stack_verify.
- Так же проходит проверка совпадения типов данных и сама проверка push_number.
- Учтено то, что нужно выделять дополнительную память или наоборот освобождать.
- Написан реалокатор.
- Проверки на возможные ошибки про вызове функции.
- pop_stack
- Проверки на возможные ошибки про вызове функции.
- Полный список находится в описании функции stack_verify.
- Так же учтен тот факт, что нужно увеличивать/уменьшать память, отводимую под хранение данных.
- Проверки на возможные ошибки про вызове функции.
- stack_dump
- Вывод ошибок, если такого существует. И соответственно отсутствие ошибок, если их нет.
- Вывод всех актуальной информации о стеке.
- Уровень защиты данных.
- Имя стека.
- Текущий размер.
- Максимальный размер.
- Все данные, которые лежат в стеке.
- Значение hash' a stack' a.
- Тип данных, хранимых в stack' e.
- Учтен тот факт, что данные могут быть разного типа.
- stack_verify
- Проверки
- MAX_CAPACITY_ERROR.
- Stack == nullptr.
- Проверка на соответствие hash 'a.
- stack->data == nullptr.
- Cur_size > max_size.
- Cur_size < 0.
- Проверка на валидность значения max_size.
- Max_size < 0.
- Проверка на валидность значения cur_size.
- Проверка на соответствие канареек stack 'a.
- Проверка на соответствие канареек stack->data' ы.
- В случае ошибки фиксировать ее.
- Регулировка проверок по уровню защиты
- LOW.
- MEDIUM.
- HIGH.
- Проверки
- error_print
- Возращает сообщение об ошибки в соответсвии с ошибками.
- Все типы ошибок представлены в stack_verify.
- Возращает сообщение об ошибки в соответсвии с ошибками.
- add_memory
- Проверки на возможные ошибки про вызове функции.
- Полный список находится в описании функции stack_verify.
- Увеличение память на заранее заданную константу REAL_MULTIPLIER = 2, если это нужно.
- Соответственно уменьшение выделенной памяти на заданную константу REAL_REDUCER = 2 * REAL_MULTIPLIER при необходимых условиях.
- Если начальный размер равен нулю, то размер задается константой REAL_ADDER.
- Все новые данных (или все удаленне) заполняются __POISON' ом.
- Проверки на возможные ошибки про вызове функции.
- hash_stack
- Проверки на возможные ошибки про вызове функции.
- Полный список находится в описании функции stack_verify.
- Хэширование данных в стеке.
- Все хранящиеся данные.
- имя стека.
- Указателей.
- Проверки на возможные ошибки про вызове функции.
- define_lvl
- Определяет уровень защиты в требованию пользователя.
Так как этот проект превращен в библиотеку, то логичным началом станет показать как правильно включать библиотеку в ваш проект.
#define DOUBLE_T
#include <stack.h>
Так как stack написан на языке C , то думаю всем понятно, что строчкой перед #include мы даем понять нашему стеку какой тип данных ему необходимо открыть. Сразу становится понятно, что мы не можем создавать стеки, хранящие различные типы данных. В будущей вернии stack' а, который будет зарефакторен на язык C++ это неудобство будет убрано и пользователь сможет создавать стеки, хранящие разные типы данных.
В C версии так же существуют еще [4] типа данных, которые поддерживает наш stack. Вот как будет выглядеть подключание библиотеки в соответствующих случаях.
#define INT_T // stack int'ов
#include <stack.h>
#define FLOAT_T // stack float'ов
#include <stack.h>
#define STRING_T // stack char'ов
#include <stack.h>
#define CHAR*_T // stack, содержащий строки
#include <stack.h>
В нашей реализации было целесообразно добавить разные уровни защиты stack' а. Всего такох уровней было добавлено 3, как было видно на схеме в начале.
- High secure.
- Meduim secure.
- Easy secure.
Аналогично чтобы указать уровень защиты необходимо вместе с предыдущим define' ом прописать соответственно одно из следующих
#define HIGH_SECURE // High security
// or
#define MEDIUM_SECURE // Medium security
// or
#define LOW_SECURE // Low security
В зависимости от уровня защиты скорость работы соответственно увеличивается/уменьшается, при уменьшении/увеличении уровня защиты соответственно.
Как подмечалось ранее для работы со структорой данных stack предусмотрено 2 основных функции: push и pop (как понятно из названия они заносят/достают данные в stack соответственно). Но перед тем как использовать stack необходимо его объявить и проинициализировать. Для первой цели отлично подходит обычное объявление структуры, для второй цели директива препроцессора, она здесь нужна для того, чтобы присвоить stack' у имя, чтобы каким-либо образом различать stack' и между собой.
stack_t name = {};
Construct(name,b)
Опять же приходится делать как-то все не очень обычно, но эти неудобства будут устранены когда stack будет написан на C++. Теперь, когда stack объявлен и проинициализирован мы можем начать работать с ним. Приведем примеры как использовать функции push и pop, если тип данных double.
push_stack(&Stack, 25.4); // Здесь 25,4 -- push number
pop_stack(&Stack); // Достаем число из stack'a.
// Для случая с данными типа double мы можем присвоить занести число,
// которое лежало на верхушке stack'a в другую какуб-нибудь переменную:
double temp = pop_stack(&Stack);
Для просмотра информации (эта функции полезна для пользователя, но особенно для разработчика) существует функция dump. Приведем пример ее использования и ее результат для како-либо абстрактной ситуации.
stack_dump(&Stack);
Результат вывода в файл:
В последок стоит упомянуть, что в конце работы со stack' ом необходимо вызывать деконструктор. Необходимость этой исчезнет в C++ версии.
В C++ версии stack' a будет добавлено:
-
Удобное подключение библиотеки
-
Так как не будет необходимости указывать тип данных при подключении библиотеки, а так же при помощи средств языке C++ у юзера будет возможность создавать stack' и разных типов данных, что станет одним из главных достатков.
-
Будет добавлен конструктор по умолчанию и теперь пользователь сможет при объявлении неявно инициализировать стек, без проделывания лишних действий.
-
Будет добавлен деконструктор по умолчанию, что так же облегчик работу и повысит удобство использования stack' а.
-
Благодаря возмодностям class' ов в языке C++ появится возможность сделать публичные и приватные данные в стеке, что уберет необходимость дополнительной защиты данных.
-
Так же множество других полезных функций.
Coming soon..
⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄.
⠄⠄⠄⠄⠄⠄⢰⣷⡄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
⠄⠄⠄⠄⣠⣾⣿⣿⣷⣦⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
⠄⠄⠄⣠⣿⣿⣿⣿⣿⣿⣇⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
⠄⠄⠄⠄⠛⠿⣿⣿⣿⣿⣿⣆⠄⠄⠄⠄⠄⣴⣿⣿⣆⠄⠄⠄
⠄⠄⠄⠄⠄⣰⣿⣿⣿⣿⣿⣿⣷⣄⠄⠄⠄⣿⣿⠛⠉⠄⠄⠄
⠄⠄⠄⠄⠄⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠄⠘⣿⡆⠄⠄⠄⠄
⠄⠄⠄⠄⠄⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠸⣿⡀⠄⠄⠄
⠄⠄⠄⠄⠄⠄⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠄⣿⡇⠄⠄⠄
⠄⠄⠄⠄⠄⠄⢸⣿⡟⣿⣿⣿⣿⣿⣿⣿⣿⡇⢀⣿⠇⠄⠄⠄
⠄⠄⠄⠄⠄⢀⣸⡿⢁⣘⣿⣿⣿⣿⣿⣿⣿⣇⣼⠋⠄⠄⠄⠄
⠄⠄⠄⠄⠄⠻⠿⠓⠿⠿⠿⠿⠿⠿⠿⠿⠿⠛⠁⠄⠄⠄⠄⠄
⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄⠄
......................./> フ.....................
| _ _ |
/`ミ x 彡
/ |
/ ヽ ノ
/ ̄| | | |
| ( ̄ヽ____ヽ__)___)
\二つ