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.