Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 143
Текст из файла (страница 143)
Советы [1) При написании алгоритма решите, какой вид итераторов нужсн для обеспечения приемлемой эффективности, и,выразите алгоритм при помощи (только) операторов, поддерживаемых этими итераторами; 9 19.2.1. [2) Для обеспечения эффективных реализаций алгоритма, ко~да в качестве аргументов вы имеете итераторы, обеспечивающие нечто большее, чем необходимо, используйте перегрузку; 9 19.2.3. [3) Для выражения алгоритмов, соответствующих разным категориям итераторов, пользуйтесь !1ега1ог 1га!1з; 5 19.2.2. 644 Глава 19. Итераторы и распределители памяти [4] Не забывайте употреблять ++ между обращениями к 1в1геат 11ега1ог и овггеат Пегагог; 9 19.2.6.
[5] Чтобы избежать переполнения контейнеров, пользуйтесь вставками; 6 19.2.4. [6] Во время отладки используйте дополнительные проверки и удаляйте их потом только в случае неооходимостя; 9 19.3,1. [7) Предпочитайте использовать++р, анер++; 6 193. [8] Чтобы повысить быстродействие алгоритмов, расширяющих структуры данных, пользуйтесь неинициализированной памятью; 6 19.4А. [9) Чтобы повысить быстродействие алгоритмов, требующих временной памяти для хранения структур данных, пользуйтесь временными буферами; 9 19АА. [10] Прежде чем писать свой распределитель памяти, хорошенько подумайте; 9 19А.
[11] Избегайте функций таПос 0, 1гее (), геаПос () и т. пя 9 19.4.6. [12] Вы можете симулировать 1уреде~с шаблоном, воспользовавшись приемом с ге61лд; 9 19.4.1. 19.6. Упражнения 1. (*1.5) Реализуйте геоегзе () из 9 18.6.7. Подсказка: См. 9 19.2.3. 2. ('1.5) Напишите итератор для записи 81ля, который бы в действительности никуда не писал. Когда мол<ет пригодиться 81ля? 3. 1'2) Реализуйте геоегве Пега1ог(6 19.2.5). 4.
[" 1.5) Реализуйте ов1геат Пега1ог [9' 19.2.6). 5. (*2) Реализуйте Мгеат Пега1ог(9 19.2.6). 6. ("2.5) Заверигите Сйесяей Пег [9 193). 7. 1 "2.5) Переделайте Слесяед Пег, чтобы проверять недействительные итераторы. 8. (*2) Придумайте и реализуйте вспомогательный класс, который мог бы работать как заместитель контейнера, обеспечивая для пользователей полный интерфейс контейнера.
Его реализация должна состоять из указателя на контейнер и реализации контейнерных операций с проверкой диапазона. 9. 1*2.5) Завершите или реализуйте ааново Рос! аПос Я 19.4.2) так, чтобы она обеспечивала все возможности распределителя памяти аПоса1ог Я 19 4Л ) из стандартной библиотеки. Сравните быстродействие аПоса1ог и Роо1 аПос, чтобы решить, имеет ли смысл пользоваться Роо1 аПос в вашей системе.
10. [*2.5) Реализуйте вес1ог при помощи распределителей памяти, а не операторов неге и Пе1еге. Строки Оригинальности лредпочитайгле стандарт. — Странк и Уайт Строки — символы — сйаг !га(1е — Ьаз(с е(г(пд — итераторы — доступ к элементам — конструкторы — обработка ошибок — првсваивание— преобразования — сравнения — вставка — конкатенация — поиск и замена— размер и емкость — ввод/вывод строк — С-строки — классификация символов — функции из библиотеки С вЂ” советы — упражнения. 20.1.
Введение Строка — это последовательность символов. Стандартный библиотечный класс з1ггад обеспечивает операции для манипулирования строками, такие как индексация (6 20.3.3), присванвание (6 20.3.6), сравнение (9 20.3,8), добавление (6 20.3.9), конкатенация (9 20 3 10) и поиск подстрок (9 20 3 6). Стандарт не обеспечивает для подстрок никаких общих средств, поэтому то, что рассматривается здесь, можно считать станлартным примером использования строк (9 20.3.11). Стандартная строка может состоять из практически любых символов (э 20.2). Опыт показывает, что совершенный класс зЖпп разработать невозможно. Для этого сли1пком различаются людские вкусы, ожидания и потребности. Поэтому стандартный библиотечный класс э1ппп не идеален.
Я бы кое-что решил по-другому, и вы тоже. Однако библиотечный класс в1ггпя'хорошо служит многим потребностям, легко предоставлял>тся вспомогательные функции, и эйзвй тдшироко известен и доступен. В большинстве случаев эти факторы важнее, чем второстепенные улучшения, которые мы можем произвести. Написание строковых классов имеет большое образовательное значение (6 11.12, 9 13.2), по для широко используемого кода следует пользоваться стандартным библиотечным классом вИпд.
С.н- унаследовал от С понятие строки как оканчившощегося нулем массива элементов типа айаг, а также набор функций для манипулирования такими С-строками (6 20А.1). 20.2. Символы «Символ» вЂ” само по себе интересное понятие. Рассмотрим символ С. С, который вы видите как кривую линию па странице (или экране), я напечатал на моем компьютере много месяцев назад. Там он и живет, как числовое значение 67 в 8-битпом Глава 20 Строки 646 байте. Это третья буква в латинском алфавите, обычная аббревиатура для шестого химического элемента (углерод) и, между прочим, имя языка программирования Я 1.6). То, что имеет значение в контексте программирования с использованием строк — это наличие связи между закорючками с общепонятными значениями, так называемыми буквами, и числовыми кодами. Чтобы все окончательно запутать, одна и та же буква в разных символьных наборах может иметь разные числовые значения, н не каждый набор имеет значение для той или иной буквы, а в широком использовании находится много различных символьных наборов.
Символьный набор — это взаимное соответствие между буквой (некоторого обьцспонятпого символа) и числом. Программисты на С++ обычно считают доступным стандартный американский символьный набор (АЗСП), но С++ допускает использование и некоторых символов, которых может не оказаться в программном окружении. Например, при отсутствии таких символов как ( и (, могут использоваться ключевые слова и днграфы (~ В.З.1). Символьный набор с симво.лами не из АБСП представляет еще одну проблему. Такие языки как китайский, датский, французский, исландский, японский пс могут быть адекватно переданы с использованием только символов АЯСП.
Хуже того, символьные наборы для этих языков могут быть взаимно не согласованы. Например, буквы европейских языков, использующих латинский алфавьгг, почти укладываются в набор из 256 символов. К несчастью, в разных языках по-прежнему используются разные символьные наборы, н некоторые разные символы имеют один и тот же код. Например, французский язык (нспользующий (.айп 1) не слишком хорошо сосуществует с исландским (который поэтому требует Вагш 2). Амбициозные попытки представить все известные человеку символы в едином наборе принесли большую пользу, но даже 16-разрядный набор — такой как 11пгсоде — не может удовлетворить всех.
32-разрядные наборы, которые способны — насколько мпе известно — содержать в свое вс е символы, не нашли широкого применения. В основном подход С++ состоит в том, чтобы позволить программисту пользоваться в строках. любым символьным набором. Можно использовать расширеннын символьный набор пли переносимую числовую кодировку (6 В.З.З) 20.2.1. Особенности символов Как показано в з 13.1, строка может в качестве типа своих элементов (символов) использовать в принципе любой тип с соответствующей операцией копирования. Однако эффективность может улучшиться, а реализации могут упроститься для типов, не имеющих определяемых пользователем операций копирования.
Поэтому стандартная строка з(г(пя'требует, чтобы используемый в качестве символьного тип, нс имел пользовательских операций копирования. Это также помогает сделать простым и эффективным ВВОД/ВыВОд строк. Свойства символьного типа определяются его спаг 1га(1з (свойствами символов). с)1аг 1га(1з является специализацией шаблона: 1етр!аге<с!аэз Сй> з1гпсгсйаг 1гаггз (1; Всг с)гиг 1га11з определены в зЫ, а стандартные представлены в <з1г(пя>. Собственно универсальные спаг 1га(1з не имеют свойств, их имеют только специализации сЬаг 1га11з для конкретных символьных типов Рассмотрим с)гаг 1га11з<с)гаг>: 20.2. Символы 647 1етр!а1е<> к1гис1сйаг 1га!!я<айаг> ( 1ур еде/ сйаг сЬа г 1уре; к!айс оо!й аяя!уп (сваг 1урей, сопи! сйаг 1урей) //пиш силшола //=длясйаг 1уре // численное представление символов: 1урейе~!п1 !п1 1уре; // тип цел отсслет<ь и // значений сил~волов и1айс сйаг 1уре 1о сйаг 1уре (сопк1 !п! 1урей) О преобразование!а! всма! ига!!с !и! 1уре1о !п1 1уре (сопя! сйаг 1уреЦ; // преобразование слог в !и! ягайсьоо!ед !п1 суре(сопя1 !п1 1урей,сопя!шг гурей) //== // сравнетш слог 1уре: к1а1!с Ьоо! еу(сопк1сйаг 1урей, сопк1 сйаг 1урей) О== ига!!с Ьоо1 й (сопя1 сйаг 1урей, сопя! сйаг 1урей) // < О операции надмассиваит к[п): к1айс сйаг 1уре* топе (сйаг 1уре* к, сопи! сЬаг 1уре* я2, я!ге 1п); Ыпйс слаг 1уре* сору (сЬаг гуре' и, сопи! сйаг !уре' к2, гиге гп); к!а1!с сйаг 1уре* авгйуп (сйаг 1уре я, я!ге 1п, сйаг 1уре а); к1айс ш1сотраге(сопи! сйаг 1уре" я, сопя! сйаг 1уре*я2,ксзе 1п); ксайск!ее 1!епугй (сопк1сйаг 1уре ) ига!!ссопк1сйаг 1уре !!пй(сопягсйаг 1уре'я, ш1п, сопягсБаг 1урей'; // функции, связанные с вводом/выводолс // смегцение в потоке // позиция.
в потоке //многобайтное состояние потока 1урейе1 к1геато21 оЦ !уре; 1урейе/к1геатроя рок 1уре; 1урейе~тук1а1е 1к1а1е 1уре; // конец файла // ! если ! не равно еоЯ //многобайтное преобразование // состояния символа в р к1айс !пг 1уре ео/ () я!айс!п1 1урепо1 ео/(сопягш1 1урей1) ига!!ся1а1е 1уреуе! к1а1е(рок Йсре р); Реализация стандартного шаблона строк — Ьая!с я1г!пу Я 20.3) — опирается на эти типы и функции.
Тип, используемый для Ьая!с я1г!пд в качестве символьного, должен обеспечивать специализацию сйаг 1га!1я, которая бы поддерживала их все. Чтобы тип был сйаг 1уре, мы должны уметь получать целочисленное значение, соответствующее каждому символу. Тип этого целого — !п1 1уре, и преобразование его в сйаг 1уре и обратно выполняется функциями 1о сйаг 1уре () и 1о ш1 1уре ().
Для сйаг это преобразование тривиально. И топе (я, я2, и), и сору (я, я2, и) копируют и символов из я2 в я при помощи аяя!уп (я[!], я2[!)). Разница в том, что топе () работает правильно, даже если диапазоны [я, я+а[ и [я2, я2+и[ перекрываются. Поэтому сору () может оказаться быстрее. Это аналог функций из стандартной библиотеки С вЂ” тетсру () н теттопе () (9 19.4.6).