Лабораторная работа №8. Программирование с использованием процедур и функций 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Лабораторная работа №8. Программирование с использованием процедур и функций



Цель работы: познакомиться с понятиями "процедура" и "функция" в языке программирования Pascal, рассмотреть их сходства и различия, закрепить практические навыки работы с системой TURBO Pascal на примере реализации алгоритмов при помощи процедур и функций, научиться применять метод последовательной детализации в практическом программировании; применять процедуры и функции при решении задач.

Процедуры и функции

Практически во всех алгоритмических языках имеется возможность программирования функций и процедур - блоков операторов, оформленных в виде подпрограмм. Разработка функций и процедур необходима при многократном использовании в разных местах программы или в нескольких программах блока операторов, выполняющих однотипные действия, например, расчет значений сложной функции при различных значениях аргумента. В Турбо - Паскале имеется также возможность создавать библиотеки (модули), состоящие из специальных процедур и функций, отличных от поставляемых в пакете (модули System, Crt, Graph).

Процедуры (подпрограммы) и функции, определяемые программистом, приводятся в разделе описания основной программы. Процедуры и функции имеют заголовок, раздел описания и раздел операторов.

Заголовок процедуры состоит из служебного слова Procedure, имени процедуры и списка параметров,

например:

Procedure Name_P(p1, p2,...: "тип"; Var p3, p4,...: "тип";...);

Заголовок функции состоит из служебного слова Function, имени функции и списка параметров, кроме того указывается тип возвращаемого функцией значения,

например:

Function Name_F("список формальных параметров"):"тип результа-та";

Здесь:
Function и Procedure - служебные слова,
Name_F, Name_P - имена функции и процедуры соответственно,
p1, p2 - имена формальных параметров-значений,
p3, p4 - имена формальных параметров-переменных,
... - многоточие означает возможность перечисления большего числа параметров.

В дальнейшем, если не оговаривается особо, все сказанное к процедуре относится также и к функции.

Тип возвращаемого функцией значения может быть простым, строковым или типом-указателем. Тип формальных параметров может быть любым, но должен указываться только идентификатором (именем типа). Таким образом, имя типа формального параметра - массива должно быть задано предварительно в операторе Type, например: Type M= array[1..100]of real; Затем тип массива может указываться в заголовке процедуры, например: Procedure Name_P(p: M); Тип формальных параметров описывается только в заголовке процедуры. Список формальных параметров может отсутствовать, например. процедура Randomize; не имеет параметров.

Если в результате выполнения нескольких операторов получается одно значение переменной, то эти операторы можно включить в описание функции. Например, функция Sin(x); возвращает значение, которое присваивается переменной Y:=sin(x); (эта, и другие стандартные функции описаны в модуле System, который подключается к программе автоматически).

Если в результате выполнения нескольких операторов производится некоторое действие или расчет нескольких переменных, то эти операторы лучше включить в описание процедуры. Например, процедура ClrScr; из модуля CRT очищает экран.

Вызов процедуры осуществляется в разделе выполнения основной программы или других процедур (вложенные процедуры). Программа (процедура) внутри которой вызывается другая процедура называется внешней по отношению к вызываемой процедуре.

При вызове процедуры вместо формальных параметров подставляются фактические параметры, значения которых используются в процедуре.

Например:

Name_P(p11, p22,..., p33, p44,...); - вызов процедуры Name_P, Y:= Name_F("список фактических параметров"): - вызов функции Name_F,

Здесь:
p11, p22,... - имена или значения переменных,
p33, p44,... - имена переменных, значения которых возвращаются в программу.
Y - переменная, которой присваивается значение возвращаемое функцией.

Типы соответствующих формальных и фактических параметров должны совпадать, а имена могут совпадать или быть различными. Вместо параметров-значений можно подставлять имена переменных, значения переменных или выражения, вместо параметров-переменных подставляются имена переменных. Функция и параметры-переменные возвращают во внешнюю программу значения, полученные после окончания работы функции или процедуры. Изменения параметров-значений в процедуре носит локальный характер, во внешней программе соответствующие фактические параметры не изменяются. Если не требуется передавать во внешнюю программу новые значения, то следует использовать параметры-значения, а не параметры-переменные.

В процедуре можно использовать локальные метки, константы и переменные, описав их в разделе описания процедуры. Локальные имена не должны совпадать с именами формальных параметров, а их значения не передаются во внешнюю программу. Метки, константы и переменные, описанные во внешней программе раньше, чем сама процедура, называются глобальными по отношению к вызываемой процедуре. Если локальные и глобальные имена совпадают, то в процедуре используются локальные значения, а во внешней программе - глобальные значения, т. е. локальные и глобальные идентификаторы независимы. Если имя глобальной переменной уникально (в процедуре не описывается переменная с таким же именем) и ее значение в процедуре изменяется, то оно изменяется и во внешней программе. Вызывая в программе процедуру программист использует ее имя и параметры не анализируя, а часто и не зная содержимого процедуры. Поэтому в целях универсальности процедур следует все значения в процедуру передавать через список параметров, а переменные внутри процедуры описывать, т. е. делать их локальными.

Приведем пример процедуры вывода на экран визитной карточки программиста.

Program NP_1;Var Dat, Fam: string; { Fam: глобальная переменная }Procedure VIZ(D_R:string); { D_R - формальный параметр }Var S_t: string;{ S_t: локальная переменная }Begin Writeln('| --------------------------------------------- |'); Writeln('| Разработчик программы:', Fam:14,' |'); Writeln('| |'); Writeln('| г. Анжеро-Судженск ', D_R:14,' |'); Writeln('| Телефон: 2-99-76 |'); Writeln('| ----------------------------------------------|'); Write(' Комментарий: '); Readln(S_t) end;Begin Fam:='И.И.Иванов'; Dat:='06.12.95'; {Dat - фактический параметр} VIZ(Dat); { вызов процедуры } Readln;END.

Если процедура описана в другом файле с именем, например, F_PR. pas, то ее можно подключить к программе, указав в разделе описания директиву: {$I F_PR. pas}

Приведем пример использования стандартных процедур модуля DOS для вывода текущей даты и времени:

uses DOS; { подключение модуля DOS }Procedure Date_Time;var y, m, d, d_w:word; h, min, sec, hund: word;{локальные параметры } begin GetDate(y,m,d,d_w); {вызов процедуры DOS, возвращающей параметры даты } GetTime(h,min,sec,hund); { процедура, возвращающая параметры времени } writeln('сегодня: '); writeln('_':10, d, ' число'); writeln('_':10, m, ' месяц'); writeln('_':10, y, ' год'); writeln('день недели: ', d_w); { d_w= 0 - воскресенье, и т. д. } writeln('Время: '); writeln('_':6, h, ' часов'); writeln('_':6, min, ' минут'); writeln('_':6, sec, ' секунд'); readlnend;Begin Date_Time end.

В практических задачах часто пишутся процедуры, возвращающие значения элементов массивов. Приведем пример процедуры расчета "N" значений функции, например, Y= 4*Sin(x)+7*Cos(x); в заданном диапазоне x1<=x<=x2, при N<=100 и равномерной разбивке диапазона.

type r_1000= array[1.. 1000] of real; { задается тип r_1000 }var Z: r_1000; x1, x2: real; n: word;Procedure Mas_Y(var Y:r_1000; x1,x2:real; n:word); {Y - параметр-перемен-ная}var i: word; x, dx: real; { локальные параметры } begin If (n>1000) or (n<2) then begin writeln('Длина массива >1 и не должна превышать 1000'); Readln; Halt end; i:=0; x:=x1; dx:=(x2-x1)/(n-1); { dx - шаг изменения аргумента } If dx<= 0 then begin writeln('x2 должно быть больше x1'); Readln; Halt end; While x<="" pre="">Здесь тип формального параметра "Y" задается в разделе описания типов внешней программы и совпадает с типом фактического параметра "Z", значения элементов которого возвращаются во внешнюю программу.


Оператор Halt прерывает выполнение всей программы, даже если он используется внутри процедуры. Применение оператора Exit внутри процедуры вызывает прерывание процедуры, но не внешней программы. Приведем пример процедуры вывода массива чисел в файл:Type M_30х30_r= array[1..30, 1..30] of real; { задается тип M_30х30_r }var x: M_30х30_r; i, j, n, m: byte;{------------------------------------------------------------------------}Procedure Wr_M(a: M_30х30_r; name_f: string; n, m: byte);Var i, j: byte; { a - массив NxM, n<=30, m<=30 } f: text; { name_f - имя файла }begin assign(f, name_f); rewrite(f); For i:= 1 to n do begin writeln(f); For j:= 1 to m do write(f, a[i,j]:6:2) end; close(f) end;{------------------------------------------------------------------------}Begin N:= 10; { создание симметричной матрицы } for i:= 1 to N do for j:= i to N do x[i, j]:= 0.5 + random(50); { заполнение верхней треугольной матрицы } for i:= 1 to N do for j:= i to N do x[j,i]:= x[i,j]; { заполнение нижней, симметричной части матрицы }End. Для правильного считывания данных, записанных в файл бесформатным выводом необходима запись пробела для разделения чисел.


Приведем пример функции для расчета высоты треугольника по заданным значениям его сторон. Program TR;Var a, b, c, ha, hb, hc: real;{----------------------------------------------------------------------------}Function H_TR(a, b, c: real): real; { a, b, c - Стороны треугольника }Var p, s: real;Begin If (a<0) or (b<0) or (c<0) Then begin Writeln('Стороны треугольника >0?'); readln; Halt end; If (a>(b+c)) or (b>(a+c)) or (c>(a+b)) Then begin Writeln('a<(b+c), b<(a+c), c<(a+b)?'); readln; Halt end; p:= (a+b+c)/2; { полупериметр } s:= Sqrt(p*(p-a)*(p-b)*(p-c)); { площадь } H_TR:= 2*s/a; { Присвоение функции значения }End;{----------------------------------------------------------------}Begin Writeln('Введите значения сторон треугольника a,b,c'); Readln(a,b,c); ha:= H_TR(a, b, c); hb:= H_TR(b, a, c); hc:= H_TR(c, b, a); Writeln('Высоты треугольника:'); Writeln('ha=',ha:-10:4, 'hb=',hb:-10:4, 'hc=',hc:-10:4); ReadlnEnd. В программе трижды вызывается функция расчета высоты треугольника для различных комбинаций фактических параметров, что позволяет вычислить все высоты треугольника.


Приведем пример использования функции для расчета суммы членов степенного ряда, представляющего тригонометрическую функцию Y= Sin(x).PROGRAM fun_sin;var y, y1, x1: real;{-------------------------------------------------------------------------}Function Sin_r(x: real): real; Var a, k, y: real; i: longint;begin if abs(x) > 2*Pi Then x:= 2*pi*Frac(x/(2*Pi)); {учет периодичности } if abs(x) > 2*Pi Then x:= x - 2*pi*Int(x/(2*Pi)); { функции } if abs(x) > Pi Then x:= Pi - ABS(x); { учет асимметрии функции } i:= 0; a:= x; y:= a; while abs(a)>0.0000001 do begin i:=i+1; k:=-x*x/(2*i*(2*i+1)); a:= a*k; y:= y + a end; Sin_r:= y; { присвоение функции ее значения }end;{-------------------------------------------------------------------------}Begin write('Введите значение аргумента: x1= '); Readln(x1); Y:= Sin_r(x1); { вызов функции, разработанной программистом } Y1:= Sin(x1); { вызов стандартной функции } writeln('значение аргумента: x1= ', x1); writeln('расчетное значение функции: Sin_r(x1)= ', y:-11:8); writeln('контрольный результат: Sin(x1) = ', y1:-11:8); writeln('Нажмите Enter'); readln;end. В описании функции обязателен оператор присвоения функции ее значения. Изменение величины параметра-значения "x" в теле функции не отражается на его значении во внешней программе. Функция возвращает значение, которое во внешней программе присваивается переменной "y".

Контрольные вопросы

1. Для чего нужны в программе процедуры и функции?2. 3. В чем отличие между процедурой и функцией?4. 5. Чем отличаются формальные и фактические параметры?6. 7. Чем отличаются параметры-значения и параметры-переменные?8. 9. Как объявляются глобальные и локальные переменные? Каково правило видимости этих переменных?10. 11.Почему при обращении к процедуре, аргумент, передаваемый параметру-переменной, может быть только переменной, а не константой или выражением?12.

Пример

Пример1. Найти сумму положительных элементов в массиве.


Этапы решения задачи: 1. Алгоритм решения довольно прост - в цикле будем "пробегать" массив, сравнивая его ячейки с 0 и суммировать, если они >0.2. 3. Составим блок-схему программы4.
Уточним из каких блоков состоит блок "Суммирование положительных ячеек"
Содержание этих блоков простое, поэтому не стоит их уточнять.5. Напишем программу на языке Паскаль6. program example; type Tarray = array[1..100] of integer; Var v: Tarray; N,i,s:integer; Procedure vvod_data(var m:Tarray;n:integer); Var i:integer; Begin Writeln('Введите ',n,' чисел через пробел'); For i:= 1 to n do read(m[i]); End; Function summ(m:TArray):integer; Var s:integer; Begin S:=0; For i:= 1 to n do if m[i]>0 then s:= s+m[i]; Summ:=s; End; begin write('Введите размерность массива N= '); readln(n); vvod_Data(v,n); s:= summ(v); writeln('Сумма= ',s); end.

Задания

1. Описать функции Min2(A,B) и Max2(A,B)2 вещественного типа, находящие минимальное и максимальное из двух вещественных чисел A и B. 2. Описать процедуру Minmax(A,B), записывающую в переменную A минимальное из значений A и B, а в переменную B - максимальное из этих значений. 3. Описать функцию Fact(N) целого типа, вычисляющую значение факториала N! = 1·2·...·N (N > 0 - параметр целого типа). С помощью этой фунции вычислить факториалы 10 данных чисел. 4. Описать процедуру SumDigit(N,S), находящую сумму цифр S целого числа N (N - входной, S - выходной параметр). Используя эту процедуру, найти суммы цифр пяти данных чисел. 5. Описать функцию Polynom(A,N,X) вещественного типа, находящую значение полинома P в вещественной точке X. Полином P задается параметрами N (степень полинома, 0 < N < 8) и A (коэффициенты полинома, вещественный массив размера N+1): P(X) = A[1]·XN + A[2]·XN-1 +... + A[N]·X + A[N+1]. Используя эту функцию, найти значения заданного полинома в пяти данных точках. 6. Описать функцию Min(A,N) и Max(A,N)2 вещественного типа, находящую минимальный и максимальный элемент массива A, состоящего из N вещественных чисел. 7. Описать функцию NMin(A,N) и NMax(A,N)2 целого типа, находящую номер минимального и максимального2 элемента массива A (массив состоит из N вещественных чисел). 8. Описать процедуру NMinmax(A,N,NMin,NMax), находящую номера минимального и максимального элемента массива A из N вещественных чисел. 9. Описать процедуру Invert(A,N), меняющую порядок следования элементов массива A из N вещественных чисел на противоположный ("инвертирование массива"). 10.Описать процедуру Smooth(A,N), заменяющую каждый элемент вещественного массива A размера N на его среднее арифметическое со своими соседями ("сглаживание массива"). С помощью этой процедуры выполнить пятикратное сглаживание данного массива A размера N, выводя на экран результаты каждого сглаживания. 11.Описать функцию SumLine(A,M,N,k) вещественного типа, вычисляющую сумму элементов вещественной матрицы A размера M x N, расположенных в k-й строке (если [k > M]1|[k > N]2, то функция возвращает 0). 12.Описать функцию SumCol(A,M,N,k)2 вещественного типа, вычисляющую сумму элементов вещественной матрицы A размера M x N, расположенных в k-й столбце (если [k > M]1|[k > N]2, то функция возвращает 0). 13.Описать функцию IsIdent(S) целого типа, проверяющую, является ли строка S допустимым идентификатором Паскаля. При утвердительном ответе возвращается 0. Если S является пустой строкой, то возвращается -1, если строка начинается с цифры, то возвращается -2. Если S содержит недопустимые символы, то возвращается номер первого недопустимого символа. Проверить с помощью этой функции пять данных строк. 14.Описать функцию FillStr(S,Len) строкового типа, возвращающую строку длины Len, заполненную повторяющимися копиями строки-шаблона S (последняя копия строки-шаблона может входить в результирующую строку частично). 15.Описать процедуру Trim(S), удаляющую в строке S начальные и конечные пробелы. 16.Описать функцию PosLast(subS,S) целого типа, возвращающую номер позиции, с которой в строке S содержится последнее вхождение подстроки subS. Если в строке S отсутствуют подстроки subS, то функция возвращает 0. 17.Даны действительные числа х1, у1, х2, у2, …,х10, у10. Найти периметр десятиугольника, вершины которого имеют соответственно координаты (х1, у1), (х2, у2), …, (х10, у10). (Определить процедуру вычисления расстояния между двумя точками, заданными своими координатами.)18. 19.Даны действительные числа a, b, c, d, e - стороны пятиугольника. Найти площадь пятиугольника. (Определить процедуру вычисления площади треугольника по его сторонам.)20. 21.Даны три символьные матрицы. 22.
a) ту матрицу, где есть хотя бы одна гласная - транспонировать;23.
b) в той матрице, на главной диагонали которой все цифры, найти наименьшую и удалить соответствующую строку. 24. 25.Написать программу вычисления P по формуле: где n - заданное натуральное число. 26. 27.Описать функцию Stepen (x,n) от вещественного x и целого n, вычисляющую (посредством умножения) величину xn, и использовать ee для вычисления b=2.7k+(a+1)-5.28. 29.Даны отрезки a,b,c и d. Для каждой тройки этих отрезков, из которых можно построить треугольник, напечатать площадь данного треугольника. Определить процедуру Plo(x,y,z), печатающую площадь треугольника со сторонами x,y и z, если такой треугольник существует. 30. 31.Пусть процедура Socr(a,b,p,q) от целых параметров (b№0)приводит дробь к несократимому виду Описать данную процедуру и использовать ее для приведения дроби к несократимому виду 32. 33.Даны длины a,b и c сторон некоторого треугольника. Найти медианы треугольника, сторонами которого являются медианы исходного треугольника. Длина медианы, проведенной к стороне a, равна 34. 35.Даны координаты вершин двух треугольников. Определить, какой из них имеет большую площадь. 36. 37.Даны координаты вершин треугольника и координаты некоторой точки внутри него. Найти расстояние от данной точки до ближайшей стороны треугольника. (При определении расстояний учесть, что площадь треугольника вычисляется и через три его стороны, и через основание и высоту.).38. 39.Три прямые на плоскости заданы уравнениями akx+bky=ck, k=1,2,3. Если эти прямые попарно пересекаются и образуют треугольник, тогда найти его площадь. 40. 41.Два натуральных числа называются "дружественными", если каждое из них равно сумме всех делителей другого, за исключением его самого (таковы, например, числа 220 и 284). Напечатать все пары "дружественных" чисел, не превосходящих заданного натурального числа. 42. 43.Дано четное число n > 2. Проверить для этого числа гипотезу Гольдбаха. Эта гипотеза (по сегодняшний день не опровергнутая и полностью не доказанная) заключается в том, что каждое четное n, большее двух, представляется в виде суммы двух простых чисел. Воспользоваться функцией распознавания простых чисел. 44. 45.Дано натуральное число n. Выяснить, является ли оно полным квадратом. Определить функцию, позволяющую распознавать полные квадраты.46. 47.Дан массив A[1..50], элементы которого отличны от нуля. Расположить их в таком порядке, чтобы первыми были все положительные элементы, а затем - все отрицательные, причем порядок следования как положительных, так и отрицательных элементов должен сохраниться (при решении задачи новый массив не заводить!).48. 49.Преобразовать массив S, "поворачивая" его вокруг центра на 90, 180, 270 градусов против часовой стрелки.50. 51.Рассматривая массивы X, Y и Z как представление некоторых множеств из объектов типа индекс (X[k]=TRUE, если элемент k принадлежит множеству X, и X[k]=FALSE иначе, и т.п.), реализовать следующую операцию над этими массивами-множествами: переменной t присвоить значение TRUE, если множество X является подмножеством множества Y, и значение FALSE иначе.52. 53.Элемент двухмерного массива называется локальным минимумом, если он строго меньше всех имеющихся у него соседей. Подсчитать количество локальных минимумов заданной матрицы размером NxN найти максимум среди всех локальных минимумов.54. 55.Составить функцию для нахождения точного значения суммы натуральных чисел, в десятичной записи которых более 20 знаков. Указание. Исходные данные и ответ представить в виде массивов цифр.56. 57.Даны две строки символов. Символ будем называть общим, если он встречается и в первой, и во второй строке. Пусть K1 - число вхождений в первую строку общего символа, а K2 - во вторую. Минимальное из чисел K1, K2 будем называть числом общности. Вывести все общие символы с указанием для них числа общности.58. Задачи повышенной сложности

1. Рассмотрим произвольное натуральное число и найдем сумму его цифр, затем сумму цифр полученного числа и так далее, пока не получим однозначное число. Назовем это число цифровым корнем. Требуется написать программу, которая для заданного N (N<10100) находит его цифровой корень.2. 3. Задано N натуральных чисел a1,a2,…,aN (1Ј N Ј 20), каждое из которых находится в интервале от 1 до 10000. Необходимо определить количество натуральных делителей произведения a1*a2*…*aN. 4. 5. Написать функцию поиска корней полинома степени n. Исходными параметрами будут числа a1, a2,…,an. Комплексные корни учитывать.6. 7. Требуется написать программу, которая выводит в порядке возрастания все правильные несократимые дроби, знаменатели которых не превосходят N (2<=N<=500).8. 9. На экране компьютера, работающего в операционной системе Windows, было открыто N (N <= 20) окон, положение каждого из которых однозначно определяется четверкой натуральных чисел - X1 Y1 X2 Y2 - координатами левого верхнего и правого нижнего угла окна. Очевидно, что окна, открытые позже, могут частично или полностью перекрывать открытые ранее. Окно считается видимым, если виден хотя бы один образующий его пиксел.10. </n<=>

 



Поделиться:


Последнее изменение этой страницы: 2016-08-06; просмотров: 944; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.17.28.48 (0.011 с.)