Мітки у 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.