#5 Ввод данных с клавитуры (из консоли) в Паскаль. Процедура Readln()

Ранее мы говорили о стандартных процедурах write() и writeln(), служащих для вывода данных в консоль, теперь же погорим об обратном процессе - а именно получении данных от пользователя.

Процедура Readln()

Если кратко:

Стандартная процедура readln() позволяет записывать в переданные аргументы-переменные те значения, которые пользователь вводит в консоли.

Подробнее:
Стандартная процедура readln() (читают как "ридлэн" или "ридлайн") работает в двух режимах (всегда временно останавливая консоль):

  1. Если ей переданы аргументы-переменные, например:
    var a: integer;
       b: real;
    begin
       readln(a, b); // запрашиваем у пользователя значения для двух переменных 

    -- то она ожидает ввода данных (литералов) для этих переменных, а после ввода последнего требуемого литерала ожидает последнего нажатия клавиши Enter.

  2. Просто ожидает нажатия Enter пользователем, если вызывается без аргументов:
    readln(); //  вызов процедуры readln() без аргументов

    -- кстати, именно этот её свойство мы используем для удержания консоли (там мы делаем вызов процедуры readln() перед закрывающей операторной скобкой тела программы).

Подробнее поговорим о первой функции данной процедуры.

Получение значений переменных и стандартный поток ввода данных

Стандартный поток ввода данных

В Паскале стандартным потоком ввода можно назвать

"то, откуда читает Readln()"

, так для разных реализаций Паскаля этот "источник" чтения может оказаться различным.

Давайте возьмём такой код:


program Project1;
var
    b: integer; // объявляем переменную целого типа
begin
  writeln('Vvedite znachenie peremennoi b:'); // вывод пояснения -- строкового литерала
  readln(b); // запрос чтения

end.   

и запустим его в паре средств разработки (мы можете попробовать запустить в вашей среде).

В Lazarus Delphi местом чтения оказывается "консоль", например в Windows, это выглядит как-то так (черное окно появляющееся при запуске программы):
Консоль паскаль пример работы  readln() стандартный поток ввода
-- белый горизонтальный курсор внизу мигает (на этой картинке он просто отображается, а на экране мигает) в ожидании того, как пользователь введёт число и нажмёт Энтер.

Тот же самый код, запущенный в среде ABCПаскаль, не приведёт к открытию черного окна, а просто предложит ввести данные в нижней части собственного окна:
abcPascal Readln() как работает пример
-- здесь для обозначения места ввода используется вертикальный курсор.

Получение значений для переменных -- два способа

К этому моменту мы с вами слышали про два способа получения значений для переменных:

  1. С помощью операции (и её оператора) присваивания, например:
    a := 5;
  2. С помощью вызова Readln(), где в качестве аргументов переданы эти переменная/переменные:
    readln(a); // запрос на чтения значения для одной переменной

    -- о втором способе получения данных поговорим подробнее ниже.

Как работает Readln()

Readln() выполняет неявное (внутри своего тела -- тела процедуры) присваивание введенных пользователем значений переменным, которые переданы в него в качестве аргументов.

Как и при перезаписи переменной (если одной и той же переменной при выполнении программы последовательно присваивают разные значения), Readln() может перезаписать старое значение переменной, например, запустите код:

program Project1;
var
    b: integer; // объявляем переменную целого типа
begin
  b := 8;
  writeln('b: ', b); // вывод с литералом- пояснением
  writeln('Vvedite znachenie peremennoi b -- celoe chislo:'); // вывод пояснения -- строкового литерала
  readln(b); // запрос чтения 
// сразу после ввода значение  переменной b могло поменяться (смотря что ввели)
  writeln('b: ', b); // вывод с литералом- пояснением

  readln(); // задержка консоли
end.  

Если второй раз вы введете не восьмерку -- а любое другое целое число, то значение переменной b изменится -- собственно это и есть основной пример иллюстрирующий работу readln.

С помощью readln() можно вводить данные любого типа, из списка приведённого ранее.
Когда мы говорим "вводить", то подразумеваем, что пользователь вводит -- передаёт данные в "область" выполнения программы -- как бы из одного мира в другой.

Получение значений для нескольких переменных одним вызовом

Readln() умеет запрашивать данные сразу для нескольких переменных одним вызовов, переменные, переданные в качестве аргументов могут быть разных типов, но так как мы к данному моменту изучили только два типа (integer и real), то рассмотрим пример получения нескольких значений этих двух типов.

Запустите код:

var
    a, b: integer; // пара целых
    c:  real;  // одна вещественная
begin
  // первый запорос на чтения -- по одной
  writeln('1) Vvedite znachenie peremennih:');
  readln(a); // запрос значения у пользователя
  readln(b);  // запрос значения у пользователя
  readln(c);  // запрос значения у пользователя
  writeln(' Poluchili a=' , a,  ' b=', b, ' c=', c); // выводим значения переменных с пояснениями

   // второй запорос на чтение -- списком
  writeln('2) Vvedite znachenie peremennih:');
  readln(a, b, c); // запрос чтения
  writeln(' Poluchili a=' , a,  ' b=', b, ' c=', c); // выводим значения переменных с пояснениями

  readln(); // задержка консоли
end.  

Здесь в первой части программы значения всегда придётся вводить по одному, а вот во второй части, где аргументы передаются списком можно:

  1. либо также вводить по одному (после каждого нажимая Энтер), тогда мы получим в консоли что-то вроде:
    Паскаль readln() ввод значений по одному
  2. либо в одну строку через пробел, нажав Энтер после ввода третьего значения:
    Паскаль ввод списком через пробел значений пример  readln

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

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

Например, рассмотрим код:

var a: integer;
begin
   a := 5;
   writeln('=', a); // =5

   readln(a);
   writeln('=', a); //="тому, что ввёл пользователь"

   a := 7;
   writeln('=', a); // =7
end;

В примере выше в однострочных комментариях мы показали, что выведет на экран writeln() в первом и третьем случае.
Во втором же случае значение переменной $a$ перезаписывается не явно с помощью оператора присваивания, а с помощью процедуры чтения readln(), а потому в консоли вместо строки:

"тому, что ввёл пользователь"

будет какое-то число введённое пользователем.

Разбор задач

Пример №1

Задача:

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

Это не сложная задача.
Во-первых, так как первая переменная вещественна, то и вторую (которой будем присваивать результат произведения), тоже придётся объявить как вещественную, так как в силу неявного приведения типов произведение вещественного значения и целого числа (в нашем случае это $2$) даёт вещественное значение.

Далее перейдём к решению:

var 
 a, // первое значение
 b //  результат умножения на 2 
: real;
begin 
   writeln('vvedite vechestvennoe znachenie:');
   readln(a);  // читаем значение из консоли
   b := a *2; // запоминаем результат произведения
   writeln('Otvet: a=', a, '  b=', b);
end.

Запустите этот код и посмотрите на ответ задачи (введя значение переменной и нажав Энтер).

Пример №2

Задача:

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

Сказано, что одна переменная хранит целое число, а другая вещественное -- значит ясно, что одну надо объявить как переменную целого типа integer, а вторую как вещественного real. Третья же переменная будет хранить их сумму, так как в случае арифметических операций с вещественными и целыми типами имеет место неявное приведение типа, то тип суммы будет вещественным.
Давайте объявим эти переменные:

var
  a: integer;
  b, c: real;

С помощью комментариев к коду можно даже пояснить какая переменная за что отвечает:

var
  a: integer; // для первого числа
  b, // для хранения второго числа 
  c: real; // для хранения их суммы

Теперь когда мы определились с секцией объявления переменных, можно переходить к реализации тела программы.
Здесь всё просто:

var
  a: integer; // для первого числа
  b, // для хранения второго числа 
  c: real; // для хранения их суммы
begin
   a := 31; // пусть значение первой переменной = 31
   readln(b);  // запрос на чтение значения для переменной b
   c := a + b;  
   writeln('c=', c); // выводим ответ
end.

-- запустите эту программу, курсор ввода значения (задержанный realdln-ом) для второй переменной будет мигать без всяких пояснений, что не удобно, так как не совсем понятно, что требуется делать. В таких случаях обычно перед любым readln() используют вывод какого-либо пояснения, которое помогает пользователю понять, что требуется делать:

var
  a: integer; // для первого числа
  b, // для хранения второго числа 
  c: real; // для хранения их суммы
begin
   a := 31; // пусть значение первой переменной = 31
   writeln('vvedite vechestvennoe chilso:'); // вывод пояснения
   readln(b);  // запрос на чтение значения для переменной b
   c := a + b;  
   writeln('c=', c); // выводим ответ
end.

-- так уже понятнее ;)

Самостоятельная работа

Теоретические вопросы

  1. Теоретические вопросы:
  2. Что такое и для чего нужен Readln()?
  3. Что такое процедура?
  4. Что такое аргумент процедуры?
  5. Сколько аргументов может принимать Readln()?
  6. Что такое выражение? Какие выражения вы знаете? Укажите выражения в коде примеров этого урока.
  7. Задачи

  8. Вам нужно получить от пользователя два вещественных числа и ещё два целых, запишите все эти 4 значения в переменные и выведете значения переменных на экран, чтобы было ясно значение какой переменной чему равно.
  9. Получите от пользователя целое значение, умножьте его на значение вещественной переменной (присвойте ей его явно в коде), результат произведения запишите в третью переменную и выведете её значение на экран.
  10. Получите от пользователя значений трех чисел -- два целых и одно вещественное и выведите на экран значение их суммы.