Учебный центр "ANIT Texno Inform"
Опубликован: 25.06.2014 | Доступ: свободный | Студентов: 2595 / 850 | Длительность: 24:39:00
Специальности: Программист
Лекция 10:

Циклы и переключатель case

Условный цикл while…do

Слово while переводится как пока, а do - как делать. Другими словами, цикл while…do выполняется до тех пор, пока какое-то условие верно. Синтаксис:

while <условие> do <оператор>;
    

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

Если же значение условия изначально будет false, то цикл не будет выполнен ни разу.

Оператор также может быть составным, если находится в скобках begin…end.

В цикле while…do также можно использовать операторы break и continue.

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

var b: boolean;
begin
   b:= true;
   while b = true do 
      ShowMessage('Истина');
    

Здесь цикл while будет выполняться до тех пор, пока b будет оставаться true. А поскольку внутри цикла не предусмотрено изменение значения b, цикл получился "зацикленным". Он будет выводить сообщение "Истина" до тех пор, пока у вас не сгорит компьютер, либо пока вы сами его со злости не разобьёте (шучу, у вас всегда есть возможность прервать зависшую программу).

Обратите внимание на строку

   while b = true do
    

Я так написал, чтобы сразу было понятно, что тут к чему. Для цикла важно, чтобы условие было истинным. Поскольку b действительно равно true, то условие истинно. Но в этом случае можно было написать проще:

   while b do
    

Ведь b итак содержит true! А зацикленный цикл можно написать еще понятней, вообще обойдясь без переменной:

   while true do
    

Делать, пока истина, то есть, всегда. Все эти три примера будут равноценны. Однако вернемся к нашему проекту, и опробуем цикл на практике. Мы будем 100 делить на любое введенное пользователем число, и выводить результат. Причем будем делать это, пока пользователю не надоест, то есть, заранее неизвестно, сколько раз. Когда же ему надоест вводить числа, он введет ноль. Мы со своей стороны выведем сообщение, что на нуль делить нельзя, и на этом завершим работу цикла. Проверку на корректность введенного числа производить не будем. Пользователь сам будет контролировать введенное значение.

Чтобы не заниматься переделкой кода, добавим на форму еще одну кнопку, в Caption которой напишем

while…do
    

чтобы было понятно, какая кнопка с каким циклом работает. Для кнопки сгенерируем такое событие OnClick:

procedure TfMain.Button2Click(Sender: TObject);
var
  s: string; //для получения числа от пользователя
  r: real; //результат деления
  begin
    //начинаем цикл
    while true do begin
      //очистим строку:
      s:= '';
      //получим число от пользователя:
      InputQuery('100 / на...', 'Введите число', s);
      //если ноль, выводим сообщение и выходим из цикла:
      if s = '0' then begin
        ShowMessage('На нуль делить нельзя!');
        break;
      end;
      //если еще не вышли, значит не нуль. делим:
      r:= 100 / StrToFloat(s);
      //выводим результат:
      ShowMessage('100 / ' + s + ' = ' + FloatToStr(r));
    end;  //конец цикла
end;
    

Комментарии достаточно подробны, но все же проясним некоторые детали. Прежде всего, мы сделали "зацикленный" цикл:

    while true do begin
    

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

      if s = '0' then begin
        ShowMessage('На нуль делить нельзя!');
        break;
      end;
    

Поэтому компьютер не зависнет - стоит пользователю ввести ноль, как цикл прекратится. Как пользоваться функцией InputQuery() вы, надеюсь, не забыли? Если забыли, вернитесь к "Стандартные строковые функции и сообщения" . Всё остальное должно быть понятно по предыдущим примерам.

Когда цикл начнется, пользователю выйдет запрос:

Запрос пользователю

Рис. 10.3. Запрос пользователю

При вводе числа не забывайте о десятичном разделителе, который зависит от языка операционной системы. В русских Windows это запятая, в английских - точка. Если введете неправильное (некорректное) число, программа зависнет. Сбросить отладку просто: <Запуск -> Сбросить отладчик>.

Условный цикл repeat…until

Цикл repeat…until - еще один условный цикл. Однако есть и отличия. Если while…do - цикл с предусловием, то repeat…until имеет постусловие. То есть, если в цикле while…do вначале проверяется условие, и в зависимости от этого условия принимается решение - выполнять ли цикл, то в repeat…until вначале выполняется цикл, а затем только проверяется условие. Другими словами, цикл repeat…until обязательно будет выполнен хотя бы однажды. Причем, опять таки, в отличие от while…do, цикл repeat…until будет выполняться до тех пор, пока условие ложно, и прекратит свою работу, когда условие станет истинным.

Англ. repeat переводится, как повторять, until - до тех пор, пока… Другими словами - выполнять какие то действия до тех пор, пока не выполнится условие. Синтаксис простой:

repeat <оператор(ы)> until <условие>;
    

Обратите внимание: ключевые служебные слова repeat…until работают, как операторские скобки begin…end, поэтому в тело цикла можно включить сколько угодно операторов. Проверим работу цикла на примере. Добавьте в проект третью кнопку, в Caption которой напишите

repeat…until
    

Код нажатия на кнопку будет следующий:

procedure TfMain.Button3Click(Sender: TObject);
var
  i: byte;
  s: string;
begin
  //зададим начальное значение счетчика:
  i:= 1;
  //теперь сам цикл:
  repeat
    s:= s + 'Квадрат от ' + IntToStr(i) + ' равен ' + IntToStr(i * i) + #13;
    i:= i + 1;
  until i > 10;
  //отчет:
  ShowMessage(s);
end;
    

Как видите, внутри цикла выполняется два оператора, при этом никаких скобок begin…end не используется. Внутри цикла мы обеспечиваем наращивание счетчика - если этого не сделать, программа зациклится, так как i никогда не станет больше 10. В нашем примере i увеличивается, и как только она станет больше 10, цикл прекращает работу, управление передается дальше, на ShowMessage(). В результате мы получим следующий отчет:

Работа цикла repeat…until

Рис. 10.4. Работа цикла repeat…until

Операторы break и continue также можно использовать в этом цикле.

Переключатель case

Переключатель case не относится к циклам, это оператор множественного выбора. Синтаксис:

case <Селектор> of
   <Значение 1>: <Оператор 1>;
  <Значение 2>: <Оператор 2>;
  …
  <Значение n>: <Оператор n>
  else <Оператор Иначе>;
end;
    

Здесь, Селектор - это переменная или выражение исчисляемого типа. То есть, как правило, это целое число или символ (для ПК символ - число, номер в таблице ANSI, то есть, исчисляемый тип), или выражение, которое возвращает в результате целое число или символ.

Далее, в зависимости от значения селектора, выполняется соответствующий оператор. Если нужно выполнить блок операторов, их заключают в операторские скобки begin…end.

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

Для примера установим на форму последнюю, четвертую кнопку, в Caption которой напишем:

case
    

Код события нажатия на кнопку будет таким:

procedure TfMain.Button4Click(Sender: TObject);
var
  i: integer;
  s: string;
begin
  //очистим строку:
  s:= '';
  //получим число от пользователя:
  InputQuery('Квадрат целого числа', 'Введите целое число от 1 до 3:', s);
  //преобразуем строковое представление числа в число:
  i:= StrToInt(s);
  //теперь выбор case
  case i of
    1: ShowMessage('Квадрат от 1 равен 1');
    2: ShowMessage('Квадрат от 2 равен 4');
    3: ShowMessage('Квадрат от 3 равен 9')
    else ShowMessage('Неизвестное число, нет решения');
  end;
end;
    

Код достаточно понятен, чтобы его дополнительно комментировать. Когда пользователь нажмет на кнопку "case", выйдет запрос на ввод целого числа. Если ввести число от 1 до 3, то будет выполнен соответствующий оператор. Если целое число будет другим, выполнится оператор else. Если ввести не целое число, а что-то другое, то произойдет ошибка, которую можно будет снять, сбросив отладчик.

Если вам потребуется выполнить более одного оператора в каждом случае, то это можно оформить, например, так (код для примера, выполнять его вам не нужно):

case i of 
  1 : begin
          ShowMessage('i = 1');
          f:= 10;
      end;
  2 : begin
          ShowMessage('i = 2');
          f:= 20;
      end;
  3 : begin
          ShowMessage('i = 3');
          f:= 30;
      end;
  else ShowMessage ('i не равно 1, 2, или 3'); 
end; //конец case
    

Собственно, этот же код можно было бы реализовать и посредством условного оператора if:

if i = 1 then …
else i = 2 then …
    

и так далее. Однако данный пример больше подходит для инструкции case - код получается более компактным, лучше читаемым. На сегодня это всё, данных инструментов будет достаточно, чтобы организовать сколь угодно сложную логику программы.

Инга Готфрид
Инга Готфрид
Александр Скрябнев
Александр Скрябнев

Через WMI, или используя утилиту wmic? А может есть еще какие более простые пути...