|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Потоковые итераторы. Классы ostream_iterator и istream_iteratorПотоковые итераторы Потоковые итераторы позволяют интерпретировать файлы и устройства ввода/ вывода (потоки cin и cout), как итераторы. А значит, можно использовать файлы и устройства ввода/вывода в качестве параметров алгоритмов! Основное предназначение входных и выходных итераторов — как раз-таки поддержка классов потоковых итераторов. С их помощью можно осуществлять применение соответствующих алгоритмов напрямую к потокам ввода/вывода. Потоковые итераторы — это, на самом деле, объекты шаблонных классов разных типов ввода/вывода. Существует два потоковых итератора: ostream_iterator и istream_iterator. Рассмотрим их по порядку. Класс ostream_iterator Объект этого класса может использоваться в качестве параметра любого алгоритма, который имеет дело с выходным итератором. В следующем небольшом примере мы используем его как параметр copy(). Листинг 15.24. Программа OUTITER // outiter.cpp // Демонстрация ostream_iterator #include <iostream> #include <algorithm> #include <list> using namespace std;
int main() { int arr[] = { 10, 20, 30, 40, 50 }; list<int> theList;
for(int j=0; j<5; j++) //перенести массив в список theList.push_back(arr[j]);
ostream_iterator<int> ositer(cout, ", "); //итератор //ostream cout << "\nСодержимое списка: "; copy(theList.begin(), theList.end(), ositer); //вывод //списка cout << endl; return 0; }
Мы определяем итератор ostream для чтения значений типа int. Двумя параметрами конструктора являются поток, в который будут записываться значения, и строка, которая будет выводиться вслед за каждым из них. Значением потока обычно является имя файла или cout; в данном случае это cout. При записи в этот поток может использоваться строка-разделитель, состоящая из любых символов. Здесь мы используем запятую и пробел. Алгоритм copy() копирует содержимое списка в поток cout. Итератор выходного потока используется в качестве его третьего аргумента и является именем объекта назначения. На экране в результате работы программы мы увидим: Содержимое списка: 10, 20, 30, 40, 50, Листинг 15.25. Программа FOUTITER // foutiter.cpp // Демонстрация работы ostream_iterator с файлами #include <fstream> #include <algorithm> #include <list> using namespace std;
int main() { int arr[] = { 11, 21, 31, 41, 51 }; list<int> theList;
for(int j=0; j<5; j++) //Передача данных theList.push_back(arr[j]); //из массива в список ofstream outfile("ITER.DAT"); //создание файлового объекта
ostream_iterator<int> ositer(outfile, " "); //итератор //записать список в файл copy(theList.begin(), theList.end(), ositer); return 0; }
Необходимо определить файловый объект класса ofstream и ассоциировать его с конкретным файлом (в программе ассоциируем его с файлом ITER.DAT). При записи в файл желательно использовать удобочитаемые разделители. Здесь мы между элементами вставляем просто символ пробела. Вывод на экран в этой программе не производится, но с помощью любого текстового редактора можно просмотреть содержимое файла ITER.DAT: 11 21 31 41 51 Класс istream_iterator Объект этого класса может использоваться в качестве параметра любого алгоритма, работающего с входным итератором. На примере программы INITER покажем, как такие объекты могут являться сразу двумя аргументами алгоритма copy(). Введенные с клавиатуры (поток cin) числа в формате с плавающей запятой сохраняются в контейнере типа список. Листинг 15.26. Программа INITER // initer.cpp // Демонстрация istream_iterator #include <iostream> #include <list> #include <algorithm> using namespace std;
int main() { list<float> fList(5); // неинициализированный список
cout << "\nВведите 5 чисел (типа float): "; // итераторы istream istream_iterator<float> cin_iter(cin); // cin istream_iterator<float> end_of_stream; //eos (конец потока) // копировать из cin в fList copy(cin_iter, end_of_stream, fList.begin());
cout << endl; // вывести fList ostream_iterator<float> ositer(cout, "--"); copy(fList.begin(), fList.end(), ositer); cout << endl; return 0; }
Взаимодействие программы с пользователем может выглядеть, например, следующим образом: Введите 5 чисел (типа float): 1.1 2.2 3.3 4.4 5.5 1.1--2.2--3.3--4.4--5.5-- Для copy() необходимо указывать и верхний, и нижний предел диапазона значений, поскольку данные, приходящие с cin, являются исходными, а не конечными. Программа начинается с того, что мы соединяем istream_iterator с потоком cin, который определен с помощью конструктора с одним параметром как cin_ iter. Но что у нас с концом диапазона? Используемый по умолчанию конструк- тор класса stream_iterator без аргументов выполняет здесь особую роль. Он всегда создает объект istream_iterator для указания конца потока. Как пользователь сообщает об окончании ввода данных? Нажатием комбинации клавиш Ctrl+Z, в результате чего в поток передается стандартный символ конца файла. Иногда требуется нажать Ctrl+Z несколько раз. Нажатие Enter не приведет к установке признака окончания файла, хотя и поставит ограничитель чисел. ostream_iterator используется для вывода содержимого списка. Впрочем, для этих целей можно использовать множество других инструментов. Любые операции вывода на экран, даже такие, как просто вывод строки «Введите пять чисел в формате float», необходимо выполнять не только до использо- вания итератора istream, но даже до его определения, поскольку с того момента, как он определяется в программе, вывод на экран оказывается недоступен: программа ожидает ввода данных. В следующем примере вместо потока cin используется входной файл, из которого берутся данные для программы. Пример также демонстрирует работу с алгоритмом copy().
Листинг 15.27. Программа FINITER // finiter.cpp // Демонстрация работы istream_iterator с файлами #include <iostream> #include <list> #include <fstream> #include <algorithm> using namespace std;
int main() { list<int> iList; // пустой список ifstream infile("ITER.DAT"); // создать входной файловый объект // (файл ITER.DAT должен уже существовать) // итераторы istream istream_iterator<int> file_iter(infile); // файл istream_iterator<int> end_of_stream; // eos (конец потока) // копировать данные из входного файла в iList copy(file_iter, end_of_stream, back_inserter(iList));
cout << endl; // вывести iList ostream_iterator<int> ositer(cout, "--"); copy(iList.begin(), iList.end(), ositer); cout << endl; return 0; }
Результат работы программы: 11--21--31--31--41--51-- Объект ifstream используется для представления файла ITER.DAT, который к моменту запуска программы должен уже физически существовать на диске и содержать необходимые данные (в программе FOUTITER мы его, если помните, создавали). Вместо cout, как и в случае с итератором istream в программе INITER, мы пользуемся объектом класса ifstream под названием infile. Для обозначения конца потока используется все тот же объект. Еще одно изменение, сделанное в этой программе, заключается в том, что мы используем back_inserter для вставки данных в iList. Таким образом, этот контейнер можно сделать изначально пустым, не задавая его размеров. Так имеет смысл делать при чтении входных данных, поскольку заранее неизвестно, сколько элементов будет введено.
Базовые принципы функционирования ОС семейства Windows. Графический интерфейс пользователя. Многозадачная среда. Управление памятью. Независимость от оборудования. Динамически подключаемые библиотеки.
ОС Windows В течение многих лет фирма MS развивала новый технологический подход к обработке данных, основанный на работе с данными в графическом режиме. ОС семейства Windows основаны на объектно-ориентированном подходе к работе с данными. Это среда управления событиями. Каждое событие – это некоторый пакет информации (сообщение). Сообщение воспринимается объектом-окном, которое в ответ на сообщение выполняет какое-то действие. Windows обеспечивает многозадачную и многопоточную обработку программ. Многозадачность – возможность одновременной работы с несколькими приложениями. Многопоточность – это возможность организовать обработку нескольких потоков данных конкурирующих за время процессора. при этом допускается параллельное выполнение нескольких приложений. Существует 2 класса ОС Windows – многопользовательские ОС на базе OC Windows NT: Windows 2000/ XP и однопользовательские ОС на базе Windows 95: Windows 98/Me. Главным отличием многопользовательских систем от однопользовательских является наличие средств защиты информации каждого пользователя от несанкционированного доступа других пользователей 1. Основные технологические принципы Windows Стандартный графический интерфейс пользователя. До появления Windows каждый программист при разработке программ придумывал свой собственный интерфейс - систему меню, способы диалога (ввод данных, выбор вариантов и т. д.). Каждый интерфейс мог быть по своему хорош, но такой подход заставлял пользователя переучиваться при переходе к новому программному продукту. Интерфейс Windows часто называют интуитивным: о технике выполнения многих операции можно просто догадаться, если знать базовые принципы построения интерфейса. Стандартный интерфейс Windows базируется на понятии окна. Окно – это прямоугольная область экрана. Можно выделить три типа окон: окно приложения, окно документа и диалоговое окно. Окно приложения всегда содержит два стандартных элемента: заголовок и горизонтальное меню. Кроме них в окне могут отображаться панели инструментов. Панель инструментов можно настраивать по своему вкусу с помощью команд главного меню (Сервис/Настройка). Панели инструментов дублируют команды главного меню. С помощью переключателей можно отображать или не отображать панели инструментов на экране. Необязательным элементом окна приложения является строка статуса, в которой отображается справочная информация. Кроме того, с помощью правой кнопки мыши можно вызвать меню, которое называется контекстным, т. к. оно зависит от того, для какого объекта его вызывают. Окно документа содержит заголовок, полосы прокрутки (вертикальная и горизонтальная), линейки. Полосы прокрутки появляются, если документ не помещается в окне. Линейки можно выключать. Диалоговое окно используется для ввода данных необходимых для работы программы. Диалоговые окна бывают модальными и немодальными. Модальное окно блокирует работу приложения пока оно не закрыто, т. е. все операции с ним должны быть завершены. Не модальное окно не останавливает работу приложения. В состав диалоговых окон входят: командные кнопки; переключатели; поля выбора; текстовые поля (поля ввода); списки; демонстрационные окна (образец); вкладки; поясняющие надписи. Принцип WYSIWYG (что вы видите, то и имеете). При подготовке текстовых документов страница текста на экране выглядит так же, как и на бумаге после распечатки. Текстовая информация на экране монитора и бумаге принтера отображается следующим образом. В кодовой таблице (ASCII) каждому символу присвоен определенный десятичный код. Чтобы отобразить полученный тем или иным способом код символа, компьютер может: найти в памяти по этому коду изображение символа и вывести его на экран; переслать код символа принтеру, который, пользуясь примерно тем же механизмом, отпечатает изображение символа на бумаге. Монитор и принтер работают под управлением разных драйверов, т. е. то, что появляется на экране монитора не имеет никакого отношения к принтеру. Технология работы с экранными шрифтами целиком определяется режимом монитора – текстовым или графическим. В текстовом режиме экран разбивается на 25 строк по 80 символов каждая, и в каждую позицию (знакоместо) экрана можно вывести произвольный символ кодовой таблицы, все символы имеют одинаковые размеры. Чтобы закодировать изображение такого символа его представляют в виде матрицы, например, 8х16 и закрасить часть клеток так, чтобы получилось изображение символа. Если в закрашенных клетках проставить 1, а в пустых — 0, то каждую строку матрицы можно будет представить десятичным числом от 0 до 255 (8 бит или один байт). Если записать эти числа в 16 последовательных байтов, то мы получим битовую карту символа, сам шрифт называется растровым. Если матрица одного символа занимает 16 байтов, то для представления всех 256 символов потребуется 4096 байтов. Подготовленный таким образом растровый шрифт записывается в файл (обычно с расширением.FNT). Графическая технология Windows резко изменила ситуацию. Основой представления символов является та же самая кодовая таблица, принцип работы монитора и принтера также не изменились. Однако программное обеспечение Windows, вывело нашу работу с текстами на качественно иной уровень. Используя различные шрифты и стили, графические эффекты, мы можем отныне готовить на своем принтере документы высокого качества. При этом в процессе работы над документом мы видим его на экране именно так, как он будет выглядеть на экране. Если ранее мы имели дело с одним-единственным экранным шрифтом и несколькими принтерными, то сейчас существует огромное количество шрифтов. Шрифты можно классифицировать по способу формирования рисунка символов. По способу формирования рисунка символов шрифты делятся на растровые и векторные. Изображение растрового символа кодируется в явном виде (по точкам) в битовой карте (матрице), а затем без изменений отображается на экране или бумаге принтера. Растровый шрифт в графике создается точно так же, как и экранный шрифт для текстового режима монитора, только матрица символа чаще всего квадратная (16x16). Основной недостаток растрового шрифта — заметное ухудшение качества при увеличении (масштабировании) символа: изображение приобретает ступенчатые очертания. Поэтому необходимо, либо создавать отдельные шрифты для разных размеров (а это не только дополнительная работа, но и затраты памяти), либо мириться с ухудшением качества. Кроме того, растровые шрифты в значительной мере зависят от конкретных характеристик устройства отображения. При создании векторного шрифта рисунок символа не кодируется явно по точкам, а описывается совокупностью геометрических фигур, которые и определяют контур рисунка, т. е он описывается по определенным формулам, не зависящим ни размера шрифта, ни от разрешающей способности устройства. Поэтому векторные шрифты легко масштабировать без потери качества изображения. Иногда векторные шрифты называют масштабируемыми, но это не совсем точно, так как масштабировать можно и растровые шрифты. В среде Windows для работы с документами, как правило, используются векторные шрифты специального формата TrueType. При этом один и тот же шрифт применяется и при выводе экранного текста, и при распечатке на принтере, т. е. функции монитора и принтера как бы «интегрируются». Технология подключения устройств Plug and Play. По типу установки устройства можно условно разделить на две группы: Plug and Play и не Plug and Play. Большинство устройств, изготовленных после 1995 года, используют технологию Plug and Play. Устройства Plug and Play достаточно подключить к компьютеру, после чего их можно использовать сразу, не настраивая вручную. Установка нового устройства, независимо от того, поддерживает ли оно технологию Plug and Play, обычно выполняется в три этапа. Подключение к компьютеру. Загрузка соответствующих драйверов устройства. Настройка свойств и параметров устройства. Если устройство поддерживает технологию Plug and Play, шаги 2 и 3 можно пропустить, т. к. при запуске компьютера автоматически буде распознаваться новое оборудование и загружаться все необходимые драйверы. В ходе процесса настройки Windows назначает устанавливаемому устройству уникальный набор системных ресурсов. Ресурс – это некоторая часть компьютера, (диск, принтер или память), которая может быть предоставлена выполняющейся программе или процессу. Эти ресурсы могут включать один или несколько из следующих параметров: линии запросов на прерывание (IRQ), каналы прямого доступа к памяти (DMA), порты ввода-вывода адреса памяти. Каждый ресурс, назначаемый устройству, должен быть уникальным. Это необходимо для правильной работы устройства. Для устройств Plug and Play Windows автоматически проверяет правильность настройки ресурсов. Иногда двум устройствам требуются одинаковые ресурсы, что приводит к конфликту устройств. В этом случае необходимо вручную изменить настройку ресурсов таким образом, чтобы все параметры были уникальными. Некоторые ресурсы, например прерывания устройств, могут в зависимости от драйверов и компьютера использоваться совместно.
Файл с картинкой можно было связать с документом Word, при этом все изменения вносимые в рисунок будут отображаться документе, но рисунок не будет частью документа, он останется самостоятельным файлом. В документе будет находиться только его адрес, следовательно, размер файла Word не увеличится. Таким образом, связанный объект – это объект, созданный в файле-источнике и вставленный в файл назначения с поддержанием связи между этими двумя файлами. Связанный объект в файле назначения может быть обновлен при обновлении файла-источника. Внедренный объект – это данные (объект), содержащиеся в файле-источнике и вставленные в файл назначения. После внедрения объект становится частью файла назначения. Связанный или внедренный объект можно создать на основе любой программы, поддерживающей эти виды объектов. В общем случае технология OLE дает нам следующие преимущества: во-первых, внедрив в документ приложения некий объект, созданный в другом приложении, мы получаем не только составной документ, но и возможность редактировать этот объект средствами «родного» приложения; во-вторых, если мы установим связь некоего объекта с документом, мы сохраним объекту самостоятельное назначение, он сможет обслуживать другие документы и т. п. (а заодно и сбережем память на диске). Чтобы разобраться в универсальных принципах OLE, необходимо ввести следующие определения: Объектом OLE (OLE-объектом) мы называем произвольный элемент, созданный средствами какого-либо приложения Windows, который можно поместить (внедрить и (или) связать) в документ другого приложения Windows. Таким элементом может быть фрагмент некоего документа (например, фрагмент растровой картинки) или весь документ (например, файл.BMP). Приложение, средствами которого создается объект OLE (т. е. программа, которая обслуживает другое приложение), называется сервером OLE (OLE-сервером, исходным приложением, приложением-источником). В нашем примере сервером OLE является программа Paint. . Приложение и документ. Приложение Windows - это прикладная программа. Каждая прикладная программа рассчитана на определенный объект обработки. Любой объект обработки универсального приложения называется документом. Для размещения каждого документа объекта на экране прикладная программа предусматривает отдельное окно, которое называется окном документа. Пиктограмма (иконка –icon, значок) - это цветной значок, который ставится в соответствие приложению Windows или файлу или какой-то функции. Пиктограмма содержит название этого приложения (файла, функции) и картинку, связанную с назначением этого приложения (файла, функции). Понятие динамически подключаемых библиотек. Библиотека DLL представляет собой коллекцию подпрограмм, которые могут быть вызваны на выполнение приложениями или подпрограммами из других библиотек. Подобно модулям, библиотеки DLL содержат разделяемый (sharable) код или ресурсы. Однако, в отличие от модулей, библиотеки содержат отдельно откомпилированный исполняемый код, который подключается к приложению динамически на этапе его выполнения, а не компиляции. Для того чтобы библиотеки можно было отличить от самостоятельно выполняемых приложений, они имеют расширение.dll. Программы, написанные на Object Pascal, могут использовать библиотеки, написанные на других языках. С другой стороны, приложения Windows могут использовать библиотеки, написанные на Object Pascal. Библиотеки могут содержать два вида подпрограмм: экспортируемые и внутренние. Экспортируемые подпрограммы могут вызываться процессом, подключающим библиотеку, а внутренние могут быть вызваны только внутри библиотеки. Библиотека загружается в адресное пространство процесса, который ее вызвал. Подпрограммы библиотеки также используют стековое пространство процесса и его динамическую память.
Преимущества использования динамических библиотек (по сравнению со статическим подключением подпрограмм на этапе сборки приложения) следующие: 1 Процессы, которые загрузили библиотеку по одному и тому же базовому адресу, пользуются одной копией их кода, но имеют свои собственные копии данных. Благодаря этому снижаются требования к объему памяти и снижается своппинг. 2 Модификация подпрограмм библиотек не требует повторной компиляции приложений до тех пор, пока остается неизменным формат их вызова. 3 Библиотеки обеспечивают также послепродажную поддержку (after-market support). Например, дисплейный драйвер, предоставляемый библиотекой, может быть обновлен для того, чтобы поддерживать дисплей, который не существовал в момент продажи приложения. 4 Программы, написанные на разных языках программирования, могут использовать одну и ту же библиотечную функцию, если они следуют соглашению по вызову, предусмотренному функцией. Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.01 сек.) |