Песни о Паскале
Шрифт:
Е) Исходные позиции шахматных фигур известны всякому (если вы – исключение из правила, ознакомьтесь с основами шахмат). Пользователь в цикле вводит число, по которому программа печатает название фигуры, стоящей на соответствующей вертикали шахматной доски (от 1 до 8). Ноль служит для выхода из цикла, а на все прочие числа программа сообщает об ошибке.
Ж) Программа запрашивает в цикле два числа: вертикаль и горизонталь шахматной доски (числа от 1 до 8), а затем печатает цвет клетки на их пересечении. Если хотя бы одно из чисел равно нулю, цикл завершается. Если числа выходят за указанные пределы,
Подсказка: на пересечении 1-й строки и 1-го столбца находится чёрная клетка.
Глава 17
И вновь за парту
Натешившись глупой игрушкой, сотворенной нами в предыдущей главе, с новыми силами набросимся на экзаменатора, ведь он ещё не совсем настоящий. Настоящий экзаменатор выставляет оценку, не так ли? Пусть наша программа оценивает ученика по количеству допущенных ошибок. Ответив, к примеру, на 15 вопросов, ученик получит:
• «отлично» – за ноль ошибок;
• «хорошо» – за 1-2 ошибки;
• «удовлетворительно» – за 3-5 ошибок;
• «неуд» – за 6 ошибок и более.
Цикл со счетчиком
Очевидно, что новая версия экзаменатора будет циклической (рис. 39), только условие выхода из цикла будет теперь другим.
Рис. 39 – Блок-схема экзаменатора, выставляющего оценку
Основное отличие этой версии от предыдущих состоит в применении счетчиков. Один из них подсчитывает количество заданных вопросов (то есть проходов цикла), а другой – количество ошибок. Что такое счетчик? Это числовая переменная, наращиваемая по ходу выполнения программы. Сначала рассмотрим тонкости, связанные с подсчетом вопросов.
Зададимся простой задачей: распечатать на экране числа от 1 до 10. Вот как это делается оператором REPEAT-UNTIL.
var N : integer; { счетчик }
begin
N:=1;
repeat
Writeln(N);
N:= N+1;
until N>10
end.
Первый из выделенных операторов устанавливает счетчик цикла в единицу, – программисты называют это инициализацией цикла. Другой выделенный оператор наращивает счетчик. Эта пара операторов, как принято говорить, организует цикл. Слабость такой организации в том, что действуют операторы порознь, а это таит две неприятности.
Человеку свойственно ошибаться, и программисты забывают порой вставить в программу ту или иную строчку.
Цикл со счетчиком объединяет в одной конструкции три действия: инициализацию счетчика, его приращение и проверку условия завершения цикла. Если б написать его по-русски, то оператор выглядел бы так:
ДЛЯ N:= начальное_значение ДО конечное_значение ВЫПОЛНИТЬ оператор
Но русским Паскаль не владеет, а потому переведем это на английский:
FOR N:= начальное_значение TO конечное_значение DO оператор
Как видите, конструкция построена на трех ключевых словах: FOR-TO-DO. После слова FOR следует оператор присваивания начального значения счетчику цикла. За словом TO указывают конечное значение счетчика, а после DO – выполняемый внутри цикла оператор. Но где наращивается счетчик? А нигде, это происходит автоматически! Теперь задача распечатки чисел может быть решена одним составным оператором.
var N : integer; { счетчик }
begin
for N:=1 to 10 do Writeln(N);
end.
Испытайте эту программку. Согласитесь, что ошибиться здесь труднее, чем в варианте с REPEAT. Как только вы написали FOR, то обязаны тут же указать начальное и конечное значения счетчика, а наращивать его Паскаль будет и без вас. В качестве начального и конечного значений вы вправе указать не только числа, но и выражения, – они будут вычислены один раз в начале цикла. Если начальное значение счетчика окажется равным конечному, цикл выполнится единожды. А если конечное значение окажется меньше начального, то ни разу!
Осталось ответить лишь на один вопрос: что, если внутри цикла надо выполнить несколько операторов? Ведь после слова DO предусмотрен лишь один. Впрочем, те, кто помнит об операторных скобках BEGIN-END, знают ответ. Напомню, что эти скобки превращают группу операторов в единый блок, этим мы и воспользуемся в новой версии экзаменатора.
{ P_17_1 – экзаменатор, выставляющий оценку }
var A, B, C : integer; { сомножители и произведение }
Q, E : integer; { счетчик вопросов и счетчик ошибок }
S: string;
begin
Randomize;
E:= 0; { обнуляем счетчики ошибок }
for Q:= 1 to 15 do begin { 15 вопросов }
A:= 1+ Random(10); B:= 1+ Random(10);
Write(Q,’) Сколько будет ’, A,’ x ’,B, ’ ? ’);
Readln(C);
{ Если ответ неверный, увеличиваем счетчик ошибок }
if A*B <> C then E:= E+1;
end; { цикл и блок завершаются здесь}