Организация данных в ЭВМ и основы программирования (1017140), страница 7
Текст из файла (страница 7)
End;
Begin Readln;
Podshet (tochka);
Writeln (‘Кол-во точек=’s:3);
Podshet (‘A’);
Writeln (‘Кол-во букв A=’,S:3);
End.
Программы Pod и Pod1 работают одинаково. Для конкретной задачи программист можно выбирать тот или иной способ передачи результатов работы процедуры и вызвавшую её программу.
Однако в сложных программных комплексах не рекомендуется использовать глобальные переменные, т.к. это ухудшает структурированность программы.
Пример:
Procedure Summa (A:integer;var B:Integer);
Begin A:=A+3;B:=B+3;
End;
В основной программе: A:=5; B:=5;
Summa (A,B);
Write (A,B);
Здесь значения A:=5; B:=5 передаются в процедуру, где вычисляются новые значения A=5+3=8 и B=5+3=8. Новое значение В передается в программу, а значение А нет. Поэтому в основной программе будет А=5, В=8.
Если в процедуру нужно передать в качестве параметра не просто одно значение, а массив, то в этом случае фактически параметрами является имя массива. При этом формальный параметр указывается после слова var вместе с типом массива. Само же описание массива делается в разделе type основной программы.
В языке программирования Паскаль допускается использование процедур без параметров. В этом случае отсутствует как формальные, так и фактические параметры.
Пример: Определить длину окружности С, площадь круга S, (радиуса = R) удаление L центра окружности от начала координат. X, Y – координаты центра окружности.
1й вариант
y
R
y
L
x x
Program Ex;
Var R:Real;(*радиус*)
X,Y,:Real; (*центр*)
C:Real; (*длина окружности*)
S:Real; (*S круга *)
L:Real; (*Удаление центра*)
Procedure Round;
Begin
C:=2*Pi*R;
S:=Pi*SQR(R);
L:=SQRT (SQR(X)+SQR(Y));
End;
Begin
Writeln (‘Ввод);
Read (r,x,y);
Round; (*вызов процедуры*)
Writeln (‘Длина окр-ти=’,C:6:2);
Writeln (‘S круга=’,S:6:2);
Writeln (‘Удал-е центра=’,L:6:2);
End.
2й вариант
Program Ex;
Var R,X,Y,C,S,L:Real;
Procedure Round (R,X,Y:Real; Var C,S,L);
Begin
C:2*Pi*R;
S:=Pi*SQR (R);
L:=SQRT (SQR (X)+ SQR (Y));
End:
Begin
Writeln (‘Ввод’);
Read (R,X,Y);
Round (R,S,Y,S,L,C);
Writeln (‘Длина окружности=’,C:6:2);
Writeln (‘S круга=’,S:6:2);
Writeln (‘Удаление центра’,L:6:2);
End.
4.2. Стандартные процедуры
Это, в первую очередь, процедуры ввода и вывода Read, readln, write, writeln. С ними вы знакомы.
В циклах Repeat, While и For можно использовать еще две процедуры – Break и Continue. Процедура Break позволяет досрочно выйти из цикла, не дожидаясь выполнения условий выхода.
Процедура Continue позволяет начать новую итерацию цикла, даже если предыдущая не завершена.
Пример: В массиве целых чисел найти первое отрицательное число и вывести его на экран.
Фрагмент программы
For I:=1 to N do {поиск отрицательного числа}
Begin
If A[i]>=0 then
Continiue; {не отр.=> на след. число}
Writeln (‘1-ое отриц. число=’, A[i]);
Break
End;
Процедура Exit служит для досрочного выхода из программы. Дело в том, что безусловный переход с использованием оператора goto можно осуществлять далеко не из каждого места программы и не в любое место программы. Так, например, нельзя с его помощью перейти из основной программы в подпрограмму или выйти из подпрограммы. Для этой цели используется процедура Exit.
Пример: Функция, обращает первое отрицательное число в массиве.
Function Minus
---------------------
Begin
Minus:=0
For i:=1 to N do
If T[i]<0 then
Begin
Minus:=T[i];
Exit {досрочный выход из фун-и}
END
End;
Существует множество стандартных процедур, которые работают с файлами:
Halt(1) - остановка,
Halt(0) - завершение,
Halt=Halt(0).
4.3. Описание функций
Описание функции в основном аналогично описанию процедуры, однако есть и отличия. Результатом работы функции является одно значение. Тип результата задается в заголовке.
Общий вид заголовка функции:
Function имя функции (список формальных параметров):тип результата.
Если функция изменяет значения формальных параметров – переменных или значения глобальных по отношению к данной функции переменных, то говорят, что функция имеет побочный эффект.
Применение функции с побочным эффектом нарушает структурированность программы, поэтому их использование нежелательно.
Среди входящих в функцию операторов должен обязательно присутствовать хотя бы один оператор присваивания, в левой части которого стоит имя функции. Этот оператор и определяет значение, вырабатываемое функцией. При вызове функции передача фактических параметров производится так же, как и при вызове параметра.
Пример: Найти разность двух факториалов: F=m!-k!
Program P1;
Var F,M,K:Integer;
Function Fact (N:Integer):Integer;
Var P,I:Integer;
Begin
P:=1
For I:=2 to N do
P:=P*I;
Fact:=P
End;
Begin
Writeln (‘Ввод М,К’);
Readln (M,K);
F:=Fact (M) – Fact (K);
Writeln (‘F=’,F:5);
End.
Внутри функции имена N,P,I являются локальными. Результат вычисления факториала обозначается именем функции Fact. В основной программе переменные F,M,K являются глобальными. При вычислении значения F дважды происходит обращение к функции Fact(M) и Fact(k) прямо в правой части оператора присваивания. При этом вызов функции м. делать непосредственно внутри выражения, подобно тому, как используются стандартные встроенные функции, например Sin(x).
П ример: вычислить длину гипотенузы.
S=h/tg
Program Dlina;
Const Pi=3.14159;
Var H:Real;
Betta:Real;
Function S(M:Real;Betta:Real):Real;
Var x:Real;
Begin x:=Betta*Pi/180;
S:=H/(sin(x)/cos(x));
End;
Begin x:=Betta*Pi/180;
S:=H/9sin(x)/cos(x));
End;
Begin Write (‘Ввести Betta,H’);
Readln (Betta,H);
Write (‘S=’,s(H,Betta):10:4);
End;
Вызов функции осуществляется непосредственно в операции ввода.
4.4. Стандартные функции
Они вам известны: это арифметические, алгебраические и тригонометрические функции. Кроме того, есть функция конца строки: Eoln - end of line.
4.5. Итерация и рекурсия
Итерация (от лат. повторение) - повторение, применение какой – либо математической.
Пример: Вычислить сумму ряда:
S=a1+a2+….+an
S1=a1
S2=a1+a2
S3=a1+a2+a3
S4=a1+a2+a3+a4
…………………
S=a1+a2+…+an
Рекурсия (от лат. возвращение) - вычисление последующего значения ряда через предыдущее. Последовательность, в которой соседние значения связаны формулой, называется рекурсивной.
Пример: Арифметическая прогрессия: a1, a2=a1+d, a3=a2+d, an=an-1+d
Пример.
Begin
If (n=0) or (n=1) then Factorial:=1
Else begin F:=1
For i:=2 to n do
F:=f*i;
Factorial:=f;
End;
End;
Begin Writeln (‘Введите N’);
Readln (N);
Writeln (‘факториал=’,Fact);
End.
Пример.
Program Rekursion;
Var fact:real;
N:integer;
Function Factorial (N:integer):real;
Begin
If (n=0) or (N=1) then factorial:=1
Else factorial:=factorial (N-1)*n;
End;
Begin
writeln (‘Введите N’);
Readln (N);
Fact:=factorial (N);
Writeln (‘факториал=’,fact);
End.
Здесь первый вызов функции происходит в основной программе, а затем, начинается рекурсивный вызов внутри функции.
В языке программирования Паскаль есть возможность обращения процедуры или функции к самой себе. При этом циклическую часть программы можно составить без операторов цикла. Способ обращения процедуры или функции к самой себе называется рекурсией. С помощью рекурсии удобно представлять те задачи, которые сводятся к подзадачам того же типа, но меньшей размерности.
Вычисление факториала можно представить опять через факториал.
N!=n(n-1)!-рекурсивная формула.
Представление факториала в виде последовательности операций умножения – это итерационный процесс. n!= 1*2*3…n-итерационная формула. Итерация программируется с помощью циклов.
Пример: Вычисление факториала.
Program Iteracion ;
Var fact: real;
N:integer;
Function factorial (n: integer):real;
Var f:real;
I: integer;
Пример. В 13 веке итальянский математик Фибоначчи сформулировал задачу: ”Некто поместил пару кроликов в некое место, огороженное со всех сторон стеной, чтобы узнать, сколько пар кроликов родится в течении года, если через месяц пара кроликов производит на свет другую пару, а рожают со второго месяца после своего рождения.
Program Krolik;
Var kr:integer; (*число кроликов*)
N:Integer; (*число месяцев*)
Function fib(n:integer):integer;
Begin
If (n=1) or (n=2) then fib:=1
Else fib:=fib(n-1)+fib(n-2)
End;
Begin
Writeln(‘ввести N’);
Readln (N);
Kr:=fib (N); (*вызов ф-и*)
Writeln (kr:5);
End.
4.6. Побочный эффект рекурсии
В теле подпрограммы известны, то есть доступны все объекты, описанные в объемлющем блоке, в том числе и имя самой подпрограммы. Внутри тела подпрограммы возможен вызов самой подпрограммы. Параметры и функции использующие вызовы “самих себя“, называются рекурсивными. Допустима также косвенная рекурсия, при которой параметр А вызывает параметр В, а тот, в свою очередь, вызывает С, который вызывает первоначальный параметр А.
Рекурсия достаточно широко применяется в программировании, что основано на рекурсивной природе многих математических алгоритмов. В языке программирования Паскаль нет никаких ограничений на рекурсивные вызовы подпрограмм, необходимо только понимать, что каждый очередной рекурсивный вызов приводит к образованию новой копии локальный объектов подпрограммы и все эти копии, соответствующие цепочке активизированных и не активизированных рекурсивных вызовов, существующих независимо друг от друга.
При выполнении функций возникает один неожиданный эффект, причиной которого является изменение значений нелокальных переменных в теле функции.
Если в некоторой функции имеются конструкции, например, операторы присваивания, изменяющие значения переменных, описанных в объемлющих блоках, то может возникнуть ситуация, при которой значения выражения, использующего вызов такой функции, зависит от порядка следования операторов, что является потенциальным источником ошибок и поэтому крайне нежелательно. Описанная ситуация называется побочным эффектом рекурсии.
Пример:
Program Side Effect;
Var a,z :integer;
Function change (x: integer): integer;
Begin
Z:=z-x; {изменяем значение нелокальной переменной}
Change:= sqr (x)
End;
Begin
Z:=10; a:=change (z); writeln(a,z);
Z:=10; a:=change (10)*change (z);
Writeln(a,z);
Z:=10; a:=change (z) * change(10);
Writeln (a,z)
End.
Выполнение этой программы приводит к следующему результату на дисплее:
100 0
10000 -10
0 0
Т.е. два последних присваивания переменной а дают различный результат, хотя правила вычисления выражений предлагают равноправные сомножители.
Следует всячески избегать такой зависимости функции от глобальных по отношению к ней переменных. Заметим, что современные языки, например, Ada содержит прямые запреты на подобные действия.
4.7. Предварительное описание (ссылки вперед)
Объявления констант и переменных в любом блоке располагаются перед скобками begin ...end (в этих скобках заключены сами операторы). Поэтому компилятору никогда не приходится иметь дело с оператором, содержащим константы и переменные, которых он не знает, это вызовет во время компиляции сообщение об ошибке. Все это справедливо и в отношении подпрограмм (т.е. функций и процедур). Программист обязан следить за правильным порядком следования определений (описаний).
Пример :