Главная » Просмотр файлов » С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс

С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (1114944), страница 38

Файл №1114944 С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс) 38 страницаС.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (1114944) страница 382019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 38)

Одним из способов может бытьиспользование функции find() – нахождение элемента с определенным значением:pointer_to_3 = mylist.find( 3 );find() принимает в качестве параметра значение из списка. Если элемент с такимзначением найден, то возвращается его адрес, иначе find() возвращает 0.Может быть два специальных случая вставки элемента: в начало и в конец списка. Дляinsert_front( value );этого требуется только задание значения:1nsert_end( value );Предусмотрим следующие операции удаления элемента с заданным значением, первогоremove( value );remove_front();элемента и всех элементов списка:remove_all();218С++ для начинающихФункция display() распечатывает размер списка и все его элементы.

Пустой списокможно представить в виде:(0)( )а список из семи элементов как:(7) ( 0 1 1 2 3 5 8 )reverse() меняет порядок элементов на противоположный. После вызоваmylist.reverse();предыдущий список выглядит таким образом:(7) ( 8 5 3 2 1 1 0 )Конкатенация добавляет элементы второго списка в конец первого. Например, для двухсписков:(4)( 0 1 1 2 ) // listl(4)( 2 3 5 8 ) // list2операцияlistl.concat( list2 );превращает list1 в(8) ( 0 1 1 2 2 3 5 8 )Чтобы сделать из этого списка последовательность чисел Фибоначчи, мы можемвоспользоваться функцией remove():listl.remove( 2 );Мы определили поведение нашего списка, теперь можно приступать к реализации.

Пустьсписок (list) и элемент списка (list_item) будут представлены двумя разнымиклассами. (Ограничимся теми элементами, которые способны хранить только целыезначения. Отсюда названия наших классов – ilist и ilist_item.)Наш список содержит следующие члены: _at_front – адрес первого элемента, _at_end –адрес последнего элемента и _size – количество элементов. При определении объектатипа ilist все три члена должны быть инициализированы 0. Это обеспечиваетсяконструктором по умолчанию:219С++ для начинающихclass ilist_item;class ilist {public:// конструктор по умолчаниюilist() : _at_front( 0 ),_at_end( 0 ), _size( 0 ) {}// ...private:ilist_item *_at_front;ilist_item *_at_end;int _size;};Теперь мы можем определять объекты типа ilist, например:ilist mylist;но пока ничего больше.

Добавим возможность запрашивать размер списка. Включимобъявление функции size() в открытый интерфейс списка и определим эту функциютак:inline int ilist::size() { return _size; }Теперь мы можем использовать:int size = mylist.size();Пока не будем позволять присваивать один список другому и инициализировать одинсписок другим (впоследствии мы реализуем и это, причем такие изменения не потребуютмодификации пользовательских программ). Объявим копирующий конструктор икопирующий оператор присваивания в закрытой части определения списка без ихclass ilist {public:// определения не показаныilist();int size();// ...private:// запрещаем инициализацию// и присваивание одного списка другомуilist( const ilist& );ilist& operator=( const ilist& );// данные-члены без измененияреализации.

Теперь определение класса ilist выглядит таким образом:};Обе строки следующей программы вызовут ошибки компиляции, потому что функцияmain() не может обращаться к закрытым членам класса ilist:220С++ для начинающихint main(){ilist yourlist( mylist ); // ошибкаmylist = mylist;// ошибка}Следующий шаг – вставка элемента, для представления которого мы выбрали отдельныйclass ilist_item {public:// ...private:int_value;ilist_item *_next;класс:};Член _value хранит значение, а _next – адрес следующего элемента или 0.Конструктор ilist_item требует задания значения и необязательного параметра –адреса существующего объекта ilist_item. Если этот адрес задан, то создаваемыйобъект ilist_item будет помещен в список после указанного.

Например, для списка0 1 1 2 5вызов конструктораilist_item ( 3, pointer_to_2 );модифицирует последовательность так:0 1 1 2 3 5Вот реализация ilist_item. (Напомним, что второй параметр конструктора являетсянеобязательным. Если пользователь не задал второй аргумент при вызове конструктора,по умолчанию употребляется 0. Значение по умолчанию указывается в объявлениифункции, а не в ее определении; это поясняется в главе 7.)221С++ для начинающихclass ilist_item {public:ilist_item( int value, ilist_-item *item_to_link_to = 0 );// ...};inlineilist_item::ilist_item( int value, ilist_item *item ): _value( value ){if ( item )_next = 0;else {_next = item->_next;item->_next = this;}Операция insert() в общем случае работает с двумя параметрами – значением иадресом элемента, после которого производится вставка.

Наш первый вариантinline voidilist::insert( ilist_item *ptr, int value ){new ilist_item( value, ptr );++_size;реализации имеет два недочета. Сможете ли вы их найти?}Одна из проблем заключается в том, что указатель не проверяется на нулевое значение.Мы обязаны распознать и обработать такую ситуацию, иначе это приведет к крахупрограммы во время исполнения. Как реагировать на нулевой указатель? Можноаварийно закончить выполнение, вызвав стандартную функцию abort(), объявленную в#include <cstdlib>// ...if ( ! ptr )заголовочном файле cstdlib:abort();Кроме того, можно использовать макрос assert(). Это также приведет к аварийному#include <cassert>// ...завершению, но с выводом диагностического сообщения:assert( ptr != 0 );Третья возможность – возбудить исключение:222С++ для начинающих223if ( ! ptr )throw "Panic: ilist::insert(): ptr == O";В общем случае желательно избегать аварийного завершения программы: в такойситуации мы заставляем пользователя беспомощно сидеть и ждать, пока службаподдержки обнаружит и исправит ошибку.Если мы не можем продолжать выполнение там, где обнаружена ошибка, лучшимрешением будет возбуждение исключения: оно передает управление вызвавшейпрограмме в надежде, что та сумеет выйти из положения.Мы же поступим совсем другим способом: рассмотрим передачу нулевого указателя какif ( ! ptr )запрос на вставку элемента перед первым в списке:insert_front( value );Второй изъян в нашей версии можно назвать философским.

Мы реализовали size() и_size как пробный вариант, который может впоследствии измениться. Если мыпреобразуем функции size() таким образом, что она будет просто пересчитыватьэлементы списка, член _size перестанет быть нужным. Написав:++_size;мы тесно связали реализацию insert() с текущей конструкцией алгоритма пересчетаэлементов списка. Если мы изменим алгоритм, нам придется переписывать эту функцию,как и insert_front(), insert_end() и все операции удаления из списка. Вместо тогочтобы распространять детали текущей реализации на разные функции класса, лучшеinline void ilist::bump_up_size(){ ++_size; }инкапсулировать их в паре:inline void ilist::bump_down_size() { --_size; }Поскольку мы объявили эти функции встроенными, эффективность не пострадала.

Вотinline voidilist::insert( ilist_item *ptr, int value )if (!ptr )insert_front( value );else{bump_up_size();new ilist_item( value, ptr );}окончательный вариант insert():}С++ для начинающихРеализация функций insert_front() и insert_end() достаточно очевидна. В каждойinline voidilist::insert_front( int value ){ilist_item *ptr = new ilist_item( value );if ( !_at_front )_at_front = _at_end = ptr;else {ptr->next( _at_front );_at_front = ptr;}bump_up_size();}inl-ine voidilist::insert_end( int value ){if ( !_at_end )_at_end = _at_front = new ilist_item( value );else _at_end = new ilist_item( value, _at_end );bump_up_s-ize();из них мы должны предусмотреть случай, когда список пуст.}find()ищет значение в списке.

Если элемент с указанным значением найден,ilist_item*ilist::find( int value ){ilist_item *ptr = _at_front;while ( ptr ){if ( ptr->value() == value )break;ptr = ptr->next();}return ptr;возвращается его адрес, иначе find() возвращает 0. Реализация find()выглядит так:}ilist_item *ptr = mylist.find( 8 );Функцию find() можно использовать следующим образом:mylist.insert( ptr, some_value );или в более компактной записи:224С++ для начинающихmylist.insert( mylist.find( 8 ), some_value );Перед тем как тестировать операции вставки элементов, нам нужно написать функциюdisplay(), которая поможет нам при отладке.

Алгоритм display() достаточно прост:печатаем все элементы, с первого до последнего. Можете ли вы сказать, где в данной// не работает правильно!for ( ilist_item *iter = _at_front; // начнем с первогоiter != _at_end;// пока не последний++iter )// возьмем следующийcout << iter->value() << ' ';// теперь напечатаем последнийреализации ошибка?cout << iter->value();Список – это не массив, его элементы не занимают непрерывную область памяти.Инкремент итератора++iter;вовсе не сдвигает его на следующий элемент списка. Вместо этого он указывает на местов памяти, непосредственно следующее за данным элементом, а там может быть все чтоугодно. Для изменения значения итератора нужно воспользоваться членом _next объектаilist_item:iter = iter->_next;Мы инкапсулировали доступ к членам ilist_item набором встраиваемых функций.class ilist_item {public:ilist_item( int value, ilist_item *item_to_link_to = 0 );intvalue() { return _value; }iilst_item* next() { return _next; }void next( ilist_item *link ) { _next = link; }void value( int new_value ) { _value = new_value; }private:int _value;ilist_item *_next;Определение класса ilist_item теперь выглядит так:};Вот определение функции display(), использующее последнюю реализацию классаilist_item:225С++ для начинающих226#include <iostream>class ilist {public:void display( ostream &os = cout );// ...};void ilist::display( ostream &os ){os << "\n( " << _size << " )(";ilist_item *ptr = _at_front;while ( ptr ) {os << ptr->value() << " ";ptr = ptr->next();}os << ")\n";}Тестовую программу для нашего класса ilist в его текущей реализации можнопредставить таким образом:С++ для начинающих#include <iostream>#include "ilist.h"int main(){ilist mylist;for ( int ix = 0; ix < 10; ++ix ) {mylist.insert_front( ix );mylist.insert_end( ix );}cout <<"Ok: после insert_front() и insert_end()\n";mylist.display();ilist_item *it = mylist.find( 8 );cout << "\n"<< "Ищем значение 8: нашли?"<< ( it ? " да!\n" : " нет!\n" );mylist.insert( it, 1024 );cout << "\n" <<"Вставка элемента 1024 после 8\n";mylist.display();int elem_cnt = mylist.remove( 8 );cout << "\n"<< "Удалено " << elem_cnt<< " элемент(ов) со значением 8\n";mylist.display();cout << "\n" << "Удален первый элемент\n";mylist.remove_front(); mylist.display();cout << "\n" << "Удалены все элементы\n";mylist.remove_all(); mylist.display();}Результат работы программы:Ok: после insert_front() и insert_end()(20)( 9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9 )Ищем значение 8: нашли? да!Вставка элемента 1024 после 8( 21 )( 9 8 1024 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9 )Удалено 2 элемент(ов) со значением 8( 19 )( 9 1024 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 9 )Удален первый элемент( 18 )( 1024 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 9 )Удалены все элементы( 0 )( )227С++ для начинающихПомимо вставки элементов, необходима возможность их удаления.

Характеристики

Тип файла
PDF-файл
Размер
5,41 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6418
Авторов
на СтудИзбе
307
Средний доход
с одного платного файла
Обучение Подробнее