Паскаль. Оператор перехода GOTO

Паскаль. Оператор перехода GOTO

Оператор перехода. Цикл. Метки

Цикл - главное средство заставить компьютер много раз сделать одно и то же или похожее. Посмотрим, как же осуществить цикл на Паскале. Предположим, мы хотим, чтобы компьютер бесконечно повторял выполнение следующего фрагмента:

Write('Это ');
Write('тело ');
Write('цикла');
Write('  ');

На мониторе мы увидим:

Это тело цикла Это тело цикла Это тело цикла Это тело цикла …

Большинство языков программирования (в том числе и Паскаль) устроены так, что операторы выполняются в том порядке, в котором они записаны. Это значит, что после оператора Write('Это ') обязательно выполнится оператор Write('тело '), а после него - Write('цикла'), а после него - Write(' '). Все это хорошо. Но нам нужно, чтобы после выполнения оператора Write(' ') Паскаль нарушал этот свой принцип последовательного выполнения операторов и выполнял бы оператор Write('Это '). Если мы этого добьемся, то дальше все пойдет само собой, так как после Write('Это ') Паскаль автоматически выполнит Write('тело ') и так далее до бесконечности.

Если бы операторы Паскаля можно было писать по-русски, то для достижения нашей цели было бы естественно воспользоваться такой конструкцией:

метка m1: Write('Это ');
          Write('тело ');
          Write('цикла');
          Write(' ');
          иди к оператору, помеченному меткой m1

Здесь мы видим новый для нас «оператор» ИДИ, который выполняется после Write (' ') и единственная работа которого заключается в том, чтобы заставить компьютер перескочить к выполнению оператора Write('Это '), помеченного меткой m1.

А вот как этот фрагмент выглядит реально на Паскале:

m1: Write ('Это ');
    Write ('тело ');
    Write ('цикла');
    Write (' ');
    GOTO m1;

Здесь GOTO - оператор перехода, читается «гоуту», переводится «ИДИ К», m1 - метка. Метка - это произвольное имя или произвольное не слишком большое целое положительное число. Оператор GOTO можно писать в любых местах программы и метку можно ставить перед любым оператором, заставляя компьютер таким образом перескакивать в программе откуда угодно куда угодно (правда, в сложных программах и внутри сложных операторов эта свобода перескакивания существенно ограничивается. Метка должна отделяться от оператора двоеточием.

Мы пока знаем, что переменная, встречающаяся в программе, должна быть описана выше Begin после слова Var. Метки, встречающиеся в программе, тоже должны быть описаны выше Begin после слова Label (читается «лэйбл», переводится «МЕТКА»).

Вот наша программа полностью:

Label m1;
Begin
m1: Write('Это ');
    Write('тело ');
    Write('цикла');
    Write(' ');
    goto m1
End.

Если вы уже запустили эту программу, то через некоторое время перед вами должен встать жизненно важный вопрос – как же ее остановить? В PascalABC.NET достаточно нажать кнопку «Завершить», которая находится рядом с кнопкой «Выполнить». В других средах программирования должна помочь комбинация клавиш «Ctrl-Break» (имеется в виду, что, удерживая нажатой клавишу «Ctrl», вы должны щелкнуть по клавише «Break»). На экран возвращается окно редактора. Строка программы, на которой она была прервана, выделяется полосой белого цвета. Если вы снова запустите программу, она продолжит работу с прерванного места. Чтобы начать сначала, уберите полосу с экрана клавишами «Ctrl-F2».

Группа операторов, выполняющихся многократно, называется телом цикла. У нас это все операторы, начиная с Write('Это ') и кончая goto m1.

Пример программы:

Label 8;
Var a,k: Integer;
Begin
    k:=6;
    a:=100;
    goto 8;
    a:=a+k;
    k:=2*k;
    WriteLn(a);
 8: a:=a+1;
    k:=k+10;
    WriteLn(k,' ' ,a);
End.

Эта программа напечатает 16 101. Операторы выполняются в такой последовательности:

k:=6;
a:=100;
goto 8;
a:=a+1;
k:=k+10;
WriteLn(k,' ' ,a);	

А операторы a:=a+k; k:=2*k; WriteLn(a) выполнены не будут вообще, несмотря на то, что написаны.

Задание 1

Определить без компьютера, что будет печатать программа:

Label m1,met5; 
Var n,k: Integer;
Begin
      n:=10; k:=0;
      WriteLn('Считаем зайцев' ); 
met5: Write(n);
      n:=n+k;
      goto m1;
      n:=n+1;
  ml: Write(' зайцев ');
      k:=k+1;
      goto met5;
      WriteLn('Сосчитали зайцев') 
End.

Задание 2

Написать программы для выполнения следующих заданий:

  • Бесконечно печатать букву А: ААААААААААА;    
  • Бесконечно печатать 1000 999 998 997 996;
  • Бесконечно печатать 100 50 25 12.5.... с 8 десятичными знаками.

Примечание: Во всех программах используйте ReadLn для создания паузы на каждом цикле. Чтобы программа шла все-таки довольно быстро, нажмите клавишу ввода и не отпускайте.

Выход из цикла с помощью if

Интересно рассмотреть применение оператора goto внутри операторов if или case.

Задача:

При помощи цикла напечатать на экране:

Начало счета 3 5 7 9 Конец счета

Вот три варианта программы. Первый - самый простой, а второй и третий нам понадобятся в дальнейшем.

Вариант 1Вариант 2
Label m;
Var f: Integer;
Begin
Write('Haчaлo счета ');
f:=3;
m:  Write(f,' ');
f:=f+2;
if f<=9 then goto m;

Write(' Конец счета')
End.
Label m1,m2;
Var f: Integer;
Begin
Write('Haчaлo счета ');
f:=3;
m1: Write(f,' ');
f:=f+2;
if f>9 then goto m2
else goto m1;
m2: Write(' Конец счета')
End.

Вот в каком порядке выполняются операторы программы первого варианта:

Write('Начало счета ');
f:=3; Write(f,' '); {печатается 3}
f:=f+2; {f становится равным 5}
if f<=9 goto m;
Write(f,' '); {печ. 5}
f:=f+2; {f = 7}
if f<=9 goto m;
Write(f,' '); {печ. 7}
f:=f+2; {f = 9}
if f<=9 goto m;
Write(f,' '); {печ. 9}
f:=f+2; {f = 11} 
if f<=9 Write(' Конец счета')

Здесь оператор goto выполняется три раза. На четвертый раз условие f<=9 оказывается ложным и поэтому выполняется не goto, а следующий за if оператор Write('Конец счета'), то есть программа выходит из цикла и завершает свою работу.

Вариант 3:

Label m1,m2,m3;
Var f: Integer;
Begin
    Write('Начало счета ');
    f:=3;
m1: if f<=9 then goto m3
    else goto m2;
m3: Write(f,' ');
    f:=f+2;
    goto m1;
m2: Write(' Конец счета')
End.

Задание 3

  • Напечатать 20000000 раз числа 1 2 3 4. . . 99 100 99. . . 3 2 1.
  • «Таблицы Брадиса» - вычислить и напечатать с 6 десятичными знаками квадраты чисел 0.000 0.001 0.002 0.003 . . . 0.999 1.000.
  • Для х=2700, 900, 300, 100 . . . и т.д. вычислять и печатать y=x/4 + 20 и z=2y+0.23 до тех пор, пока yz не станет меньше 1/х.

Задание 4

Определить без компьютера, что будет печатать программа:

Label m1, m2;
Var i: Integer;
Begin 
    WriteLn('Haчaлo ');
    i:=100;
m1: Write(sqr(i),' ');    
    if i < 50 then goto m2;
       i:=i-10;
    if i>=0 then goto m1;
m2: WriteLn(' Конец ')
End.

Турбо-Паскаль 7.0 - Самоучитель
Лукин С.Н.