Итак, как всегда возвращаемся к Паскалю. В прошлом уроке мы начали изучение конструкций языка…
Освоили одну из них — if…then…else, которая дала нам возможность выбирать условия прямо в программе и влиять на ее выполнение.
Вроде бы по этой конструкции все, но нет — так быстро во всех тонкостях не разобраться. В ней существуют некоторые сложности, или просто нюансы — на которые нужно обратить внимание. Также надо двигаться дальше — пора заняться новыми типами и процедурами.
Хочу сказать, что нам осталось не так уж много теории, после чего начнется одна практика — мы будем стараться писать много программ, чтобы закреплять все пройденное и развивать алгоритмическое мышление, так необходимое программисту.
Сейчас нам нужно освоить один прием, который является очень важным и, возможно, вы уже сами сталкивались с необходимостью его применения.
Это вложенность, или, если забыть про стандартные определения, просто ситуация, когда нужно после проверки условия выполнять не одно, а несколько действий если условие верно, после чего также выполнять несколько действий, если условие не верно.
Здесь нам не обойтись без примера, который я сейчас приведу.
Давайте напишем программу, которая будет:
- Читать два числа A, B с клавиатуры;
- Складывать их и если сумма больше 50, то:
- Читать A еще раз;
- Опять складывать A и B;
- Выводить ответ на экран (уже ничего не проверяя).
- Если сумма меньше 50, то:
- Читать B еще раз;
- Вычесть A и B;
- Выводить ответ на экран (уже ничего не проверяя).
- Конец программы.
Как мы здесь будет поступать? Заметили, нам нужно выполнять несколько действий, в ходе проверки.
Все это, в принципе могло бы выглядеть так (только алгоритм):
If A+B > 50 Then |
Readln(A); |
A := A + B; |
Write(A); |
else |
Readln(B); |
A := A — B; |
Write(A); |
Выглядит, вроде, без ошибок. Но попробуйте, напишите так программу. Ничего не выйдет, в конструкции if…then…else должно быть только по одному действию. Как же поступить?
Здесь нам на помощь приходит возможность вложенности. Как же это реализовать? На самом деле очень просто. Необходимо заключить все действия в отдельные служебные слова begin и end; — то есть сделать как бы маленькую программку в основной программе или сделать ее вложенной — отсюда и название «вложенность». Только запомните, после слова end, если вы его используете для обособленности оператора в конструкциях, ставиться точка с запятой — «;», а не точка! Точка ставиться только в конце программы. Без исключений.
Итак, модифицированный вариант нашей программы, уже полностью:
Program Primer; |
var |
A,B: Integer; |
begin |
Write(‘Введите A: ‘); |
Readln(A); |
Write(‘Введите B: ‘); |
Readln(B); |
If A+B > 50 Then |
begin |
Readln(A); |
A := A + B; |
Write(A); |
end; |
else |
begin |
Readln(B); |
A := A — B; |
Write(A); |
end; |
Readln; |
end. |
Вот, собственно и все. Этот метод применяется везде и повсеместно. Уверяю вас, скоро вы забудете про него и это уже будет получаться автоматически. А пока запомните это и вспоминайте при необходимости.
Теперь новая процедура, часто используемая в совокупности с конструкций if…then…else. Это процедура goto, о которой рассказываю подробно.
Процедура GOTO
Меня часто спрашивают, как же сделать программу по настоящему интерактивной, то есть работающей в зависимости от действий пользователя, не всегда заканчивающей работу после того, как она выполнит какие-нибудь действия. Это возможно, причем просто и мы сейчас этим займемся. А поможет нам в этом процедура goto.
Процедура Goto — осуществляет переход в какое-нибудь место в программе из любой ее точки. То есть с ее помощью можно «прыгать» по программе. Обычно эти прыжки происходят из-за каких либо условий, вот пример:
- Вводим два числа;
- Складываем их и выводим сумму на экран;
- Спрашиваем, повторить ли действие?
- Если ответ утвердительный, переходим (прыгаем) на пункт 1 данного алгоритма.
- Завершаем программу.
В этом примере программа может выполняться бесконечно, пока ответ пользователя будет утвердительным. Как же это сделать?
Команда goto переходит к определенному месту, которое помечатется так называемой «меткой». Эти метки — особенный тип Паскаля, можно даже сказать и не тип, а часть языка. До того, как их использовать, метки нужно описать — сообщить Паскалю о их наличии. Описание меток поисходит также, как и описание переменных.
Для описания меток имеется специальный раздел, наподобие var (помните, я говорил, что var и begin-end не единственные разделы?) только гораздо проще его. Метки не имеют типа, нужно просто задать им имя. Раздел с метками назвается label и оформляется следующим образом:
Program UseGOTO; |
label |
First; |
var |
A,B: Integer; |
begin |
First: |
Write(‘Введите A: ‘); |
Readln(A); |
Write(‘Введите B: ‘); |
Readln(B); |
If A > B Then goto First; |
Readln; |
end. |
Этот пример хорошо демонстрирует использование процедуры goto. Посмотрите внимательно на программу. Что она делает? Запрашивает два числа и если 1-е больше чем 2-е, то повторяется сначала. Необходимые комментарии:
- label Это и есть раздел описания меток. Служебное слово label озаглавливает этот раздел, после него идут имена меток. Если меток несколько, то они перечисляются через запятую.
- First: Так устанавливается метка в программе. Обратите внимание на синтаксис — после имени метки ставиться двоеточие — «:».
- If A > B Then goto First;А это и есть переход при выполнении условия. Заметьте, в конструкии if…then…else отсутсвует слово else, оно нам не нужно, так как мы не делаем ничего при невыполнении условия.
Вот, собственно и все. А теперь давайте вспомним ту задачу, которую я представил вначале — ввести два числа, сложить и запросить повтор. (см. выше).
Итак, напишем эту программу с учетом пройденного материала:
Program UseGOTO; |
label |
Again; |
var |
A,B: Integer; |
S: String; |
Begin |
Again: |
Write(‘Введите A: ‘); |
Readln(A); |
Write(‘Введите B: ‘); |
Readln(B); |
Writeln(‘A+B = ‘,A+B); |
Write(‘Еще раз? (Y/N): ‘); |
Readln(S); |
If S = ‘Y’ Then goto First; |
Readln; |
end. |
Откройте Паскаль и введите эту программу. Запустите ее на выполнение — видите, она уже полностью реагирует на действия пользователя и как бы самостоятельно принимает решение, что делать дальше. Вот это уже полностью интерактивная программа, хотя и простая.
Особых комментариев, думаю, не требуется — все рассказывал ранее. Вот только я использовал одну процедуру, которую мы с вами пока не проходили — думаю, стоит объяснить ее работу.
Процедура Writeln — эта процедура работает точно так же, как и Write, но после того, как выведет строку, она переносит курсор на новую строку. Если вы читали про HTML в прошлых выпусках, то увидите сходство с тэгом <ВR>
Мне часто задавали вопрос, как переносить строки, отделяя таким образом переменные и прочие части вывода. Запомните, для этого и используется эта процедура. Ею можно вообще просто отделять строки — сколько раз вы ее напишите, столько строк будет попущено.
В нашем примере я вывожу с ее помощью строку A+B = (результат), после чего сразу же переноситься курсор и уже обычной процедурой Write выводиться Еще раз? (Y/N). В общем, это очень полезная процедура и невероятно необходимая.
Ну а сейчас мы продолжаем и следующий раздел — типы.
Тип Char
В прошлом выпуске мы с вами изучили новый тип, позволяющий работать со строками символов. Это был тип String, с его помощью можно хранить любые данные в текстовом виде, запрашивать программой строки будь то имя, фамилия или что-нибудь еще. Очень полезная возможность, не так ли? Но вот давайте представим, что мы решили запросить не целую строку, а один символ, например в качестве ответа на такой вопрос:Повторить действие? (Y/N):
Здесь видно, что ввести нужно всего лишь одну букву — Y или N. Заводить для этого целую строку нецелесообразно, хотя и можно. Но при этом программа получается более громоздкой — целая строка используется для хранения всего лишь одного символа. При этом мы теряем память, засоряя ее; работа несколько замедляется, так как строки долго обрабатываются. В общем, здесь встает вопрос оптимизации, который волнует абсолютно всех программистов на свете.
Именно для таких целей — оптимизации — существует один тип, тоже символьный, он более простой, чем строки. Это тип Char.
Char — Переменная этого типа способна хранить всего лишь один символ. Это как бы строка, но с максимальной длиной, равной единице. Он очень удобен для некоторых случаев: невероятно экономит память, ускоряет работу и позволяет легче состалять программу.
Вот примеры присваивания значений переменной типа Char:
Program UseCHAR; |
var |
C: Char; |
begin |
C := ‘Y’; |
Write(C); |
C := ‘:’; |
Write(C); |
Readln(C); |
If C <> ‘Y’ Then Write(‘C не является буквой Y!’); |
Readln; |
end. |
Посмотрите внимательно на пример. Он очень простой, введите его в Паскале и посмотрите, что он делает. При его работе выводиться: Y: после чего программа ждет ввода. Если введенный символ не буква Y, то об этом сообщается пользователю. Необходимые пояснения к типу Char.
- Переменной типа Char можно прямо в программе присвоить значение. Это делается посредством знака присваивания: «:=», после которого должен находиться символ, заключенный в одиночные кавычки (апострофы): ‘A’.
- Переменную можно с успехом использовать в конструкциях сравнения;
- Ее можно читать с клавиатуры. При этом если мы введем строку, состоящую из нескольких символов, то значением переменной Char станет только 1-й символ.
- Его можно прибавлять к строке:Program UseCHAR;varC: Char;S: String;beginWrite(‘Введите строку: ‘);Readln(S);Write(‘Введите символ: ‘);Readln(C);S := S + C;Write(‘Если это сложить, получиться: ‘,S);Readln;end.Но вычитать нельзя!!! Запомните это.
- Переменная типа Char может хранить совершенно любой символ, в том числе и букву русского языка (знак кириллицы).
Ну а теперь, напоследок, напишем программу, которая будет очень хорошо демонстрировать использование строк, символов, сравнения и goto.Программа будет читать символы с клавиатуры, пока не прочитает символ «!» — восклицательный знак. Он будет служить сигналом окончания ввода. Все читаемые символы будут записываться в строку, которая по окончанию действия выведстя на экран. Начнем?Для начала, как всегда, запишем алгоритм программы, то есть определимся, что она будет делать и расскажем это простым человеческим языком. Условимся, что мы имеем две переменных— S: String; — в нее будут записываться все вводимые символы;— C: Char; — этот символ будет постоянно читаться с клавиатуры.А теперь алгоритм:
- Читаем символ с клавиатуры;
- Проверяем — если это не «!», то:
- Добавляем введенный символ в строку (прибавляем его к строке);
- Переходим у вводу символа — пункту 1.
- Выводим составленную строку на экран;
- Ставим Readln; тем самым затормаживая программу;
- Завершаем программу;
Вот вроде и все. Теперь текст программы:
Program Primer; |
label |
A; |
var |
C: Char; |
S: String; |
begin |
A; |
Write(‘Введите символ: ‘); |
Readln(С); |
If C <> ‘!’ Then |
begin |
S := S + C; |
Goto A; |
end |
else |
Write(‘Вы ввели эти символы: ‘,S); |
Readln; |
end. |
Введите эту программу и запустите. Как вам ее работа? Она делает все то, что и планировалось, помещает вводимые символы в строку и выводит ее на экран. Объяснять эту программу по шагам я не буду, разбирайтесь сами, это будет очень полезно. Советую написать что-нибудь самостоятельно в этом роде; придумайте условие и реализуйте его.
А пока на сегодня про Паскаль все, осталась небольшая практика.
Практика
Задачи, которые я вам сейчас задам, мне присылать не нужно! Это работа не будет проверяться, так как является рядовым заданием для самостоятельного выполнения. Практикуйтесь сами, вам сейчас нужно больше работать с Паскалем. Итак, задачи:
1 | Напишите программу, которая будет запрашивать у пользователя данные — ФИО, дату рождения. После чего будет выводить их на экран каким-нибудь форматным образом. К примеру, так:Имя: ВасилийФамилия: ПетровОтчество: ИвановичРодился: 22.11.1961 г.Сделайте возможность изменять данные, то есть возвращаться назад. |
2 | Ввести несколько символов, составляя из них строку. Далее — ввести целую строку и проверить, равны ли получившиеся строки. |
3 | Запросите текущее время (в часах). В зависимости от времени суток, выведете приветсвие на экран, вроде:»Доброе утро!»»Добрый день!»»Доброй ночи!» |
4 | Напишите простейший калькулятор. Вводите два числа, знак действия (+,-,*. Без деления!) и выполняйте это самое действие. Ответ на экран, спросите, начать ли заново, то есть сделайте его интерактивным. |
5 | Придумайте сами себе несколько заданий, полезно будет!!! |
Изучите все, что мы сегодня проходили. Нужно понять до конца, что такое goto, волженность и метки. Это нам дальше понадобиться, а пока все. Разбирайтесь!