Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Использование указателей на структуры




Можно объявить указатель на структуру:

// определение указателя на тип Worker

Worker *pw;

а затем присвоить ему адрес существующей переменной указанного типа:

pw = &worker; // worker – переменная типа Worker

Объявление и инициализацию указателя, как обычно, можно совместить:

Worker *pw = &worker;

Для доступа к элементам (полям) структуры через указатель используется операция -> (“стрелка”, селектор):

pw->salary = 150000;

1.2.2.3. Об операциях. и –>

Операция –> является кратким способом записи доступа к значению структуры по ее адресу. Другой, более подробный способ записи предыдущего оператора:

(*pw).salary = 150000;

Операции. и –>, наряду с операцией индексирования [], имеют наивысший приоритет среди всех операций (выше, чем унарные).

Поэтому, например, код

Worker *pw = staff;

++pw->code;

увеличит значение переменной code начальной (с нулевым индексом) структуры массива структур staff, а не значение указателя pw.

Динамические структуры и массивы структур

Память под структуру и массив структур можно выделять динамически:

Worker *pw = new Worker; // выделение памяти для структуры

pw->age=28;

pw->code=3983;

Worker *pwd = new Worker[k]; // выделение памяти для массива из k структур

Освобождение выделенной памяти осуществляется с помощью оператора delete:

delete pw;

delete [] pwd;

Обращение к полям элементов динамического массива структур можно осуществлять любым из возможных способов – с помощью операций индексирования,. или ->, на­пример:

pwd[2].age=28;

(pwd+2)->code=3983;

(*(pwd+2)).salary=35000;

(скобки необходимы, так как приоритет операций. и –> выше, чем приоритет операции *).

Легко догадаться, что способы доступа к полям элементов статического массива структур те же, поскольку массив в C++ реализован как указатель на его начало:

Worker staff[100];

...

int nAge = staff[1].age;

int iCode = (staff+2)->code;

int iAge = (*(staff+2)).age;

Динамический массив структур можно реализовать как массив указателей.

Комбинируя структуры и массивы можно строить достаточно сложные, универсальные и гибкие структуры данных.

В языке C++ структура является видом класса и обладает всеми его свойствами, но во многих случаях достаточно использовать структуры так, как они определены в языке С.

Классы

Класс можно рассматривать как сложный тип данных, включающий в себя поля данных одного или различных типов, а также функции, предназначенные для работы с ними. Переменные такого типа данных называют объектами.

Идея классов отражает внутреннюю организацию и функционирование объектов реального мира, ведь каждый предмет или процесс обладает набором характеристик (свойствами) и отличительных черт (поведением), которые можно представить данными соответствующих типов и функциями (методами работы с ними).

Введение в ООП

Применение классов лежит в основе объектно-ориентированного программирования (ООП) – программирования с использованием объектов.

Три кита ООП – инкапсуляция, наследование, полиморфизм.

Под инкапсуляцией (encapsulation) понимают объединение данных с функциями их обработки в сочетании с сокрытием ненужной для использования этих данных информации.

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

Полиморфизм заключается в возможности использовать в различных классах иерархии одно имя для обозначения сходных по смыслу действий и гибко выбирать требуемое действие во время выполнения про­граммы.

2. Язык C++: ввод-вывод

Известно, что операции ввода-вывода имеют сильную аппаратно-операционную зависимость. По этой причине в C/C++ средства ввода-вывода отделены от языка и вынесены в отдельные библиотеки. В языке C, предшественнике C++, операции ввода-вывода были реали­зованы с помощью набора стандартных функций библиотеки stdio. В C++ для ввода или вывода данных используется набор стандартных классов, кото­рые объединены в объектно-ориентированной библиотеке iostream.

Поскольку C++ в основном совместим с C, в нем доступны стандартные функции ввода-вывода языка C.

В C/C++ реализован механизм ввода-вывода, не зависящий от особенностей работы разнообразных устройств, осуществляющих обмен данными с внешними носителями информации. Программа работает не с физическими, а с логическими устройствами ввода-вывода – потоками. Название это, возможно, произошло от того, что информация вводится и выводится в виде потока бай­тов – значение за значением. Ввод информации осуществляется из одного или нескольких входных потоков, вывод программа производит в один или несколько выходных потоков. Поток можно связать с файлом. Все устройства ввода-вывода различны, но все потоки функционируют одинаково. Одна и та же функция может выводить данные и на экран и в файл, читать данные с клавиатуры и из файла. Различия заключаются только в том, как создаются потоки и как они привязываются к нужным файлам.

Потоки

Поток – это своеобразный унифицированный интерфейс между программой и физическими устройствами, позволяющий программисту не думать об особенностях переноса данных от источника к приемнику.

Поток определяется как последовательность байтов и не зависит от конкретного устройства, с которым взаимодействует программа при передаче данных (оперативная память, файл на диске, клавиатура или принтер). Ввод данных называют извлечением из потока или чтением, вывод данных – помещением (включением) в поток или записью. Взаимодействие с потоком для увеличения скорости передачи данных производится, как правило, через специальную область оперативной памяти – буфер. Фактическая передача данных выполняется при выводе после заполнения буфера, а при вводе – если буфер исчерпан.

По направлению передачи данных потоки можно разделить на входные (данные вводятся в память), выходные (данные выводятся из памяти) и двунаправленные (допускающие как ввод, так и вывод данных).

По виду устройств, с которыми работает поток, можно разделить потоки на стандартные, файловые и строковые.

Стандартные потоки предназначены для передачи данных от клавиатуры и на экран дисплея, файловые потоки – для обмена информацией с файлами, расположенными на носителях данных (например, на дисках), а строковые потоки – для работы с массивами символов в оперативной памяти.

Для поддержки потоков библиотека C++ содержит иерархию классов, построенную на основе двух базовых классов – ios и streambuf. Класс ios содержит общие для ввода и вывода поля и методы, класс streambuf обеспечивает буферизацию потоков и их взаимодействие с физическими устройствами. От этих классов наследуется класс istream для входных потоков и ostream – для выходных. Два последних класса являются базовыми для класса iostream, реализующего двунаправленные потоки. Ниже в иерархии классов располагаются классы файловых (ifstream, ofstream, fstream) и строковых потоков.

Стандартные потоки

Класс istream реализует поток ввода, класс ostream – поток вывода. Эти классы определены в файле заголовков iostream.h. Библиотека потоков ввода-вывода определяет четыре глобальных системных объекта: cin, cout, cerr и clog. При этом cin представляет стандартный входной поток, cout, cerr и clog – стандартный выходной поток. Объекты cout, cerr и clog принадлежат к классу ostream, объект cin – к классу istream. По умолчанию стандартный входной поток связан с клавиатурой, стандартный выходной поток – с экраном. Наличие нескольких объектов для вывода информации обеспечивает возможность разделять обычный вывод и, скажем, сообщения об ошибках (cerr и clog предназначены именно для этого).

Разница между cout и cerr существенна в операционных системах типа Unix – они используют разные дескрипторы для вывода. В других системах они существуют в основном для совместимости.

Вывод в стандартный выходной поток может осуществляться, например, с помощью операции >>, а ввод из стандартного входного потока – с помощью операции <<.

2.3. Операции >> и <<

Операция >> для класса istream и операция << для класса ostream определены для всех встроенных типов языка C++ и для указателей на стро­ку символов (char*). Эти операции – операции побитового сдвига, переопределенные ("перегруженные") для входных и выходных потоков. Перегрузка операций, реализованная в C++, позволяет придать операциям дополнительный смысл и расширить область их действия. Если мы хотим использовать такую же запись для ввода и вывода других типов данных, определенных в программе, для них нужно определить ("перегрузить") эти операции.

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

Если в качестве второго операнда операции >> используется переменная числового типа (int, long, short, double, float), введенная символьная последовательность преобразуется к требуемому числовому типу (естественно, для корректного выполнения данной операции вводимая последовательность символов должна представлять собой запись числа соответствующего типа). При вводе чисел вещественных типов (double, float) для разделения целой и дробной части следует использовать точку, для ввода чисел с нулевым значением дробной части можно использовать соответствующие целые числа. Правым ограничителем при вводе числового значения является первый разделитель или первый недопустимый символ.

Операция вывода << помещает последовательность символов в выходной поток, при этом для всех числовых типов выполняется преобразование из числового формата в соответствующее символьное представление.

Операция << возвращает в качестве результата ссылку на поток вывода. Это позволяет упрощать запись выражений, соединяющих несколько операций вывода, например:

cout << x << ' ' << y;

что в более подробной записи может выглядеть так:

((cout << x) << ' ') << y;

Аналогично реализована операция ввода <<, позволяющая соединять несколько операций ввода:

cin >> x >> y;

При вводе данных с помощью операции >> по умолчанию пробельные символы воспринимаются как разделители, нельзя, например, ввести строку, содержащую пробел, или ввести присутствующий во входном потоке пробел в переменную типа char. Для того, чтобы иметь возможность ввода пробельных символов с помощью операции >>, необходимо для соответствующего входного потока изменить формат ввода, установленный по умолчанию.

Файловые потоки

В библиотеке C++ для ввода-вывода файлов существуют классы ifstream (для файловых входных потоков), ofstream (для файловых выходных потоков) и fstream (для файловых двунаправленных потоков). Эти классы – наследники, соответственно, классов istream, ostream и iostream, которые, в свою очередь, наследуют свойства класса ios. Это означает, что классы файлового ввода-вывода наследуют соответствующие операции и методы ввода-вывода, поля и способы фор­матирования и т.д. Классы файлового ввода-вывода определены в файле заголовков fstream.h.

Использование файлов в программе предполагает выполнение следующих действий:

- создание файлового потока;

- открытие потока и связывание его с файлом;

- передача данных (ввод/вывод);

- закрытие файла;

- уничтожение потока.

В программе файловый поток объявляется как объект одного из классов файлового ввода-вывода (ifstream, ofstream или fstream):

ifstream f1; // создание потока f1 для файлового ввода

ofstream f2; // создание потока f2 для файлового вывода

Как и любые другие объекты, потоки могут создаваться статически (как f1 и f2 в предыдущем примере) или динамически (с помощью операции new):

ofstream *f3 = new ofstream; // динамическое создание потока f3

// для файлового вывода

Классы файлового ввода-вывода содержат специальные операции и методы работы с файлами – открытия, проверки состояния, работы с текущей позицией, закрытия файлов, а также ввода-вывода и форматирования информации. Большинство из них унаследовано от классов-предков (ios, istream, ostream). Связывание потока с конкретным файлом осуществляется одним из двух возможных способов – либо при создании потока:

ofstream f4("d:\\test4.txt"); // создание потока f4 для файлового вывода,

// открытие и связывание его с файлом

либо при открытии уже созданного потока с помощью метода open:

f1.open("d:\\test5.txt"); // открытие ранее созданного потока f1

// и связывание его с файлом

И в том и другом случае указывается имя файла и, если необходимо, режимы его открытия, описанные в разделе 11.4.3.

Передача данных выполняется операциями >> и << или методами ввода-вывода, описанными в разделе 11.4.5. Закрытие файла происходит либо посредством выполнения метода close:

f4.close();

f3->close();

либо автоматически при уничтожении потока (при завершении программы или при удалении динамически созданного потока с помощью delete):

delete f3;





Поделиться с друзьями:


Дата добавления: 2016-07-29; Мы поможем в написании ваших работ!; просмотров: 678 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Сложнее всего начать действовать, все остальное зависит только от упорства. © Амелия Эрхарт
==> читать все изречения...

2215 - | 2091 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.01 с.