Мітки у Pascal

ред.

Цей розділ описує практику програмування, що вважається зараз вкрай грубою і некультурною; тим не менш, ознайомитися із цією практикою треба для загального розвитку. Будь ласка, намагайтеся уникати цієї практики в реальному програмуванні.

Припустимо, що нам треба виконати в залежності від умови кілька дій. Наприклад, в попередньому прикладі нам довелося викинути з програми окреме обчислення змінної x. Давайте повернемо його:

program LinearEquation;
var a,b,x:real;
begin
  writeln('Ця програма розв''язує лінійне рівняння ax=b');
  write('a=');
  readln(a);
  write('b=');
  readln(b);
  if a<>0 then 
  x:=b/a;
  writeln('x=',x);
  else if b=0 then writeln('Будь-яке дійсне число задовільняє цьому рівнянню')
  else writeln('Рівняння не має дійсних розв''язків');
end.

Але тепер треба позначити крапкою з комою межу виразів x:=b/a та writeln('x=',b/a) - а це розірвало конструкцію if-then-else, програма тепер не запускається! Нам треба якось позначити, що після виконання перевірки іноді треба "перестрибнути" кілька команд. Такий стрибок можливий за допомогою команди goto мітка(англ. go to - "перейти до"), мітки в потрібному місці і проголошення мітки на початку програми, в розділі label(англ. "мітка"):

program LinearEquation;
label 0000,0001;
var a,b,x:real;
begin
  writeln('Ця програма розв''язує лінійне рівняння ax=b');
  write('a=');
  readln(a);
  write('b=');
  readln(b);
  if a=0 then goto 0000;
  x:=b/a;
  writeln('x=',x);
  goto 0001;
  0000:if b=0 then writeln('Будь-яке дійсне число задовільняє цьому рівнянню')
       else writeln('Рівняння не має дійсних розв''язків');
  0001:
end.

Якщо умова a=0 буде виконана, відбудеться перехід на рядок, позначений 0000:. Умова тепер змінена на протилежну, але це просто тому, що гілки помінялися місцями (goto перекидує управління в інше місце, замість того, щоб залишити на місці). Також довелося додати ще один стрибок після закінчення обчислень, перед другим if: якщо цього не зробити, ця гілка буде виконана в будь-якому разі, навіть після виводу x.

Мітки в старих версіях Паскалю можуть бути тільки числовими до від 0000 до 9999, в нових мітки можуть бути як числами, так і ідентифікаторами.

Проблема такої програми в тому, що порушується порядок виконання рядків, і то неочевидним способом, а отже, зменшується її читаність. Поки стрибків небагато, програму ще можна розібрати, але зі зростанням кількості стрибків зневадження такої програми стає дуже складною і розтягнутою справою, практично головоломкою. Тому міток і команд goto слід уникати.

Блоки

ред.

Щоб виконати за однієї умови кілька команд і при цьому зберегти читаність програми, використовують блоки або складні вирази begin-end. Набір команд, розміщених між ключовими словами begin та end, розглядається в конструкціях мови Паскаль як одна команда - так, як в наведеному прикладі:

program LinearEquation;
var a,b,x:real;
begin
  writeln('Ця програма розв''язує лінійне рівняння ax=b');
  write('a=');
  readln(a);
  write('b=');
  readln(b);
  if a<>0 then begin
    x:=b/a;
    writeln('x=',b/a)
  end
  else if b=0 then writeln('Будь-яке дійсне число задовільняє цьому рівнянню')
  else writeln('Рівняння не має дійсних розв''язків');
end.

Зверніть увагу на:

  • відсутність крапки з комою між end та else;
  • відступи всередині блоку begin-end. Такі відступи не є обов'язковими, але їх вкрай бажано ставити, бо це одразу вказує читачеві програми на те, що сусідні команди з однаковими відступами стосуються однієї гілки програми.

Ключові слова begin та end інколи звуть операторними дужками, бо вони працюють подібно до математичних дужок, об'єднуючи кілька дій в одну.

Завдання

ред.

1. Розгляньте такий приклад:

if a=1 then 
  if b=2 then writeln('a=1, b=2')
  else writeln('a - ?,b - ?');

Як гадаєте, що треба написати замість знаків питання? Якого саме з if стосується останній else? Підказка: зверніть увагу на відступи. Як зробити так, щоб else стосувався іншого if? Підказка: застосуйте конструкцію begin-end.