Совсем недавно, кстати, рассказывая про алгоритм Краута разложения квадратной матрицы в произведение двух треугольных, столкнулся с недостатком языка Паскаль. Схема алгоритма там такая:
procedure UnsymDet (...; var fail: Boolean);
...
begin
{ некоторые вычисления }
for k := 1 to n do
begin
{ вычисление ведущего элемента x столбца k }
if abs(x) < eps then
{ надо присвоить fail := true и выйти, но как??? }
end
end.
Иными словами, внутри цикла выясняется, что матрица вырожденная. Нужно прекратить вычисления и вернуть соответствующий признак в вызывающую программу. В Си и Фортране для этого есть оператор return. И в Модуле-2 есть. Но в Паскале нет! Можно пойти двумя путями. Первый - эффективный:
procedure UnsymDet (...; var fail: Boolean);
label
1;
...
begin
fail := false;
{ некоторые вычисления }
for k := 1 to n do
begin
{ вычисление ведущего элемента x столбца k }
if abs(x) < eps then
begin
fail := true;
goto 1
end
end
1:
end.
Второй «правильный»:
procedure UnsymDet (...; var fail: Boolean);
...
var
Ok: Boolean;
begin
{ некоторые вычисления }
Ok := true;
k := 0;
while Ok and (k < n) do
begin
k := k + 1;
{ вычисление ведущего элемента x столбца k }
Ok := abs(x) >= eps;
if Ok then
begin
{ продолжение вычислений }
end
end;
fail := not Ok
end.
Кстати, в школьном курсе информатики используется язык, первые версии которого были придуманы еще А.П. Ершовым в 80-е гг. XX в. Особого названия у него нет, но часто говорят «Е-язык». Так вот там есть оператор выход, но его смысл зависит от контекста. Если он встречает вне цикла, то означает выход из алгоритма (программы или подпрограммы). Но если в цикле, то выход только из цикла, причем самого внутреннего. А goto нет! Поэтому приходится извращаться. Завтра приведу пример.