![]() |
Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Инструкции printf и scanf. Схема ввода-вывода
Функции printf и scanf обычно используются в виде отдельных инструкций, которые получаются добавлением к обращению к ним символа "; ". Однако, как и большинство других функций, они могут использоваться в выражениях и, следовательно, должны возвращать некоторое значение. Функция printf возвращает число выводимых символов (байтов), а функция scanf - число введенных скалярных значений. Элементы списка данных функции scanf – адреса переменных, значения которых задаются, поэтому необходимо использовать оператор & (нахождение адреса). Примеры. l=scanf(" %d%f%d", & a, & x, & b); n=printf(" a=%d x=%.5g b=%d\n", a, x, b); // Между спецификациями 2 // пробела printf(" l=%d n=%d\n", l, n); На экране отобразится: 12 23.278e-3 45(Enter) Вводятся с клавиатуры a=12 x=0.023278 b=45 Результаты l=3 n=23 вывода printf(" Рост: " ); scanf(" %f", & height); printf(" Вес: " ); scanf(" %f", & weight); На экране отобразится: Рост: 181.5 Вес: 75.6 Обмен данных происходит через специальную область памяти, выделяемую операционной системой и называемую буфером, причем буферы ввода и вывода различны. Каждый буфер имеет фиксированный размер, вводимые и выводимые символы сначала накапливаются в соответствующем буфере и только по выполнении некоторого условия и необходимых преобразований отправляются по назначению.
При вводе это происходит при получении необходимого числа символов для формирования элемента данных, определяемого параметром спецификации W, либо по приходе специального символа – ограничителя, сигнализирующего об окончании ввода символов для текущего элемента данных. Для функции scanf такими ограничителями являются знаки разрядки. Полученная последовательность символов преобразуется во внутреннее представление элемента данных согласно спецификации управляющей строки и отправляется в область памяти соответствующего по списку данных объекта программы. Появление в последовательности символа, который не может быть преобразован в соответствии со спецификацией, также играет роль ограничителя, т.е. прекращает формирование очередного элемента. Следовательно, функция scanf получает на вход символьную строку, а в качестве результата возвращает внутреннее представление объекта из списка данных. Последующие инструкции ввода продолжают заполнять буфер. При заполнении буфера его содержимое передается в память, буфер очищается и процесс повторяется. Символ перевод строки Enter принудительно очищает (закрывает) буфер ввода. Поскольку функция scanf отображает вводимые символы на экран, то, пока буфер ввода не закрыт, процесс вывода на экран блокируется. Это может привести к тому, что, хотя инструкция scanf выполнена, следующие за ней инструкции printf не смогут вывести данные на экран, пока не будет введен символ перевод строки. В примере видно, что сначала на экране будет отображен ввод первого объекта из списка данных второй инструкции scanf и только затем появится вывод предыдущей инструкции printf. Пример. scanf(" %d%f%f%f", & a, & b, & c, & d); printf(" /%d/%g/%g/%g/\n", a, b, c, d); scanf(" %d%f", & e, & f); printf(" /%d/%g/\n", e, f); На экране имеем: 1 -23.47e-6 -236.485 2e10 4612347(Enter) Это ввод! /1/-2.347e-05/-236.485/2e+10/ -94.56e-5(Enter) /4612347/-0.0009456/ При выводе результат появится на экране только при заполнении всего буфера вывода. Последнее содержимое незаполненного буфера вывода отображается при завершении программы. Это иногда приводит к неожиданным последствиям. Если во время работы программы произошла ошибка и в это время буфер был не заполнен, то на экране его содержимое не появится. Это надо иметь в виду при попытке обнаружить место происхождения ошибки в процессе отладки программы. При выводе происходит обратное преобразование элементов списка данных из внутреннего представления в символьную строку. Ввод-вывод массивов Напомним, что одна спецификация передает одно значение, поэтому для организации ввода-вывода массивов в программе следует организовать цикл(ы), в теле которого необходимо поместить функцию printf или scanf. Ввод printf(" Ввод массива\n" ); fo r(i=0; i< 10; i++){ for (j=0; j< 10; j++){ scanf(" %f", & a[ i ][ j ]); } } Вывод printf(" %32cИсходный массив\n", ' '); for (i=0; i< 10; i++){ for (j=0; j< 10; j++){ printf(" %15.5g", a[ i ][ j ]); if ((j+1)%5==0)printf(" \n" ); // Перевод строки после вывода каждого } // 5-го значения, чтобы не выйти за } //пределы экрана. Его размер 80 позиций Очистка и останов экрана Введем 2 полезные функции консольного ввода-вывода (прототипы в файле coniow.h ). clrscr( ) – очистка экрана. Полезна: - при повторном прогоне приложения без его завершения, например, при выходе из задачи по нажатию определенной клавиши; - при вводе неправильных входных значений и его повторе. getch( ) – ввод одиночного символа без его отображения на экране. Позволяет: - ввести код символа (клавиши, например Esc) для выхода из задачи; - остановить экран для прочтения сообщения об ошибке и после ввода любого символа продолжить выполнение. Замечание. В Visual Studio и Turbo C++ вместо clrscr( ) надо применять system(“cls”). В Visual Studio вместо getch( ) надо применять _getch( ), иначе выдается предупреждение. Язык Basic Средства консольного ввода-вывода реализуются в виде методов класса Console. В данном разделе рассмотрим только методы, которые предоставляют те же возможности, что и рассмотренные выше средства языка C. Напомним, что обращение к некоторому методу этого класса должно иметь вид: Console.< имя метода> ( [ < список параметров> ] ) Чтобы не записывать префикс Console при каждом обращении к методам, следует перед инструкцией Module записать инструкцию Imports System.Console. Замечание. Обмен данных производится через буферы ввода-вывода по тем же правилам, что и для языка C. Метод ReadLine Метод читает введенную с клавиатуры строку, завершенную нажатием клавиши Enter. Пример. s=ReadLine( ) В сравнении данного метода с функцией scanf языка С очевидны следующие его ограничения: - вводится одно значение типа String, - нет средств преобразования введенной строки в значения других предопределенных типов таких, как: Integer, Single и др. Первое ограничение требует ввода каждого значения с новой строки (столбиком). О втором. Язык Basic допускает неявное преобразование значения типа String в числовой тип при условии, что строка не содержит недопустимых символов. Для этого в свойствах проекта задачи Компиляция ( Compile ) надо установить опцию Проверка сужающих преобразований ( Option strict ) в состояние Off. Пример. For i = 0 To m - 1 For j = 0 To n - 1 a(i, j) = ReadLine() Next j Next i Замечание. По умолчанию максимальная длина строки 256 символов.
Методы Write и WriteLine Оба метода формируют и выводят информацию на экран. Разница между ними в том, что WriteLine завершает вывод переводом строки, а Write – нет. Вывод выполняется с преобразованием данных из внутреннего представления значений различных предопределенных типов в символьную строку. Правила преобразования напоминают аналогичные для функции printf языка C, поэтому воспользуемся той же терминологией. Формат обращения: {Write | WriteLine}(< управляющая строка> [, < список-данных> ]) Управляющая строка состоит из текста и спецификаций. Каждая спецификация определяет только одно передаваемое значение. Текст вне спецификаций выводится на экран так же, как в языке С. Не надо только помещать в конце выводимой строки символ ′ \n′, это сделает сама инструкция WriteLine. Формат одной спецификации: {индекс элемента списка вывода [, выравнивание][: формат]}, где: - индекс элемента списка вывода – порядковый номер-1элемента списка данных, преобразованное значение которого должно быть подставлено на место спецификации в строку вывода; - выравнивание – это целое, определяющее ширину поля вывода для значения; если длина выводимого значения больше данного параметра, то он игнорируется, если меньше, то, если параметр > 0, то значение в поле вывода выравнивается вправо, если он < 0, то – влево; в целом, аналог параметра W функции printf в сочетании с флагом - (минус) при выравнивании влево; - формат – < тип> D, где < тип> - спецификация, определяющая тип передаваемого значения, D – параметр точности (совпадает с языком C ), целое без знака (не более 2-х цифр). Перечень типов
Как видно из таблицы, действие спецификаций аналогично языку C. Для очистки экрана можно использовать метод Clear (), для остановки экрана – метод ReadLine (). Вопросы для самопроверки и контроля Вопросы для самопроверки 1. Что происходит, когда длина выводимого значения больше величины W? 2. При каких условиях при выводе значений с плавающей точкой не ставится десятичная точка? 3. Перечислите символы – ограничители ввода для языка С. 4. А для языка B asic? 5. Чем отличаются правила ввода значений по спецификациям f и e? 6. Что возвращают функции printf и scanf? Контрольные вопросы 1. Почему при вводе не используется второй параметр спецификации D? 2. При каких условиях производится округление выводимого значения? 3. Как организуется ввод элементов массива? 4. Когда разумно применять спецификацию g? ПРОЦЕДУРЫ Распределение памяти Распределение памяти – это процесс, связывающий некоторую область памяти с какой-либо переменной так, что элемент данных, описанный этой переменной, может быть размещен в этой области. СХЕМА Предметная область Программист Память скаляры, элементы массивов имена адреса и структур Источник информации: определения переменных. C: инструкции описания типа: int long float double char. Basic: инструкция Dim. Распределение скаляров
Объем памяти, занимаемый массивом, равен: где S – длина одного элемента данного типа, m – число измерений (размерность массива), di – число элементов массива в i -м измерении (длина измерения), hi – максимальное значение индекса в i -м измерении (верхняя граница), li – минимальное значение индекса в i -м измерении (нижняя граница). Пример. Dim aMatr(1 To 10, 1 To 10) As Double Замечание. В изучаемых версиях языков минимальное значение индекса всегда равно 0, поэтому объем памяти, занимаемый массивом aMatr равен: V=(10+1)*(10+1)*8=968 байтов. Иногда (часто при отладке программы) требуется определить номер по порядку следования в памяти элемента многомерного массива по известным индексам (развернуть в одномерный). Он определяется по формуле:
Пример. Описание массива имеет вид: float array[10][6][5]; Адрес элемента массива array[2][3][1] равен: N=6*5*2+5*3+1+1=77 |
Последнее изменение этой страницы: 2017-04-12; Просмотров: 515; Нарушение авторского права страницы