Строки на основе char массива и класса string




В языке С++ есть два вида строк. Во-первых, в нем предусмотрены строки, завершающиеся нулевым байтом (null-terminated string), представляющие собой массивы символов, последним элементом которых является нулевой байт. Это единственный вид строки, предусмотренный в языке С. В языке С++ определен также класс string, который реализует объектно-ориентированный подход к обработке строк.

Объявляя массив символов, следует зарезервировать одну ячейку для нулевого байта, т. е. указать размер, на единицу больше, чем длина наибольшей предполагаемой строки. Например, чтобы объявить массив str, предназначенный для хранения строки, состоящей из 10 символов, следует выполнить следующий оператор:

char str[11];

В этом объявлении предусмотрена ячейка, в которой будет записан нулевой байт.

Строка символов, заключенных в двойные кавычки, например, "Здравствуйте, я ваша тетя!", называется строковой константой (string constant).

В языке C/C++ предусмотрен богатый выбор функций для работы со строками. Самыми распространенными среди них являются следующие.

 

Эти функции объявлены в стандартном заголовочном файле string.h. В программах на языке С++ используется также заголовочный файл <cstring>.

Не следует путать нуль (о) и нулевой байт (\о), или нулевой символ. Признаком конца строки является именно нулевой байт. Если не указать обратную косую черту, нуль будет считаться обычным символом.

Массивы строк используются довольно часто. Например, сервер базы данных может сравнивать команды, введенные пользователем, с массивом допустимых команд. Для того чтобы создать массив строк, завершающихся нулевым байтом, необходим двухмерный массив символов. Максимальное значение левого индекса задает количество строк, а правого индекса — максимальную длину каждой строки.

Ниже во фрагменте объявлен массив, состоящий из 30 строк, каждая из которых может содержать 9 до 79 символов и последний байт, содержащий 0:

char str_array[30] [80];

Пример массива строк:

char star[DAYS][MAX] =

{ "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье" };

Шаблонный класс string. В действительности, класс string представляет собой специализацию более общего шаблонного класса basic_string. Существует две специализации типа basic_string:

• тип string, который поддерживает 8-битовые символьные строки;

• тип wstring, который поддерживает строки, образованные двухбайтовыми символами. Существует три причины для включения в C++ стандартного класса string:

• непротиворечивость данных (строка определяется самостоятельным типом данных);

• удобство (программист может использовать стандартные С++ операторы);

• безопасность (границы массивов отныне не будут нарушаться).

Для использования строковых классов C++ необходимо включить в программу заголовок. Прототипы трех самых распространенных конструкторов класса string имеют следующий вид:

string();

string(const char *str);

string(const string &str);

Первая форма конструктора создает пустой объект класса string. Вторая форма создает string -объект из строки с завершающим нулем, адресуемой параметром str. Эта форма конструктора обеспечивает преобразование из строки с завершающим нулем в объект типа string.

 

 

Третья создает string -объект из другого string -объекта. Для объектов класса string определены следующие операторы

Эти операторы позволяют использовать объекты типа string в обычных выражениях и позволяют избежать вызова таких функций, как strcpy() или strcat(). В общем случае, в выражениях можно смешивать string -объекты и строки с завершающим нулем. Оператор "+" можно использовать для конкатенации одного string -объекта с другим или string -объекта со строкой, созданной в C -стиле.

Ввод и вывод осуществляются путем, схожим с применяемым для строкового типа. Операции << и >> перегружены для использования с объектами класса string, метод getline() принимает ввод, который может содержать пробелы или несколько строк.

Доступ к отдельным символам объектов класса string можно получить разными способами. В следующем примере показан доступ с использованием метода at(). Можно также использовать перегруженную операцию [], которая позволяет рассматривать объект класса string как массив. Однако операция [] не предупредит вас, если вы попытаетесь получить доступ к символу, лежащему за пределами массива (например, после конца строки):

string str;

str (“Мы изучаем С++!”);

cout << str.at(5);

Некоторые методы класса string представлены.

 

 

20.Перегрузка унарных операций Унарные операции – это операции которые имеют по одному операнду.Пример:a++;//инфиксный инкремент,++a;//постфиксный инкремент,--a;//постфиксный декремент,a--;//инфиксный декремент,-a;//унарный минус операция знака.мы видим, что во всех этих операциях всего по одному операнду а.Если унарная операция перегружается как функция-член, то она не должна иметь аргументов, так как в этом случае ей передается неявный аргумент-указатель this на текущий объект.Если унарная операция перегружается дружественной функцией, то она должна иметь один аргумент – объект, для которого она выполняется. Таким образом, для любой унарной операции @ aa@ или @aa может интерпретироваться или как aa.operator@(), или как operator@(aa). Если определена и та, и другая, то и aa@ и @aa являются ошибками.Функция- член класса Дружественная функцияclass А{...public:A operator!();...}; class A {... public: friend A operator!(A);... }; 21. Перегрузка бинарных операций Бинарный оператор — это функция от двух параметров, параметрами которой являются левый и правый операнды оператора. Перегрузка операций с двумя аргументами очень похожа на перегрузку унарных операций. тип‐имя_класса operator∆(список аргументов) { // операции } В перегруженных бинарных операциях всегда вызывается метод левого операнда. Объект, стоящий справа от знака операции, должен быть передан в функцию в качестве аргумента. Пример перегрузки операций +, =+, < представлен ниже. //перегрузка операций +, =+, #include <iostream> using namespace std; class Rasst // класс русских мер длины 18 века {private: int arshin, vershok; public: Rasst(): arshin(0), vershok(0) { } // конструктор без параметров Rasst(int ar, int ver) { // конструктор с двумя параметрами If (ver >= 16) {ver ‐= 16; ar++;} arshin = ar; vershok = ver; } void getras() { // получение информации от пользователя 61 cout << "\nВведите аршины: "; cin >> arshin; cout << "Введите вершки: "; cin >> vershok; } void showras() { // показ информации cout << arshin << "~" << vershok << endl; } Rasst operator+(Rasst) const; // сложение длин bool operator< (Rasst d2) const } //сравнение двух длин void operator+=(Rasst d2); //сложениие с присваиванием }; Rasst Rasst::operator+(Rasst d2) const { // сложение двух длин int a = arshin + d2.arshin; // складываем футы int v = vershok + d2.vershok; // складываем дюймы return Rasst(a, v); // создаем и возвращаем временную переменную } bool Rasst::operator < (Rasst d2) const {// сравнение двух длин float t1 = arshin + vershok / 16; float t2 = d2.arshin + d2.vershok / 16; return (t1 < t2)? true: false; } void Rasst::operator+=(Rasst d2) { arshin += d2.arshin; vershok += d2.vershok; } int main() {Rasst ras1, ras3, ras4; // определяем переменные ras1.getras(); // получаем информацию Rasst ras2(11, 12); // переменная с конкретным значением ras3 = ras1 + ras2; // складываем две переменные ras4 = ras1 + ras2 + ras3; // складываем несколько переменных cout << "ras1 = "; ras1.showras(); // показываем результат cout << "ras2 = "; ras2.showras(); cout << "ras3 = "; ras3.showras(); cout << "ras4 = "; ras4.showras(); return 0; }

 

22.Перегрузка операций индексации массива [] В С++ перегрузка рассматривается как бинарный оператор. Его следует перегружать только с помощью функции-члена. Пример:char operator [](int i){return str[i];}Где в аргументе функции передается индекс массива. Тип int не обязателен, но т. к. индексируется целыми числами, то используют его. Достоинство – с его помощью можно предотвратить выход за пределы массива.Нельзя использовать friend.Оператор [] может быть перегружен, чтобы получать единственный аргумент произвольного типа и возвращать произвольный тип в качестве своего значения.class String { private:char* s;public:String(char*);char operator[](int n) const; }; // n-й символchar String::operator[](int n){ // Здесь должна выполняться проверка диапазонаreturn s[n]; }Поскольку оператор [] может вызываться лишь с одним аргументом, для имитации многомерных массивов часто применяют анонимные экземпляры, что позволяет создать произвольное кол-во псевдоаргументов.

23.Преобразование типов от основного к пользовательскому. Для перехода от основного типа к определенному пользователем типу используется конструктор с одним аргументом. Его иногда называют конструктором преобразования. Пример такого конст- руктора представлен в листинге 2.#include <iostream>using namespace std;class Rasst // класс русских мер длины {private: const float artm = 0.7112F; //коэффициент перевода метров в аршиныint arshin; int vershok;public:Rasst(): arshin(0), vershok(0) { } // конструктор без параметровRasst(float meters) {// конструктор с одним параметром, переводящий метры в аршины и вершки (конструк‐ тор преобразования)float f_arshin = meters / artm; // переводим в аршиныarshin = int(f_arshin); // берем число полных аршиновvershok = 16 * (f_arshin — arshin); // остаток — это вершки }Rasst(int ar, int ver) {// конструктор с двумя параметрамиif(ver >= 16) {ver ‐= 16; ar++;} arshin = ar; vershok = ver; } void getras() {// получение информации от пользователяcout << "\nВведите аршины: "; cin >> arshin;cout << "Введите вершки: "; cin >> vershok; }void showras() { cout << arshin << "~" << vershok << endl; }operator float() const// оператор для перевода аршинов в метры {float f_arshin = vershok / 16; // вершки в аршиныf_arshin += static_cast(arshin); // + целые аршиныreturn f_arshin * artm; // переводим в метры } };int main() {float mtrs;Rasst ras1 = 2.35F; // используется конструктор, переводящий метры в аршины и вершкиcout << "\nras1 = ";ras1.showras();mtrs = static_cast(ras1); // используется оператор перевода в метрыcout << "\nras1 = " << mtrs << " meters\n";Rasst ras2(5, 19); // используеется конструктор с двумя параметрамиmtrs = ras2; // используется неявный перевод типаcout << "\nras2 = " << mtrs << " meters\n";// ras2 = mtrs; // а вот это ошибка — так делать нельзяreturn 0; }

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-10-12 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: