|
Программирование >> Инициализация объектов класса, структура
st = st - len; Можно попробовать исправить эту ошибку: cout << len << : << st; Теперь наша программа выдает что-то осмысленное, но не до конца. Ответ выглядит так: 18: ена бутылки вина Мы забыли учесть, что заключительный нулевой символ не был включен в подсчитанную длину. st должен быть смещен на длину строки плюс 1. Вот, наконец, правильный оператор: st = st - len - 1; а вот и и правильный результат: 18: Цена бутылки вина Однако нельзя сказать, что наша программа выглядит элегантно. Оператор st = st - len - 1; добавлен для того, чтобы исправить ошибку, допущенную на раннем этапе проектирования программы, - непосредственное увеличение указателя st. Этот оператор не вписывается в логику программы, и код теперь трудно понять. Исправления такого рода часто называют заплатками - нечто, призванное заткнуть дыру в существующей программе. Гораздо лучшим решением было бы пересмотреть логику. Одним из Во второй версии программы эта погрешность устранена. Программа успешно #include <iostream> заканчивается, однако полученный результат неправилен. Где мы не правы на этот раз? const char *st = Цена бут1лки вина\n ; int main() { int len = 0; while ( *st++ ) ++len; cout << len << : << st << endl; return 0; Ошибка состоит в том, что после завершения цикла указатель st адресует не исходный символьный литерал, а символ, расположенный в памяти после завершающего нуля этого литерала. В этом месте может находиться что угодно, и выводом программы будет случайная последовательность символов. 3.4.2. Класс string Как мы только что видели, применение встроенного строкового типа чревато ошибками и не очень удобно из-за того, что он реализован на слишком низком уровне. Поэтому достаточно распространена разработка собственного класса или классов для представления строкового типа - чуть ли не каждая компания, отдел или индивидуальный проект имели свою собственную реализацию строки. Да что говорить, в нред1дущих двух изданиях этой книги м1 делали то же самое! Это порождало проблема: совместимости и переносимости программ. Реализация стандартного класса string стандартной библиотекой С++ призвана была положить конец этому изобретению велосипедов. Попробуем специфицировать минимальный набор операций, которыми должен обладать класс string: инициализация массивом символов (строкой встроенного тина) или другим объектом тина string. Встроенный тин не обладает второй возможностью; копирование одной строки в другую. Для встроенного типа приходится использовать функцию strcpy(); доступ к отдельным символам строки для чтения и записи. Во встроенном массиве для этого применяется операция взятия индекса или косвенная адресация; сравнение двух строк на равенство. Для встроенного типа используется функция strcmp() ; конкатенация двух строк, получая результат либо как третью строку, либо вместо одной из исходных. Для встроенного типа применяется функция strcat() , однако чтобы получить результат в новой строке, необходимо последовательно задействовать функции strcpy() и strcat() ; вычисление длины строки. Узнать длину строки встроенного типа можно с помощью функции strlen() ; возможность узнать, пуста ли строка. У встроенных строк для этой цели char str = 0; ... if ( ! str ! *str ) приходится проверять два условия: return; вариантов в нашем случае может быть определение второго указателя, инициализированного значением st: const char *p = st; Теперь p можно использовать в цикле вычисления длины, оставив значение st неизменным: while ( *p++ ) #include <string> инициализированной строкой символов: string st( Цена бут1лки вина\n ) ; Длину строки возвращает функция-член size() (длина не включает завершающий cout << Длина << st << : << st.size() << символов, вкчая символ новой строки\п ; нулевой символ). Вторая форма определения строки задает пустую строку: string st2; пустая строка Как мы узнаем, пуста ли строка? Конечно, можно сравнить ее длину с 0: if ( ! st.size() ) правильно: пустая Однако есть и специальный метод empty() , возвращающий true для пустой строки и false для непустой: if ( st.empty() ) правильно: пустая Третья форма конструктора инициализирует объект типа string другим объектом того же типа: string st3 ( st ); Строка st3 инициализируется строкой st. Как мы можем убедиться, что эти строки совпадают? Воспользуемся оператором сравнения (==): if ( st == st3 ) инициализация сработала Класс string стандартной библиотеки С++ реализует все перечисленные операции (и гораздо больше, как мы увидим в главе 6). В данном разделе мы научимся пользоваться основными операциями этого класса. Для того чтобы использовать объекты класса string, необходимо включить соответствующий заголовочный файл: #include <string> Вот пример строки из предыдущего раздела, представленной объектом типа string и
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |