Целый список - линейный список, элементы которого принадлежат множеству натуральных чисел, причем некоторые элементы могут повторяться. В целых списках m – число элементов, n – размах списка, тогда разреженный список тот, в котором m<<n. Для хранения разреженных списков в компактной форме используются массивы.
Если требуется сохранить упорядоченность целых чисел, то включение и исключение элемента из какой-либо позиции вызывает сдвиг всех элементов, находящихся справа от нее. Причем целые списки могут хранить как связные линейные списки, так и кольцевые списки, посредством массива A длины не меньшей m и соответствующего дополнительного массива Next. Этот тип хранения также является компактным.
Альтернативой может служить метод хранения с использованием одного массива A, длина которого соответствует размаху N. Число, хранимое в каждой позиции A дает одновременно значение элемента списка и адрес следующего элемента, в этом случае Next оказывается излишним. Дополнительный указатель IP задает позицию первого числа в списке. Этот тип хранения называется расширенным
|
|
Глава 12. Классы ввода-вывода
Классы стандартной библиотеки
В C++ классы стандартной библиотеки разделяются на группы в соответствии со своим назначением.
1. Потоковые классы – предназначены для управления потоками данных между оперативной памятью и внешними устройствами, а также в пределах оперативной памяти.
2. Строковые классы – предназначены для удобной защищенной от ошибок работы с символьными строками
3. Контейнерные классы – реализуют наиболее распространенные структуры для хранения данных (списки, векторы, очереди). В библиотеки контейнерных классов также входят алгоритмы, использующие эти контейнеры.
4. Итераторы – предназначены для унификации доступа к элементам контейнерных и других классов.
5. Математические классы – поддерживают эффективную обработку массивов численных данных с плавающей точкой и работу с комплексными числами.
6. Диагностические классы – обеспечивают динамическую идентификацию типов и объектно-ориентированную обработку ошибок.
7. Остальные классы – обеспечивают динамическое распределение памяти и адаптацию к локальным особенностям программы, обработку функций, объектов и т.д.
Контейнерные классы, итераторы и алгоритмы классов объединяют в библиотеки шаблонов.
Потоковые классы.
Потоки в C++ отличаются от функций ввода/вывода в C, обеспечивая работу как со стандартными потоками данных, так и с типами данных, определяемыми пользователем, а также обеспечивая единообразный и понятный синтаксис. Чтение данных из потока называется извлечением, а вывод данных в поток – включением. Поток в C++ - это последовательность байтов, независимых от конкретного устройства, с которого производится считывание данных.
|
|
Обмен с потоком для увеличения скорости передачи данных производится через специальную область памяти – буфер. Передача данных выполняется при выводе после заполнения буфера и при вводе, если буфер исчерпан. По направлению обмена данных потоки делят на три группы:
· входные потоки (позволяющие вводить данные в память)
· выходные потоки (осуществляющие вывод данных из памяти)
· двунаправленные потоки
В зависимости от вида устройства, с которым работает поток данных, их делят на:
· стандартные потоки
· файловые потоки
· строковые потоки
Стандартные потоки предназначены для передачи данных с клавиатуры на экран (это: stdin - стандартный поток ввода данных, stdout - стандартный поток вывода данных и stderr - стандартный поток ошибок). Файловые потоки – для обмена информацией с файлами. Строковые потоки – для работы с массивами символов в оперативной памяти. Для поддержки этих потоков в C++ стандартная библиотека содержит иерархию классов, построенную на основе двух базовых классов:
ios – базовый класс, содержащий общие для ввода/вывода поля и методы
streambuf – обеспечивает буферизацию потоков и их взаимодействие с физическими устройствами.
От этих базовых классов наследуются классы istream и ostream для входных и выходных потоков соответственно. Эти потоки являются базовыми для iostream, который позволяет реализовывать двунаправленные потоки. Ниже в иерархии находятся файловые и строковые потоки:
· isstrinstream – класс входного строкового потока
· osstringstream – класс выходного строкового потока
· stringstream – класс двунаправленного строкового потока
· ifsteam – класс входных файловых потоков
· ofstream – класс выходных файловых потоков
· fstream – класс двунаправленных файловых потоков
Стандартный поток
Чтобы использовать стандартные потоки ввода-вывода нужно включать заголовочный файл <iostream.h>.Заголовочный файл <iostream.h> кроме описания потоков ввода-вывода содержит описание ещё и предопределенных объектов.
Объект | Класс | Описание |
cin | istream | связывается с клавиатурой (со стандартным буфером ввода) |
cout | ostream | связывается с экраном (со стандартным буфером вывода) |
cerr | ostream | связывается с экраном (стандартный не буферизованный вывод, куда направляются сообщения об ошибках) |
clog | ostream | связывается с экраном (стандартный буферизованный вывод, куда направляются сообщения об ошибках) |
Эти объекты создаются при включении в программу файла iostream. При этом становятся доступными средства ввода-вывода. Соответствующие операции << и >> определены путем перегрузки операции сдвига.
Пример 1
#include<iostream.h>
Int main()
{
int i;
cin>>i;
cout << ”Output i = ”<< i;
return 0;
}
Операции извлечения и чтения в качестве результата своего выполнения формирует ссылку на объект типа istream для извлечения и на объект типа ostream для чтения.
Файловые потоки.
Под файлом обычно подразумевается поименованная информация на внешнем носителе. Практически в С++ файл рассматривается как последовательный поток байтов. Каждый файл завершается маркером EOF или указанием числа байтов, записанных в служебную структуру данных, поддерживаемую соответствующей системой.
По способу доступа файлы делятся на последовательные и файлы с произвольным доступом. Файлы с последовательным доступом – файлы, в которых чтение и запись производятся сначала, байт за байтом. Файлы с произвольным доступом допускают чтение и запись в произвольной позиции. Стандартная библиотека содержит три класса для работы с файлами:
|
|
· Ifstream
· ofstream
· fstream
Наследуют перегруженные операции <<, >>. Использование файловых потоков в программе предполагает выполнение следующих операций:
1) создание потока
2) открытие потока и связывание его с файлом
3) обмен данных (ввод / вывод)
4) уничтожение потока
5) закрытие файла
Каждый класс файловых потоков содержит конструкторы, с помощью которых можно создавать объекты этих классов различными способами. Конструкторы без параметров создают объект соответствующего класса, не связывая его с файлом. Конструктор с параметром создает объект соответствующего класса, открывает файл с указанным именем и связывает файл с объектом.
ifstream(char *name, int mode = ios::in);
ofstream(char *name, int mode = ios::out);
fstream(char *name, int mode = ios::in [ios::out]);
Вторым параметром конструктора является режим открытия файла. Если установленное по умолчанию значение не устраивает программиста, можно указать другой, составив его из битовых масок, определенных в классе ios.
in | = 0x01; //открыт для чтения |
out | = 0x02; // открыт для записи |
ate | = 0x04; // установить указатель на конец файла |
app | = 0x08; // открыть на добавление в конец |
trune | =0x19; // если файл существует, удалить |
nocreate | = 0x20; // если файл не существует, выдать ошибку |
noreplace | = 0x40; // если файл существует, выдать ошибку |
binary | = 0x80; // открыть в двоичном режиме |
Открыть файл в программе можно с использованием конструктора, либо методом open. В open должны быть такие же параметры, как и в соответствующем конструкторе.
Пример 2
ifstream inpf(‘input.txt’,.ios::n| ios::nocreate); // использование конструктора
if(!inpf)
{
cout << “ невозможно открыть файл для чтения”;
return 1;
}
ofstream f;