И в завершении темы покажем несколько типичных ошибок, которые можно допустить, используя подпрограммы.
Тип ошибки |
Неверное написание |
Несоответствие типов формального и фактического параметров
Здесь фактический параметр типа real, а формальный –типа integer |
Function f1(x: integer): real; begin if x>0 then f1:=1/x else f1:=0.0; end; begin writeln(f1(0.5)); end. |
Несоответствие числа формальных и фактических параметров
Здесь фактических параметров - два, а формальный -один |
Function f1(x: integer): real; begin if x>0 then f1:=1/x else f1:=0.0; end; var a,b:real; begin read(a,b); writeln(f1(a,b)); end. |
Невозвращение значения функцией при одном из условий
На самом деле программа может выдать неожиданный результат в виде 1.38Е-308 - случайное значение в ячейке памяти |
Function f1(x: integer): real; begin if x>0 then f1:=1/x; end; // при x<=0 функция непредсказуема begin writeln(f1(0)); // будет ошибка end. |
Неприсваивание значения для имени подпрограммы-функции
Значение функции при выходе из подпрограммы равно нулю |
Function f1(x: real): real; begin if x>0 then writeln(1/x) else writeln(0.0); end; var a:real; begin read(a); writeln('** ',f1(a)); end. |
Присваивание значения имени подпрограммы-процедуры
Компилятор сообщает об ошибке |
procedure f1(x: real); begin if x>0 then f1:= 1/x else f1:=0.0; end; var a:real; begin read(a); f1(a); end. |
Описание локальной переменной цикла, используемого в процедуре, как глобальной переменной
Значение переменной i в основной программе испорчено. Параметр-переменная цикла i должна быть описана в теле процедуры отдельно |
var i: integer; // глобальная переменная procedure w1(x: integer); begin for i:=1 to 10 do write(x); end; begin i:=7; w1(5); // будет выведено 10 цифр 5 end. |
Передача выходных параметров по значению
В вызывающую программу параметры-значения не возвращаются, т.к в процедуре меняется лишь копия переменной i, а не сама переменная i. Для корректного возвращения в основную программу нового значения i, ее необходимо описывать в заголовке процедуры как параметр-переменная через var |
procedure BadInc(i: integer); begin i:=i+1; writeln(i); end; var i: integer; begin i:=5; writeln(i); // выдаст 5 badinc(i); //выдаст 6 writeln(i); // опять выдаст 5 end. { верное описание процедуры} { procedure BadInc(var i: integer);} |
Можно предложить несколько полезных советом по работе с подпрограммами:
· выделяйте в процедуру (функцию) небольшой логически завершенный фрагмент алгоритма;
· не смешивайте в одной процедуре (функции) ввод-вывод данных и вычислительные алгоритмы;
· называйте свои процедуры (функции) мнемоническими именами;
· если алгоритм, который вы решили выделить в процедуру (функцию), все еще слишком сложен, оформите фрагмент этого алгоритма в другой процедуре (функции);
· если алгоритм должен вычислить одно скалярное значение это должна быть функция, а не процедура;
· если в вашей программе встречаются многократно вложенные циклы или "многоэтажные" условные операторы, это верный признак, что вам нужны процедуры (функции);
· для выхода из подпрограммы используйте в процедурах и функциях процедуру Exit.