List (Первый решённый курсач)
Описание файла
Файл "List" внутри архива находится в папке "Infa_Kurs_2003". PDF-файл из архива "Первый решённый курсач", который расположен в категории "". Всё это находится в предмете "информатика" из 3 семестр, которые можно найти в файловом архиве МАИ. Не смотря на прямую связь этого архива с МАИ, его также можно найти и в других разделах. Архив можно найти в разделе "остальное", в предмете "информатика" в общих файлах.
Просмотр PDF-файла онлайн
Текст из PDF
ОписаниеПредисловиеКласс линейного списка,двунаправленного, кольцевого.Поскольку у действий со спискоммало общих черт, обо всех возможностях по порядку.class List {private:struct node {int id;char a;char b;char c;char d;node* prev;node* next;};node* start;node* curr;int cnt;int id;void lerror (char *err);public:List ();bool empty();bool rewind (int topos);bool rewindto (int topos);int count();void add(int pos, char a, char b, char c, char d);void add(char a, char b, char c, char d);bool get(char &a,char &b,char &c,char &d);void update (char a, char b, char c, char d);void update (int pos, char a, char b, char c, char d);void print(int from);void print();void del();void del(int pos);void exchange(int pos);};Если посмотреть на объявление класса (см.
врезку),большинство функций перегружены для работы с относительными и абсолютными позициями. Относительное позиционирование обеспечивается за счетпердвижения внутреннего маркера curr. Для его сдвига используется функция rewind. Аргумент– относительное значение сдвига. Для работы с абсолютнымпозиционированием, используется функция rewindto, переставляющая маркер на позицию значения аргумента относительноначала списка. Но вообще абсолютное позиционирование –вполне бесполезная вещь.
Приэтом теряются все прелестикольцевого списка, а так жевесьма филосовские рассуждения о «начале» этого кольцевого списка.List::List()Конструктор всего один, фантазии на большое количество не хватило. Он обнуляет всеосновные значения. Простота – основа надежности.bool List::empty()Функция возвращает true в случае пустого списка.bool List::rewind(int pos)Перенос маркера на pos позиций.
Если аргумент отрицательный, то сдвиг влево, если положительный – вправо. Данная функция определяет в какую сторону эффективнее перемотать, затем выполняет последовательно необходимое количество единичных сдвигов.bool List::rewindto(int pos)Аналог предыдущей функции. Перенос маркера на pos позиций относительно началасписка. Вначале маркер сдвигается в начало, потом вызывается rewind, что дает в результатенеобходимый результат.int List::count()Возвращает количество элементов в списке.Задание #2 - Описание - int List::count() /страница 1 из 12/void List::add(int pos, char ...)Добавление элемента в список в позицию pos. Функция рассматривает два случая: список пуст и список не пуст. В первом варианте – создается единственный элемент, происходитнеобходимая инициализация работы с данными.
Если же в списке присутствуют элементы –программа перематывает маркер на необходимую позицию, в нее вставляет новый элемент.Причем, значение, находившееся на pos месте, теперь расположится на pos+1. Отдельныйслучай для нулевого (заглавного элемента). Он сдвигается исключительно в случае явногоуказания позиции вставки 0. Это обусловлено необходимостью сохранения целостности нумерации списка для абсолютного позиционирования.void List::add(char ...)Аналог предыдущей функции, но для относительного позиционирования.bool List::get(char &...)Извлечение значений маркера. Это свойство возможно только для относительного позиционирования.void List::print(int from)Вывод содержимого списка на стандартный поток.
При выводе используется метод «заголовочного» элемента. Если список пуст, выводится об этом сообщение.void List::del()Удаление элемента в позиции маркера. При этой операции обеспечивается сохранностьцелостности списка.void List::del(int from)Удаление элемента уже в позиции от начала списка.void List::exchange(int pos)Перемена местами двух соседних элементов. Реализована с помощью последовательной замены ссылок. Опять таки, замена позиции головного элемента не происходит. Если поменять позиции первого и второго элементов (комманда (List)list.exchange(0)), в результатевторой элемент станет последним.void List::update(char ...)Замена содержимого элемента в позиции маркера.void List::update(int pos, char ...)То же, но для абсолютного позиционирования.Послесловие о ListМожно сказать, что задание выполнено (по крайней мере было прошено написать класс,орудие программистов, а не пользователей), но не тут то было.
Требуют еще и интерфейспользователя.По поводу вида интерфейса – это, однозначно, консоль. Никогда меню не делал и делатьне собираюсь. Меню – слишком просто и неэффективно. У консоли гораздо больше возможностей – писать скрипты, скажем. Сама идея консоли и разбора запроса родилась еще со времен создания MESQL – эмулятора SQL. На основе синтаксического анализатора этой СУБДбыли построены многие программы прошлого семестра на pascal.Придется заново изобретать велосипед.Задание #2 - Описание - Послесловие о List /страница 2 из 12/Интерфейс пользователяВведениеРеализована консоль с помощью дополнительногокласса, с функцией перехвата стандартного потока(Console::intercept())Для анализа входной строки используется немного нетрадиционный способ, идея которого – таблицы расстановок(hash-таблицы). Имеется некая функция hash : char * -> int,сопоставляющая строке уникальное значение.
Перед началом работы происходит кэширование стандартных комманд.Например, h_add соотствует комманде add, и т.д.Также присутствует набор команд-приветствий.Console::Console(List &)Конструктор. Здесь происходит кэширование стандартных запросов, сохранения адреса обрабатываемого объекта.void Console::intercept()class Console {private:List* list;int h_add;int h_del;int h_delin;int h_xch;int h_rwd;int h_rwdto;int h_exit;int h_print;int h_empty;int h_get;int h_cnt;int h_help;int h_upd;int h_to;void print_inited();void print_welcome();void print_goodbye();int hash(char *);public:Console(List&);void intercept();};Перехват стандартного потока. Организуется бесконечный цикл, в каждой итерациипроисходит захват команды, ее обработка и отображение результатов (если необходимо).
Работа заканчивается по получении команды EXIT.ЗаключениеВ принципе, получилась консоль, слабо привязанная к данному линейному списку. Ее легко адаптировать для других случаев. Это очень важное значение – унифицированность.ВыводВ целом «дежурное» блюдо но уже под соусом «C++». Трудно что нибудь полезного почерпнуть из такого задания. С одной стороны – знания C/C++ на таком уровне присутствуют, ачтобы сделать что-нибудь действительного интересное слишком «стандартное» задание. Ну ачто, действительно полезного получил – это многофайловость, использование множествафайлов, заголовочных файлов.
Это очень упрощает работу при создании сложных программ,такой подход позволяет разделить принципиально разные модули программы, чтобы легкоможно было получить доступ к необходимому участку коду (функции, классу, ...).Задание #2 - Вывод - Вывод /страница 3 из 12/ЛистингиFile: unit1.cpp//--------------------------------------------------------------------------#include "list.h"#include "console.h"int main(){List list;Console console(list);console.intercept();return 0;}//---------------------------------------------------------------------------File: list.h#ifndef __list_h#define __list_h#include <iostream.h>class List {private:struct node { //Default data structureint id;char a;char b;char c;char d;//Indificator//Field1//Field2//Field3//Field4node* prev; //Link to prev nodenode* next; //Link to next node};node* start; //Link to start nodenode* curr; //Markint cnt; //Count of listint id; //Group IDvoid lerror (char *err); //If error occuredpublic:List (); //Default Constructor~List (); //Destructorbool empty(); //Is list empty?bool rewind (int topos); //Rewind on <> positionsbool rewindto (int topos); //Rewind to <> positionint count(); //Get list nodes countvoid add(int pos, char a, char b, char c, char d); //Add new node to <> positionvoid add(char a, char b, char c, char d); //Add new node after active nodebool get(char &a,char &b,char &c,char &d); //Get values of active nodeЗадание #2 - Листинги - File: list.h /страница 4 из 12/void update (char a, char b, char c, char d); //Update active nodevoid update (int pos, char a, char b, char c, char d); //Update node in <> positionvoid print(int from); //Print from <> positionvoid print(); //Print list nosedvoid del(); //Delete active nodevoid del(int pos); //Delete node in <> positionvoid exchange(int pos); //Exchange <n> and <n+1> nodes};#endif//----------------------------------------------------------File: list.cpp//Class "List"//ME software#ifndef __list_cpp#define __list_cpp#include "list.h"void List::lerror (char *err) { //if error occuredcout<<"ME List: "<<err<<"\n";}List::List () { //default constructorcnt=0;id=0;curr=NULL;start=NULL;}List::~List () {while(!empty())del();}bool List::empty() { //is list empty?return(start==NULL);}bool List::rewind (int topos) { //rewind on <topos> positionif (curr==NULL) {lerror("List is empty");return(0);}if (topos>=cnt||topos<=-cnt) {topos%=cnt;if (topos>cnt/2)topos-=cnt;elseif (topos<-cnt/2)topos+=cnt;}if (topos>0) {while (topos>0) {Задание #2 - Листинги - File: list.cpp /страница 5 из 12/else {}}topos--;curr=(*curr).next;}while (topos<0) {topos++;curr=(*curr).prev;}}return(1);bool List::rewindto (int topos) {if (curr==NULL) {lerror("List is empty");return(0);}curr=start;rewind(topos);return(1);}int List::count() {return(cnt);}void List::add(int pos, char a, char b, char c, char d) {node* f;if (start==NULL) { //Empty listf=new node;start=f;(*f).a=a;(*f).b=b;(*f).c=c;(*f).d=d;(*f).id=id;(*f).prev=f;(*f).next=f;curr=f;}else{node *next, *prev;if(!rewindto(pos))return;prev=(*curr).prev;next=curr;f=new node;(*f).a=a;(*f).b=b;(*f).c=c;(*f).d=d;(*f).id=id;(*f).prev=prev;(*f).next=next;(*prev).next=f;(*next).prev=f;}}id++;cnt++;if (pos==0)start=f;curr=f;void List::add(char a, char b, char c, char d) {Задание #2 - Листинги - File: list.cpp /страница 6 из 12/if (start==NULL) {add(0,a,b,c,d);}else{node *f;f=new node;(*f).a=a;(*f).b=b;(*f).c=c;(*f).d=d;(*f).id=id;(*f).prev=curr;(*f).next=(*curr).next;(*curr).next=f;(*(*f).next).prev=f;curr=f;}}id++;cnt++;bool List::get(char &a,char &b, char &c, char &d) {}if (curr==NULL)return(0);a=(*curr).a;b=(*curr).b;c=(*curr).c;d=(*curr).d;return(1);void List::print(int from) {if (empty()) {cout<<"There no items\n";return;}if (!rewindto(from))return;int startid=(*curr).id;cout<<(*curr).a<<"\t"<<(*curr).b<<"\t"<<(*curr).c<<"\t"<<(*curr).d<<"\n";curr=(*curr).next;}while ((*curr).id!=startid) {cout<<(*curr).a<<"\t"<<(*curr).b<<"\t"<<(*curr).c<<"\t"<<(*curr).d<<"\n";curr=(*curr).next;}void List::print() {print(0);}void List::del() {if (empty()) {lerror("List is empty");return;}node* f;f=curr;(*(*curr).prev).next=(*curr).next;(*(*curr).next).prev=(*curr).prev;if ((*curr).id==(*start).id) {if ((*curr).id==(*(*curr).next).id) {start=NULL;curr=NULL;Задание #2 - Листинги - File: list.cpp /страница 7 из 12/else {else}}start=(*curr).next;curr=start;}curr=(*curr).next;}delete f;cnt--;void List::del(int pos) {if (!rewindto(pos))return;del();}void List::exchange(int pos) {if (!rewindto(pos))return;node* next=(*curr).next;(*(*curr).prev).next=next;(*(*next).next).prev=curr;(*next).prev=(*curr).prev;(*curr).next=(*next).next;(*curr).prev=next;(*next).next=curr;if (pos==0)start=next;}void List::update (char a, char b, char c, char d) {(*curr).a=a;(*curr).b=b;(*curr).c=c;(*curr).d=d;}void List::update (int pos, char a, char b, char c, char d) {rewindto(pos);(*curr).a=a;(*curr).b=b;(*curr).c=c;(*curr).d=d;}#endif//----------------------------------------------------------File: console.h//class Console#define SIZE_OF_COMMAND 5#include <iostream.h>#include "list.h"class Console {private:Задание #2 - Листинги - File: console.h /страница 8 из 12/List* list;intintintintintintintintintintintintinth_add;h_del;h_delin;h_xch;h_rwd;h_rwdto;h_exit;h_print;h_empty;h_get;h_cnt;h_help;h_upd;int h_to;void print_inited();void print_welcome();void print_goodbye();int hash(char *);public:Console(List&);void intercept();};//----------------------------------------------------------File: console.cpp#include "console.h"Console::Console(List &lst) {list=&lst;//Caching on standart command hash value:h_add=hash("add"); //Addh_del=hash("del"); //Deleteh_delin=hash("delin"); //Delete from posh_xch=hash("xch"); //Exchangeh_rwd=hash("rwd"); //Rewindh_rwdto=hash("rwdto"); //Rewind to posh_to=hash("to"); //'To' statementh_print=hash("print"); //Print listh_empty=hash("empty"); //Is empty?h_get=hash("get"); //Get values from current elementh_cnt=hash("cnt"); //Get count of nodesh_upd=hash("upd"); //Update nodeh_help=hash("help"); //Print helph_exit=hash("exit"); //Exit from emulatorprint_inited();}void Console::print_inited() { //Default hello messagecout<<"ME console has inited \n";}void Console::print_welcome() { //Default hello messagecout<<"Welcome to ME console of List emulator\nRun commands:\n";}void Console::print_goodbye() { //Default hello messagecout<<"Bye Bye!";}int Console::hash(char *buff) { //Convert char[5] -> intint res=0;const int layer=255;Задание #2 - Листинги - File: console.cpp /страница 9 из 12/}int inlayer=1;for (int i=0; i<5; i++) {if (buff[i]==0)break;res+=res+buff[i]*inlayer;inlayer*=layer;}return(res);void Console::intercept() { //Main function of console.