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

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

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

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

Если тип char занимает 1 байт,int – 4 и double – 8, то прибавление 2 к указателям на char, int и double увеличит ихзначение соответственно на 2, 8 и 16. Как это можно интерпретировать? Если объектыодного типа расположены в памяти друг за другом, то увеличение указателя на 1приведет к тому, что он будет указывать на следующий объект. Поэтому арифметическиедействия с указателями чаще всего применяются при обработке массивов; в любыхдругих случаях они вряд ли оправданы.Вот как выглядит типичный пример использования адресной арифметики при перебореэлементов массива с помощью итератора:int ia[10];89С++ для начинающих90int *iter = &ia[0];int *iter_end = &ia[10];while (iter != iter_end) {do_something_with_value (*iter);++iter;}Упражнение 3.8int ival = 1024, ival2 = 2048;Даны определения переменных:int *pi1 = &ival, *pi2 = &ival2, **pi3 = 0;Что происходит при выполнении нижеследующих операций присваивания? Допущены(a) ival = *pi3;(b) *pi2 = *pi3;(c) ival = pi2;(e) pi1 = *pi3;(f) ival = *pi1;(g) pi1 = ival;ли в данных примерах ошибки?(d) pi2 = *pi1;(h) pi3 = &pi2;Упражнение 3.9Работа с указателями – один из важнейших аспектов С и С++, однако в ней легкоpi = &ival;допустить ошибку.

Например, кодpi = pi + 1024;почти наверняка приведет к тому, что pi будет указывать на случайную область памяти.Что делает этот оператор присваивания и в каком случае он не приведет к ошибке?Упражнение 3.10Данная программа содержит ошибку, связанную с неправильным использованиемint foobar(int *pi) {*pi = 1024;return *pi;}int main() {int *pi2 = 0;int ival = foobar(pi2);return 0;указателей:}В чем состоит ошибка? Как можно ее исправить?С++ для начинающихУпражнение 3.11Ошибки из предыдущих двух упражнений проявляются и приводят к фатальнымпоследствиям из-за отсутствия в С++ проверки правильности значений указателей вовремя работы программы. Как вы думаете, почему такая проверка не была реализована?Можете ли вы предложить некоторые общие рекомендации для того, чтобы работа суказателями была более безопасной?3.4. Строковые типыВ С++ поддерживаются два типа строк – встроенный тип, доставшийся от С, и классstring из стандартной библиотеки С++.

Класс string предоставляет гораздо большевозможностей и поэтому удобней в применении, однако на практике нередки ситуации,когда необходимо пользоваться встроенным типом либо хорошо понимать, как онустроен. (Одним из примеров может являться разбор параметров командной строки,передаваемых в функцию main(). Мы рассмотрим это в главе 7.)3.4.1. Встроенный строковый типКак уже было сказано, встроенный строковый тип перешел к С++ по наследству от С.Строка символов хранится в памяти как массив, и доступ к ней осуществляется припомощи указателя типа char*.

Стандартная библиотека С предоставляет набор функций// возвращает длину строкиint strlen( const char* );// сравнивает две строкиint strcmp( const char*, const char* );// копирует одну строку в другуюдля манипулирования строками. Например:char* strcpy( char*, const char* );Стандартная библиотека С является частью библиотеки С++.

Для ее использования мыдолжны включить заголовочный файл:#include <cstring>Указатель на char, с помощью которого мы обращаемся к строке, указывает насоответствующий строке массив символов. Даже когда мы пишем строковый литерал,напримерconst char *st = "Цена бутылки вина\n";компилятор помещает все символы строки в массив и затем присваивает st адрес первогоэлемента массива. Как можно работать со строкой, используя такой указатель?Обычно для перебора символов строки применяется адресная арифметика.

Посколькустрока всегда заканчивается нулевым символом, можно увеличивать указатель на 1, покаочередным символом не станет нуль. Например:91С++ для начинающихwhile (*st++ ) { ... }st разыменовывается, и получившееся значение проверяется на истинность. Любоеотличное от нуля значение считается истинным, и, следовательно, цикл заканчивается,когда будет достигнут символ с кодом 0. Операция инкремента ++ прибавляет 1 куказателю st и таким образом сдвигает его к следующему символу.Вот как может выглядеть реализация функции, возвращающей длину строки. Отметим,что, поскольку указатель может содержать нулевое значение (ни на что не указывать),int string_length( const char *st ){int cnt = 0;if ( st )while ( *st++ )++cnt;return cnt;перед операцией разыменования его следует проверять:}Строка встроенного типа может считаться пустой в двух случаях: если указатель настроку имеет нулевое значение (тогда у нас вообще нет никакой строки) или указывает намассив, состоящий из одного нулевого символа (то есть на строку, не содержащую ниодного значимого символа).// pc1 не адресует никакого массива символовchar *pc1 = 0;// pc2 адресует нулевой символconst char *pc2 = "";Для начинающего программиста использование строк встроенного типа чреватоошибками из-за слишком низкого уровня реализации и невозможности обойтись безадресной арифметики.

Ниже мы покажем некоторые типичные погрешности,допускаемые новичками. Задача проста: вычислить длину строки. Первая версия неверна.#include <iostream>Исправьте ее.const char *st = "Цена бутылки вина\n";int main() {int len = 0;while ( st++ ) ++len;cout << len << ": " << st;return 0;}В этой версии указатель st не разыменовывается. Следовательно, на равенство 0проверяется не символ, на который указывает st, а сам указатель. Поскольку изначальноэтот указатель имел ненулевое значение (адрес строки), то он никогда не станет равнымнулю, и цикл будет выполняться бесконечно.92С++ для начинающихВо второй версии программы эта погрешность устранена.

Программа успешно#include <iostream>заканчивается, однако полученный результат неправилен. Где мы не правы на этот раз?const char *st = "Цена бутылки вина\n";int main(){int len = 0;while ( *st++ ) ++len;cout << len << ": " << st << endl;return 0;}Ошибка состоит в том, что после завершения цикла указатель st адресует не исходныйсимвольный литерал, а символ, расположенный в памяти после завершающего нуля этоголитерала. В этом месте может находиться что угодно, и выводом программы будетслучайная последовательность символов.st = st – len;Можно попробовать исправить эту ошибку:cout << len << ": " << st;Теперь наша программа выдает что-то осмысленное, но не до конца. Ответ выглядит так:18: ена бутылки винаМы забыли учесть, что заключительный нулевой символ не был включен в подсчитаннуюдлину.

st должен быть смещен на длину строки плюс 1. Вот, наконец, правильныйоператор:st = st – len - 1;а вот и и правильный результат:18: Цена бутылки винаОднако нельзя сказать, что наша программа выглядит элегантно. Операторst = st – len - 1;добавлен для того, чтобы исправить ошибку, допущенную на раннем этапепроектирования программы, – непосредственное увеличение указателя st. Этот операторне вписывается в логику программы, и код теперь трудно понять. Исправления такогорода часто называют заплатками – нечто, призванное заткнуть дыру в существующейпрограмме. Гораздо лучшим решением было бы пересмотреть логику.

Одним из93С++ для начинающихвариантов в нашем случае можетинициализированного значением st:94бытьопределениевторогоуказателя,const char *p = st;Теперь p можно использовать в цикле вычисления длины, оставив значение stнеизменным:while ( *p++ )3.4.2. Класс stringКак мы только что видели, применение встроенного строкового типа чревато ошибками ине очень удобно из-за того, что он реализован на слишком низком уровне. Поэтомудостаточно распространена разработка собственного класса или классов дляпредставления строкового типа – чуть ли не каждая компания, отдел илииндивидуальный проект имели свою собственную реализацию строки.

Да что говорить, впредыдущих двух изданиях этой книги мы делали то же самое! Это порождало проблемысовместимости и переносимости программ. Реализация стандартного класса stringстандартной библиотекой С++ призвана была положить конец этому изобретениювелосипедов.Попробуем специфицировать минимальный набор операций, которыми должен обладатькласс string:•инициализация массивом символов (строкой встроенного типа) или другимобъектом типа string. Встроенный тип не обладает второй возможностью;•копирование одной строки в другую. Для встроенного типа приходитсяиспользовать функцию strcpy();•доступ к отдельным символам строки для чтения и записи. Во встроенноммассиве для этого применяется операция взятия индекса или косвенная адресация;•сравнение двух строк на равенство. Для встроенного типа используетсяфункция strcmp();•конкатенация двух строк, получая результат либо как третью строку, либовместо одной из исходных.

Для встроенного типа применяется функция strcat(),однако чтобы получить результат в новой строке, необходимо последовательнозадействовать функции strcpy() и strcat();•вычисление длины строки. Узнать длину строки встроенного типа можно спомощью функции strlen();•возможность узнать, пуста ли строка. У встроенных строк для этой целиchar str = 0;//...if ( ! str || ! *str )приходится проверять два условия:return;С++ для начинающих95Класс string стандартной библиотеки С++ реализует все перечисленные операции (игораздо больше, как мы увидим в главе 6).

В данном разделе мы научимся пользоватьсяосновными операциями этого класса.Для того чтобы использовать объектысоответствующий заголовочный файл:классаstring,необходимо включить#include <string>Вот пример строки из предыдущего раздела, представленной объектом типа string и#include <string>инициализированной строкой символов:string st( "Цена бутылки вина\n" );Длину строки возвращает функция-член size() (длина не включает завершающийcout <<<<<<<<"Длина "st": " << st.size()" символов, включая символ новой строки\n";нулевой символ).Вторая форма определения строки задает пустую строку:string st2; // пустая строкаКак мы узнаем, пуста ли строка? Конечно, можно сравнить ее длину с 0:if ( ! st.size() )// правильно: пустаяОднако есть и специальный метод empty(), возвращающий true для пустой строки иfalse для непустой:if ( st.empty() )// правильно: пустаяТретья форма конструктора инициализирует объект типа string другим объектом тогоже типа:string st3( st );Строка st3 инициализируется строкой st.

Как мы можем убедиться, что эти строкисовпадают? Воспользуемся оператором сравнения (==):if ( st == st3 )// инициализация сработалаС++ для начинающихКак скопировать одну строку в другую? С помощью обычной операции присваивания:st2 = st3; // копируем st3 в st2Для конкатенации строк используется операция сложения (+) или операция сложения сприсваиванием (+=).

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

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

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

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