Green-sell.info

Новые технологии
6 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Программирование ввод вывод

Любая программа при вводе исходной информации и выводе результатов взаимодействует с внешними устройствами. Частным случаем обмена данными с внешними устройствами является обмен с консолью. Консоль представляет собой совокупность клавиатуры и экрана монитора.

Рассмотрим способы организации ввода и вывода информации, предоставляемые языком программирования Паскаль.

Процедура ввода

Ввод данных — это процесс передачи исходных данных от внешнего устройства в оперативную память.

В качестве внешнего устройства ввода, как правило, является клавиатура или файл с данными.

Для ввода данных с клавиатуры в языке Паскаль используются процедуры read и readln , имеющие следующий формат:

  • read(список);
  • readln(список);

Процедура readln аналогична процедуре read , единственное отличие заключается в том, что после считывания последнего значения переменной из списка, происходит перевод следующего ввода данных в начало новой строки.

Элементом «список» является список имен переменных через запятую, значения которых будут вводится с клавиатуры (заметим, что список может быть пустым), например:

  • read(a, b, c);
  • readln;

Вводимые значения должны разделяться пробельными символами (пробел, табуляция, перевод строки), причем их количество не ограничено. Ввод данных для одной процедуру завершается нажатием клавиши Enter . Если процедура readln используется без параметров, то происходит ожидание нажатия клавиши Enter .

ВНИМАНИЕ: вводимые значения должны соответствовать типам переменных, в противном случае возникает ошибка (например, переменная b имеет тип integer , а вводится вещественное число).

Процедура вывода

Вывод – это процесс передачи данных после обработки из оперативной памяти на внешнее устройство.

Для вывода данных на экран в языке Паскаль используются процедуры write и writeln , которые имеют следующий вид:

  • write(список);
  • writeln(список);

В случае использования процедуры write , после выведения последнего элемента списка на экран, курсор останется в той же строке. Процедура writeln , после завершения вывода, переводит курсор на следующую строку. Если процедуре writeln не передавать параметры, то курсор просто переводится на следующую строку.

Правила записи параметров процедуры вывода

  1. Список вывода разделяется запятыми
  2. Список вывода может содержать переменные, константы и выражения
  3. Под вывод любого значения можно задать формат поля вывода — количество позиций, в которых будет размещаться величина (указывается сразу после выводимого значения через двоеточие):
    • если значение выводимой величины оказывается короче, то оно «прижимается» к правому краю отведенного поля, в противном случае — поле «раздвигается» до необходимых размеров;
    • для вещественных чисел в формате поля вывода предусматривается возможность указания количество выводимых позиций и отводимых под дробную часть числа (десятичная точка также занимает одну позицию).
  • writeln(‘a = ‘, a:2, ‘ ‘, 10 + sqrt(a):2:4, ‘ ‘, pi:4:2);

Copyright © 2014-2018, Урок информатики
Все права защищены

Ввод и вывод информации в программировании

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

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

ФИНАНСОВЫЙ УНИВЕРСИТ ПРИ ПРАВИТЕЛЬСТВЕ РФ

КОНТРОЛЬНАЯ РАБОТА № 1


по дисциплине: «Информатика и программирование»

1. Ввод и вывод данных

Ввод/вывод информации в программировании — процесс обмена информацией между оперативной памятью и внешними устройствами: клавиатурой, дисплеем, внешней памятью и т.п. Ввод — это занесение информации с внешних устройств в оперативную память, а вывод — извлечение информации из оперативной памяти на внешние устройства.

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

Существует несколько способов консольного ввода и вывода.

Первый способ — это использование функции ввода printf() и функции вывода scanf() (унаследована в С++ от С).

Второй способ — это использование оператора ввода cin >> и оператора вывода cout > x — перемещает данные в x, а директивой #include

Для работы с операторами cin и cout необходимо подключить библиотеку директивой #include (табл. 2.1).

Функции и операторы ввода/вывода информации

Функции ввода/вывода printf() и scanf()

Для ввода/вывода данных в стиле C используются функции, которые описываются в библиотечном файле stdio.h. Программа, содержащая обращения к функциям ввода-вывода, должна содержать строку подключения этого файла: #include .

Рассмотрим шесть наиболее распространенных функций ввода информации с клавиатуры и ее вывода на экран (консольный ввод-вывод): getchar, putchar (для ввода-вывода символа); gets, puts (для ввода-вывода строки); scanf, printf (для форматированного ввода-вывода ); и функцию flush очистки буфера stdin.

Функция getchar предназначена для ввода символа, не имеет параметров, возвращает целое число — код введенного символа. Обращение имеет вид: getchar(). Выполняя эту функцию, программа приостанавливает свою работу и ждет от пользователя ввода символа и/или нажатия клавиши Enter. Заметим, что: 1. Эту функцию мы уже неоднократно использовали ранее для организации задержки смены экрана. 2. Будем использовать в последующих лабораторных работах для этих же целей.

Функция putchar предназначена для вывода символа. Имеет один параметр типа int (код выводимого символа) или char. Обращение имеет вид: putchar(i), где i — выражение, определяющее символ. После вывода символа курсор не переходит к началу новой строки.

Функция getchar() может использоваться в операторе присваивания. В этом случае код введенного символа присваивается переменной типа int (в примере — переменной ch).

Функция gets предназначена для ввода строки. Имеет один параметр, задающий адрес области памяти, в которую помещаются символы вводимой строки. В языке Си имя переменной, имеющей строковый тип, является этим адресом. Обращение имеет вид: gets(name)), где name — переменная строкового типа — имя вводимой строки. Выполняя эту функцию, программа приостанавливает свою работу и ждет от пользователя ввода последовательности символов и/или нажатия клавиши Enter.

Функция puts предназначена для вывода строки. Имеет один параметр, задающий адрес области памяти, из которой на экран выводятся символы. Как уже отмечалось, имя переменной, имеющей строковый тип, является этим адресом. Обращение имеет вид: puts(name)), где name — переменная-строка — имя выводимой строки или строка символов, заключенная в кавычки. После вывода строки курсор перемещается к началу новой строки экрана

данные оператор контейнер алгоритм

/* Ввод-вывод с использованием функций getchar, putchar, gets, puts */

char nf[40]; int ch; clrscr();

put («Введите Ваше имя и фамилию»);

puts(«Вас зовут»); puts(nf);

puts(«Введите любой символ»); ch=getchar();

puts(«Вы ввели символ»); putchar(ch);

getch(); /*Организации задержки смены экрана*/

Функция printf предназначена для вывода форматированной последовательности данных. Может иметь один или несколько параметров, первым из которых является строка, называемая форматной строкой. За форматной строкой следует список вывода, который может содержать переменные, константы, выражения разных типов. Форматная строка задает способ преобразования и представления на печати элементов списка вывода, а также определяет, сколько элементов содержит список вывода и какого они типа.

Функция scanf предназначена для вывода форматированной последовательности данных

Формат функции ввода:

Основным отличием применения функции scanf() от функции printf() является знак & перед именем переменной, в которую записываются результаты ввода.

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

Функция scanf() интерпретирует это так, как будто ожидает, что пользователь введет число, затем — запятую, а затем — второе число. Все происходит так, как будто требуется ввести два целых числа следующим образом:

Функция scanf() возвращает число успешно считанных элементов. Если операции считывания не происходило, что бывает в том случае, когда вместо ожидаемого цифрового значения вводится какая-либо буква, то возвращаемое значение равно 0.

2. Определение последовательного контейнера

Контейнер — это объект, который предназначен для хранения других объектов.

STL предоставляет два вида контейнеров:

o последовательные и

Последовательные контейнеры предназначены для обеспечения последовательного или произвольного доступа к своим членам (или элементам).

Ассоциативные контейнеры получают доступ к своим элементам по ключу.

Все контейнерные классы библиотеки STL определены в пространстве имен std.

Последовательные контейнеры

Последовательный контейнер (последовательность) — это вид контейнеров, в котором введено отношение порядка для совокупности хранимых объектов.

Это означает, что для элементов контейнера определены понятия первый, последний, предыдущий и следующий. К этому виду контейнеров принадлежат


o векторы,


o списки,


o Деки,


o строки типа string.


Векторы


Вектор — это контейнерный класс, в котором доступ к его элементам осуществляется по индексу. В силу этого векторы во многом напоминают одномерные массивы.

Библиотека STL предоставляет контейнерный класс vector, определенный в заголовочном файле и доступный в пространстве имен std.

Класс vector ведет себя подобно массиву, однако предоставляет больше возможностей по управлению ним. В частности, вектор можно наращивать по мере необходимости, и он обеспечивает контроль значений индексов. Определение класса vector выглядит следующим образом:


template , class А = allocator>


По умолчанию память для элементов вектора распределяется и освобождается глобальными операторами new() и delete (). Таким образом, для создания нового элемента вектора вызывается конструктор класса Т. Для встроенных типов данных векторы можно определить следующим образом:

//Вектор целых чисел

//Вектор чисел типа

double vector vDbls;

Обычно пользователь знает, сколько элементов будет содержаться в векторе. В этом случае он может зарезервировать память в векторе для нужного числа элементов, указав его после имени объекта в круглых скобках, например:

Количество элементов в векторе можно узнать с помощью функции-члена size ():

size_type size() const;

Функция resize изменяет величину вектора. Она имеет следующий прототип:

void resize(size_type sz);

Если новая величина вектора sz больше текущей, то в конец вектора добавляется нужное число элементов класса Т. Если же новая величина вектора меньше текущей, вектор усекается с конца.

void pop_back(); //удаляет последний элемент вектора.

Обращаться к элементам вектора можно по индексам. Значения индекса начинаются с нуля. Например, присвоить значение четвертому элементу объявленного выше вектора можно следующим образом:


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


Добавить элемент в конец вектора можно с помощью функции-члена push_back(), однако она требует, чтобы в классе хранимых в контейнере объектов был определен конструктор копирования (эта функция добавляет в контейнер копию элемента). Она имеет следующий прототип:

void push_back(const Т& х); //Добавить элемент в конец вектора

Проверить, не является ли контейнер пустым, можно с помощью функции-члена empty ():

bool empty() const; //является ли контейнер пустым

Она принимает значение true, если контейнер пуст.

Функция clear (), имеющая следующий прототип:

void clear(); //удаляет все элементы из вектора.

Функция front () возвращает ссылку на первый элемент в списке, а функция back () — на последний.

Функция at () работает подобно оператору индексирования ( [ ] ), но является более безопасной, поскольку проверяет, попадает ли переданный ей индекс в диапазон допустимых значений. Если индекс вне диапазона, она генерирует исключение out_of _range.

Функция insert () вставляет один или несколько элементов, начиная с указанной позиции в векторе. Функция pop_back () удаляет из вектора последний элемент. Кроме того, для класса vector определены обычные операции сравнения.

Рассмотри теперь функции-члены шаблонного класса vector.

size_type capacity() const; возвращает величину распределенной для вектора памяти в виде числа элементов, которые могут быть сохранены в векторе.

void reserve(size_type n); добавляет емкость вектору в предположении, что к вектору будут добавляться новые элементы.

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

reference back(); возвращает ссылку на последний элемент

reference front(); возвращает ссылку на первый элемент вектора.

функция reference at(size_type n); возвращает ссылку на элемент со значением индекса n.

Функция

iterator insert (iterator position, const T& x);

вставляет элемент x перед элементом, позиция которого задана параметром position. Возвращаемое значение указывает на вставленный элемент.

Кроме обычных итераторов, в контейнере определены обратные (или реверсивные) итераторы, которые имеют тип reverse_iterator. Такие итераторы используются для прохода последовательного контейнера в обратном направлении, то есть от последнего элемента к первому.


Инкремент обратного итератора приводит к тому, что он начинает указывать на предыдущий элемент, а декремент — к тому, что он указывает на следующий элемент.


reverse_iterator rbegin(); возвращает обратный итератор произвольного доступа, который указывает на область памяти за последним элементом.

reverse_iterator rend(); возвращает обратный итератор произвольного доступа, который указывает на первый элемент.

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

Библиотека STL содержит контейнерный класс list, предоставляющий в распоряжение двусвязный (двунаправленный) список. Он определен в заголовочном файле в пространстве имен std.


Этот класс имеет такие же функции, как вектор и ряд дополнительных функций.

Если с векторами итераторы используются редко, то при работе со списком они являются основным средством. Для создания списков предназначены конструкторы, которые имеют несколько форм. Конструктор

explicit list(const Allocator& alloc = Allocator() )

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

explicit list(size_type n);

создает список длины n, содержащий копии значения по умолчанию объектов типа Т. Тип Т должен иметь конструктор по умолчанию. Список использует для распределения памяти объект alloc.


Конструктор list(size_type n, const T& value, const Allocator & alloc = Allocator()); создает список длины n, содержащий копии значения value объектов типа Т. Тип Т должен иметь конструктор по умолчанию. Список использует для распределения памяти объект alloc. В классе list определены дополнительные функции. Функции void push_front(const T& x); и void pop_front(); аналогичны функциям push_back() и pop_back(), однако осуществляют добавление и удаление элементов в начале списка. Функция void remove(const Т& value); удаляет элемент из списка.

Вызвав функцию sort (), можно отсортировать список: void sort();

Операции ввода вывода

Возможны три метода выполнения операций ввода-вывода:

  1. программируемый ввод-вывод;
  2. ввод-вывод с использованием прерываний;
  3. прямой доступ к памяти (direct memory access — DMA)

Программируемый ввод-вывод

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

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

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

Состояние. Используется для проверки состояния контроллера ввода-вывода и соответствующих периферийных устройств.

Передача. Используется для чтения и/или записи данных в регистры процессора и внешние устройства и из регистров процессора и внешних устройств.

На рис. 1.19 приведен пример использования программируемого ввода-вывода для считывания в память блока данных, поступивших из внешнего устройства (например, записи с магнитной ленты). Данные считываются по одному слову. При считывании каждого слова процессор должен выполнять цикл проверки состояния, пока он не обнаружит, что это слово уже доступно в регистре данных модуля ввода-вывода. На приведенной блок-схеме видны основные недостатки такого метода: процессор выполняет большое количество операций, которых можно было бы избежать; теряется много времени.

Ввод-вывод с использованием прерываний

Проблема программируемого ввода-вывода состоит в том, что процессор должен долго ждать, пока контроллер ввода-вывода будет готов читать или принимать новые данные. Во время ожидания процессор должен постоянно производить опрос, чтобы узнать состояние модуля ввода-вывода. В результате значительно падает производительность всей системы.

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


Рис. 1.19. Три метода передачи блока входных данных

Рассмотрим для начала, как все это выглядит с точки зрения контроллера ввода-вывода. Сначала он получает от процессора команду READ и переходит к считыванию данных из связанного с ним периферийного устройства. Как только эти данные поступят в регистры контроллера, он посылает процессору по шине управления сигнал прерывания и ожидает, когда процессор запросит эти данные. При поступлении запроса контроллер передает данные по информационной шине и переходит в состояние готовности для новых операций ввода-вывода.

С точки зрения процессора передача входных данных выглядит следующим образом. Процессор генерирует команду READ, а затем сохраняет содержимое программного счетчика и других регистров, соответствующих выполняемой программе, и переходит к выполнению других операций (например, он в одно и то же время может выполнять несколько различных программ). В конце каждого цикла команды процессор проверяет наличие прерываний (см. рис. 1.7). При поступлении прерывания от контроллера ввода-вывода процессор сохраняет информацию о выполняющейся в данный момент задаче и выполняет программу, обрабатывающую прерывания. При этом он считывает слова из контроллера ввода-вывода и заносит их в память. Затем он восстанавливает контекст программы, от которой поступила команда ввода-вывода и продолжает работу.
Использование для чтения блока данных ввода-вывода, управляемого прерываниями, показано на рис. 1.19,6. Ввод-вывод с прерываниями намного эффективнее, чем программируемый ввод-вывод, так как при нем исключается ненужное ожидание. Однако этот процесс все еще потребляет много процессорного времени, потому что каждое слово, которое передается из памяти в модуль ввода-вывода или в обратном направлении, должно пройти через процессор.

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

Программирование ввод вывод

Системное программирование

Главная страница

Младший специалист

Бакалавр

О сайте

Дополнительные материалы

Пройти тест

Лекция №13. Потоковый ввод-вывод в стандарте Cи

Под вводом-выводом в программировании понимается процесс обмена информацией между оперативной памятью и внешними устройствами: клавиатурой, дисплеем, магнитными накопителя­ми и т. п. Ввод — это занесение информации с внешних устройств в оперативную память, а вывод — вынос информации из опера­тивной памяти на внешние устройства. Такие устройства, как дис­плей и принтер, предназначены только для вывода; клавиатура — устройство ввода. Магнитные накопители (диски, ленты) исполь­зуются как для ввода, так и для вывода.

Основным понятием, связанным с информацией на внешних устройствах ЭВМ, является понятие файла. Всякая операция вво­да-вывода трактуется как операция обмена с файлами: ввод — это чтение из файла в оперативную память; вывод — запись инфор­мации из оперативной памяти в файл. Поэтому вопрос об органи­зации в языке программирования ввода-вывода сводится к вопро­су об организации работы с файлами.

Внутренний файл — это переменная файлового типа, являющаяся структурированной величиной. Элементы файловой переменной могут иметь разный тип и, со­ответственно, разную длину и форму внутреннего представле­ния. Внутренний файл связывается с внешним (физическим) файлом с помощью стандартной процедуры Assign. Один эле­мент файловой переменной становится отдельной записью во внешнем файле и может быть прочитан или записан с помощью одной команды. Попытка записать в файл или прочитать из него величину, не совпадающую по типу с типом элементов файла, приводит к ошибке.

Аналогом понятия внутреннего файла в языках Си/Си++ яв­ляется понятие потока. Поток — это байтовая последовательность, передаваемая в про­цессе ввода-вывода.

Поток должен быть связан с каким-либо внешним устройством или файлом на диске. В терминологии Си это звучит так; поток должен быть направлен на какое-то устройство или файл.

Основные отличия файлов в Си состоят в следующем: здесь отсутствует понятие типа файла и, следовательно, фиксирован­ной структуры записи файла. Любой файл рассматривается как байтовая последовательность:

Стрелочкой обозначен указатель файла, определяющий теку­щий байт файла. EOF является стандартной константой — призна­ком конца файла.

Существуют стандартные потоки и потоки, объявляемые в про­грамме. Последние обычно связываются с файлами на диске, со­здаваемыми программистом. Стандартные потоки назначаются и открываются системой автоматически. С началом работы любой программы открываются 5 стандартных потоков, из которых ос­новными являются следующие:

o stdin — поток стандартного ввода (обычно связан с клавиатурой);

o stdout — поток стандартного вывода (обычно связан с дисплеем);

o stderr — вывод сообщений об ошибках (связан с диспле­ем).

Кроме этого, открывается поток для стандартной печати и до­полнительный поток для последовательного порта.

Работая ранее с программами на Си, используя функции вво­да с клавиатуры и вывода на экран, мы уже неявно имели дело с первыми двумя потоками. А сообщения об ошибках, которые система выводила на экран, относились к третьему стандартному потоку. Поток для работы с дисковым файлом должен быть от­крыт в программе.

Работа с файлами на диске. Работа с дисковым файлом начи­нается с объявления указателя на поток. Формат такого объяв­ления:

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

Следующий шаг — открытие потока, которое производится с помощью стандартной функции fopen (). Эта функция возвраща­ет конкретное значение для указателя на поток и поэтому ее зна­чение присваивается объявленному ранее указателю. Соответству­ющий оператор имеет формат:

Имя_указателя=fореn (“имя_файла”, “режим_открытия”) ;

Параметры функции fopen () являются строками, которые мо­гут быть как константами, так и указателями на символьные мас­сивы. Например:

Здесь test .dat — это имя физического файла в текущем ката­логе диска, с которым теперь будет связан поток с указателем fр. Параметр режима r означает, что файл открыт для чтения. Что касается терминологии, то допустимо употреблять как выражение «открытие потока», так и выражение «открытие файла».

Существуют следующие режимы открытия потока и соответ­ствующие им параметры:

r открыть для чтения

w создать для записи

а открыть для добавления

r+ открыть для чтения и записи

w+ создать для чтения и записи

а+ открыть для добавления или

создать для чтения и записи

Поток может быть открыт либо для текстового, либо для дво­ичного (бинарного) режима обмена.

Понятие текстового файла: это последовательность символов, которая делится на строки специальными кодами — возврат ка­ретки (код 13) и перевод строки (код 10). Если файл открыт в текстовом режиме, то при чтении из такого файла комбинация символов «возврат каретки — перевод строки» преобразуется в один символ n — переход к новой строке.

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

Указанные выше параметры режимов открывают текстовые файлы. Если требуется указать на двоичный файл, то к параметру добавляется буква b. Например: rb, или « b », или r +b. В некоторых компиляторах текстовый режим обмена обозначается буквой t, т.е. записывается a+t или rt.

Если при открытии потока по какой-либо причине возникла ошибка, то функция fopen() возвращает значение константы null. Эта константа также определена в файле stdio.h. Ошибка может возникнуть из-за отсутствия открываемого файла на диске, нехватки места в динамической памяти и т.п. Поэтому желатель­но контролировать правильность прохождения процедуры откры­тия файла. Рекомендуется следующий способ открытия:

if (fp=fopen(«test.dat», «r»)==NULL)

В случае ошибки программа завершит выполнение с закрыти­ем всех ранее открытых файлов.

Закрытие потока (файла) осуществляет функция fclose(), прототип которой имеет вид:

int fclose(FILE *fptr);

Здесь fptr обозначает формальное имя указателя на закрыва­емый поток. Функция возвращает ноль, если операция закрытия прошла успешно. Другая величина означает ошибку.

Запись и чтение символов. Запись символов в поток произво­дится функцией putc() с прототипом

int putc (int ch, FILE *fptr);

Если операция прошла успешно, то возвращается записанный символ. В случае ошибки возвращается константа EOF.

Считывание символа из потока, открытого для чтения, произ­водится функцией gets () с прототипом

int gets (FILE *fptr);

Функция возвращает значение считываемого из файла сим­вола. Если достигнут конец файла, то возвращается значение EOF. Заметим, что это происходит лишь в результате чтения кода EOF.

Исторически сложилось так, что gets() возвращает значение типа int. To же можно сказать и про аргумент ch в описании функции puts(). Используется же в обоих случаях только млад­ший байт. Поэтому обмен при обращении может происходить и с переменными типа char.

Пример 1. Составим программу записи в файл символьной пос­ледовательности, вводимой с клавиатуры. Пусть признаком завер­шения ввода будет символ *.

//Запись символов в файл

puts(«Вводите символы. Признак конца — *»);

В результате на диске (в каталоге, определяемом системой) будет создан файл с именем test.dat, который заполнится вводимы­ми символами. Символ * в файл не запишется.

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

//Чтение символов из файла

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

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

int putw(int, FILE *fptr);

Если операция прошла успешно, то возвращается записанное число. В случае ошибки возвращается константа EOF.

Считывание целого числа из потока, открытого для чтения, производится функцией getw () с прототипом

int getw(FILE *fptr);

Функция возвращает значение считываемого из файла числа. Если прочитан конец файла, то возвращается значение EOF.

Пример 3. Составим программу, по которой в файл запишется последовательность целых чисел, вводимых с клавиатуры, а затем эта последовательность будет прочитана и выведена на экран. Пусть признаком конца ввода будет число 9999.

Урок 2 — Ввод/вывод, операции над числами

В прошлом уроке мы выводили на экран текстовое сообщение, а сейчас займемся также вводом данных и заставим нашу программу что-нибудь посчитать. Содержание:

1 Потоковый ввод/вывод

В файле iostream.h находятся глобальные объекты std::cin и std::cout , позволяющие вводить данные с клавиатуры и выводить их на экран. Мы подключаем этот файл командой:
#include

Эти объекты называются потоками ввода/вывода. В дальнейших уроках мы узнаем и о других разновидностях таких потоков. Потоковый ввод/вывод осуществляется операциями >> и соответственно. Использовать их можно следующим образом:

В этой программе создается 3 переменных целого типа данных ( int ), в конце урока приведена более подробная информация об этом и других стандартных типах. Тут, как и в hello world использолся вызов функции std::cin.get() для задержки закрытия окна. На самом деле эта функция ( get ) ожидает ввода символа пользователем.

Также, в этом примере вы должны заметить комментарии к коду. Комментарием считается часть строки, расположенная правее двух слешей , а тажке текст (возможно многострочный), расположенный между символами /* и */ . Комментарии удаляются во время работы препроцессора (если забыли что это такое — освежите память) и, следовательно, не влияют на результаты компиляции. Используются комментарии только в качестве «подсказок» программисту.

Объект std::cin является потоком ввода, к нему можно применять оператор >> для получения значений переменных с клавиатуры:

Теперь значения переменных задаются не программистом, а пользователем (в процессе использования программы).

С помощью объекта cin и операции >> можно присвоить значение любой переменной. Например, если переменная x описана как целочисленная, то команда cin>>x; означает, что в переменную x будет записано некое целое число, введенное с клавиатуры. Если необходимо ввести несколько переменных, то можно написать:
cin >> x >> y >> z; .

2 Основные операции над числами

Чтобы быть полезной — наша программа должна делать что-то кроме ввода и вывода. В языке С++ поддреживается стандартный набор арифметических операций (для сложения, вычитания, деления и т.д.). Я рекомендую запустить следующий пример:

Директива using namespace std; сообщает компилятору, что в этом месте вы используете имена из пространства имен std , за счет нее вы, в частности, можете писать cout или cin вместо std::cout и std::cin . Тему пространств имен мы подробно изучим в следующих уроках.

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

Остальные приведенные тут операторы рядовым программистом используются значительно реже и более подробно рассмотрены в «справочнике», приведенном в конце урока.

Помимо целых чисел, компьютер может обрабатывать дробные — замените тип int в нашей программе на float или double , при попытке собрать программу вы получите ошибки, т.к. не все используемые тут операторы могут применяться к дробным числам. Изучите сообщения об ошибках — вам нужно научиться их читать. Запустите следующую программу:

Обратите внимание, что теперь даже если на вход будут поданы целые числа — результат операции деления будет дробным. Различия между типами данных double и float в данный момент для нас несущественны — достаточно помнить, что float обычно занимает 4 байта, а double — 8, за счет этого при вычислениях над переменными double мы можем получить более высокую точность и диапазон значений (см. справочный материал в конце урока).

Теперь рассмотрим изученное на примере более сложной задачи (наконец, заставим наш компьютер посчитать что-нибудь полезное):

Известны плотность p , высота h и радиус основания R цилиндрического слитка.
Найти объем V , массу m и площадь S основания слитка.

Составим текст программы, учитывая что:
$$S = pi cdot R cdot R, \
V = S cdot h,\
m = p cdot V.$$

Результаты работы программы:

Исследуя эту программу, обратите внимание на:

  1. описание констант с помощью ключевого слова const . Константе значение присваивается лишь один раз, если вы попробуете сделать это еще раз — программа не скомпилируется. Очень хорошая практика — явно указывать константность везде, где это возможно. Это с одной стороны защитит вас от ошибок в дальнейшем (при попытке изменить константу вы сразу получите ошибку), а с другой — позволит генерировать более оптимальный код компилятору.
  2. в конце программы мы написали cin.get() дважды. Дело в том, что:
    • функция get извлекает из потока cin один символ. Символы попадут в поток после нажатия пользователем кнопки Enter;
    • оператор >> считывает из потока слово и, в нашем случае, преобразует его в число. Исследуя программы, вы должны были заметить, что если ввести в одной строке несколько чисел — то «сработают» сразу несколько последовательных операторов ввода. Мы пользовались этим, например, при исследовании математических операторов;
    • считав первое слово с потока — оператор >> не «трогает» остальные символы. В результате, в потоке остается символ-разделитель — в нашем случае — символ перевода строки (соответствующий клавише Enter). Этот символ и будет считан первым вызовом функции get() ;
    • таким образом, если оставить только один вызов get() программа отобразит на экран результаты вычислений и сразу завершится. Второй вызов get() ожидает еще одного нажатия клавиши Enter пользователем;
    • вам нужно помнить об этом всякий раз, когда вы используете get после оператора >> .
  3. в этой программе не так легко разобраться, как хотелось бы и очень легко запутаться. Проблема заключается в «плохих» именах переменных. По мере усложнения ваших программ эта проблема станет более очевидной. Заведите правило — давать переменным имена, которые отражают суть. Более подробно про это можно прочитать в статье «Теория чистого кода. Стиль кодирования«. Попробуйте переписать эту программу, используя более понятные имена.

3 Справочный материал

3.1 Переменные и типы данных

Переменная это область памяти заполненная данными, которые называются значением переменной. У каждой переменной должно быть своё уникальное имя на латинице с учетом регистра. Переменные делятся на целочисленные, дробные, символьные, логические (т.е «да» или «нет»).

Для решения задачи в любой программе выполняется обработка каких-либо данных. К основным типам данных языка C++ относят:

  • char — символьный;
  • int — целый;
  • float — дробное число с плавающей точкой;
  • double — дробное число двойной точности;
  • bool — логический.
  • void — неполный тип и спецификатор типа. Множество значений этого типа пусто (поэтому его нет в таблице ниже). Он используется для определения функций, которые не возвращают значения, а также как базовый тип для указателей. Вы не можете создать переменную этого типа, позже станет понятно как им пользоваться.

Для формирования других типов данных используют основные и так называемые спецификаторы:

  • short — короткий;
  • long — длинный;
  • signed — знаковый;
  • unsigned — беззнаковый.
  • const — константа.

В таблице приведена справочная информация о различных комбинациях типов данных с учетом спецификаторов для операционной системы Windows:

Читать еще:  Как запрограммировать компьютер на выключение
Ссылка на основную публикацию
ВсеИнструменты
Adblock
detector