Справочник от Автор24
Поделись лекцией за скидку на Автор24

Подпрограммы в Pascal

  • 👀 231 просмотр
  • 📌 169 загрузок
Выбери формат для чтения
Загружаем конспект в формате docx
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
Конспект лекции по дисциплине «Подпрограммы в Pascal» docx
Подпрограммы Подпрограмма (англ. subroutine) — поименованная или иным образом идентифицированная часть компьютерной программы, содержащая описание определённого набора действий. Подпрограмма может быть многократно вызвана из разных частей программы. В языках программирования для оформления и использования подпрограмм существуют специальные синтаксические средства. В Pascal существует два типа подпрограмм: процедуры (подпрограммы, в которых может изменяться несколько значений или ни одного значения) и функции (подпрограммы, которые возвращают только одно значение – саму себя). Рассмотрим пример, чтобы понять, когда выгодно использовать подпрограммы. Пример: В том из двух векторов, в котором среднее геометрическое положительных элементов наибольшее, найти куб суммы ненулевых элементов данного вектора. Класс Имя Тип Структура Смысл Вход A вещ вектор (одномерный массив) первый вектор Вход B вещ вектор (одномерный массив) второй вектор Вход na цел простая переменная размер вектора A Вход nb цел простая переменная размер вектора B Промежут finA лит текстовый файл файл с вектором А Промежут finB лит текстовый файл файл с вектором В Промежут fout лит текстовый файл файл с результатом Промежут Sga вещ простая переменная среднее геометрическое положительных элементов вектора А Промежут Sgb вещ простая переменная среднее геометрическое положительных элементов вектора B Выход Suma вещ простая переменная сумма ненулевых элементов вектора А и ее куб Выход Sumb вещ простая переменная сумма ненулевых элементов вектора А и ее куб Промежут i цел простая переменная бегунок Задание по имеющемуся коду самим начертить блок-схему. Код type vector = array [1..100] of real; var A, B: vector; na, nb, i: integer; sga, sgb: real; sumA, sumB: real; ka, kb: real; finA, finB, fout: text; begin assign (finA, 'A.txt'); assign (finB, 'B.txt'); assign (fout, 'res.txt'); reset (finA); reset (finB); rewrite (fout); write ('Введите размер первого вектора '); readln (na); write ('Введите размер второго вектора '); readln (nb); for i:=1 to na do read (finA, A[i]); for i:=1 to nb do read (finB, B[i]); writeln (fout, 'Исходный первый вектор'); for i:=1 to na do write (fout, A[i], ' '); writeln (fout); writeln (fout, 'Исходный второй вектор'); for i:=1 to nb do write (fout, B[i], ' '); writeln (fout); sga:=1; ka:=0; for i:=1 to na do if A[i]>0 then begin sga:=sga*A[i]; ka:=ka+1; end; sga:=exp(ln(sga)*(1/ka)); sgb:=1; kb:=0; for i:=1 to nb do if B[i]>0 then begin sgb:=sgb*B[i]; kb:=kb+1; end; sgb:=exp(ln(sgb)*(1/kb)); writeln (fout, 'Средние геометрические первого вектора = ', sga); writeln (fout, 'Средние геометрические второго вектора = ', sgb); if sgb=sga then writeln (fout, 'Средние геометрические первого и второго векторов равны между собой') else if sga>sgb then begin writeln (fout, 'Средние геометрические первого вектора больше'); sumA:=0; for i:=1 to na do if A[i]<>0 then sumA:=sumA+A[i]; sumA:= sumA*sumA*sumA; writeln (fout, 'Куб ненулевых элементо первого вектора равен ', sumA); end else begin writeln (fout, 'Средние геометрические второго вектора больше'); sumB:=0; for i:=1 to nb do if B[i]<>0 then sumB:=sumB+B[i]; sumB:= sumB*sumB*sumB; writeln (fout, 'Куб ненулевых элементо второго вектора равен ', sumB); end; close(finA); close(finB); close(fout); end. Как видно из примера, код и блок-схема такой программы достаточно объемные, читать их не слишком удобно. Для того, чтобы повысить читабельность и сделать такой код более удобным и коротким, а так же ускорить обработку и уменьшить объем используемой памяти, используют подпрограммы. В нашем случае понадобится четыре подпрограммы: для ввода (Vvod), для вывод (Vivod), для поиска среднего геометрического (SG) и поиска куба суммы неотрицательных (KubSum). По общей договоренности, имена подпрограмм должны бить говорящими, то есть такими, чтобы пользователь, взглянув на заголовок, понял, что делает данная подпрограмма. В русскоязычном сегменте договорились использовать транслит, сокращая слова по три-четыре буквы. В некоторых языках использует написание наименований действий без пробела (к примеру, SumOfElements). Функция описывается в следующем виде: Function <имя функции> (<формальных список параметров>): <тип>; Var <список локальных параметров>; Begin <тело подпрограммы> <имя функции>:=<результат работы функции>; End; Процедура описывается следующим образом: Procedure <имя процедуры> (<формальных список параметров>); Var <список локальных параметров>; Begin <тело подпрограммы> End; Формальные параметры соотвествуют фактическим по порядку и по типу. Передаваться параметры могут по ссылке или по значению. В случае передачи по ссылке используется ключевое слово var, в случае передачи по значению никаких дополнительных ключей перед переменной не ставится. Рассмотрим на примере. Сначала просто приведен текст подпрограммы, а затем даны более подробные комментарии. procedure Vvod (var x:vector; nx: integer; var fx: text); var i: integer; begin for i:=1 to nx do read (fx, x[i]); end; procedure {ключевое слово, обозначающее процедуру} Vvod { имя процедуры для ввода вектора} var x:vector {некий вектор, который будет заполняться информацией в процессе выполнения подпрограммы} nx: integer {переменная, обозначающая размер вектора, изменяться в процессе программы не будет} var fx: text {некий текстовый файл, но даже чтение файла - это его изменение} var i: integer; {дополнительная переменная-бегунок, для хождения по массиву} begin {начало тела подпрограммы} for i:=1 to nx do {цикл для прохода по всем nx элементам вектора х} read (fx, x[i]); {поэлемнтно читаем элементы вектора х из файла fx} end; {конец тела подпрограммы, подпрограмма завершена} Вызов функции осуществляется следующим образом: <переменная>:=<имя функции>(<список фактических параметров>); Возможен следующий вызов функции, то есть результат функции не обязательно хранить, его можно сразу выводить или использовать как условие для анализа или для арифметических или логических действий: Writeln (<имя функции>(<список фактических параметров>)); Вызов процедуры осуществляется следующим образом: <имя процедуры>(<список фактических параметров>); Результат будет записан в те переменные, которые были для этого предназначены в списке формальных параметров. Рассмотрим пример вызова подпрограммы и то, как она работает. Заголовок нашей подпрограммы ввода был следующим: procedure Vvod (var x:vector; nx: integer; var fx: text); При вызове же мы видим следующие две строки: Vvod (A, na, finA); Vvod (B, nb, finB); В первом случае на место некоторого массива х в процессе выполнения программы подставляется массив А, при выполнении подпрограммы массив А и будет изменяться, то есть заполняться информацией. На место неизменяющейся переменной nx, обозначающей размер, подставляется na, то есть фактический размер массива А, а на место некоторого файла, открытого на чтение, fx подставляется finA. Аналогичным образом происходит подстановка и во втром вызове, только для массива В. Таким образом, формальные параметры, это некоторые «формочки» или «образцы», над которыми совершаются действия, а фактические – это реальные данные, обрабатываемые по алгоритму, заданному в подпрограмме. Теперь о блок-схеме и спецификации. Для каждой подпрограммы делается отдельная таблица данных и блок-схема. В первом блоке, вместо привычного «начало» пишутся входные данные, тело подпрограммы раскрывается точно так же, а в последнем блоке, вместо «конец» указываются передаваемые выходные данные. Блок-схема и таблица данных для этой подпрограммы выглядит следующим образом: Класс Имя Тип Структура Смысл Выход x вещ одномерный массив Вектор, который мы заполняем данными в этой подпрограмме Вход nx цел простая переменная Количество элементов вектора Вход fx лит текстовый файл Файл, из которого мы читаем данные Промежу-точный i цел простая переменная Бегунок для перебора элементов вектора Если же говорить о том, насколько использование подпрограмм полезно, то посмотрите, насколько сократился код, который был написан для решения задачи в начале лекции. type vector = array [1..100] of real; procedure Vvod (var x:vector; nx: integer; var fx: text); var i: integer; begin for i:=1 to nx do read (fx, x[i]); end; procedure Vivod (x:vector; nx: integer; var fx: text); var i: integer; begin for i:=1 to nx do write (fx, x[i], ' '); writeln (fx); end; function SG (x:vector; nx:integer):real; var i, k: integer; s: real; begin s:=1; k:=0; for i:=1 to nx do if x[i]>0 then begin s:=s*x[i]; k:=k+1; end; SG:=exp(ln(s)*(1/k)); end; function KubSum (x:vector; nx:integer):real; var i: integer; s: real; begin s:=0; for i:=1 to nx do if x[i]<>0 then begin s:=s+x[i]; end; KubSum:=s*s*s; end; var A, B: vector; na, nb, i: integer; sga, sgb: real; sumA, sumB: real; ka, kb: real; finA, finB, fout: text; begin assign (finA, 'A.txt'); assign (finB, 'B.txt'); assign (fout, 'res.txt'); reset (finA); reset (finB); rewrite (fout); write ('Введите размер первого вектора '); readln (na); write ('Введите размер второго вектора '); readln (nb); Vvod (A, na, finA); Vvod (B, nb, finB); writeln (fout, 'Исходный первый вектор'); Vivod (A, na, fout); writeln (fout, 'Исходный второй вектор'); Vivod (B, nb, fout); sga:=SG(A,na); sgb:=SG(B,nb); writeln (fout, 'Средние геометрические первого вектора = ', sga); writeln (fout, 'Средние геометрические второго вектора = ', sgb); if sgb=sga then writeln (fout, 'Средние геометрические первого и второго векторов равны между собой') else if sga>sgb then begin writeln (fout, 'Средние геометрические первого вектора больше'); SumA:=KubSum(A, na); writeln (fout, 'Куб ненулевых элементо первого вектора равен ', sumA); end else begin writeln (fout, 'Средние геометрические второго вектора больше'); SumB:=KubSum(B, nb); writeln (fout, 'Куб ненулевых элементо второго вектора равен ', sumB); end; close(finA); close(finB); close(fout); end. Так же обращаю Ваше внимание, что в таблице данных для главного кода надо указывать только те переменные, что используются в главном коде, к примеру, в нашем случае бегунок i не используется в основной программе, так что его указывать в составе данных для решения задач с помощью подпрограмм не нужно. Блок-схема же тоже изменится. Все алгоритмы решения переносятся в подпрограммы и для них отдельными блок-схемами указывается алгоритм, в главном же коде указывается как и в какой последовательности будут вызываться подпрограммы, а так же некоторые дополнительные действия. Вызов подпрограммы обозначается через прямоугольник с двумя полосами по бокам. В верхнем левом углу пишут входные фактические данные для подпрограммы, в нижнем правом – выходные данные. В середине пишут ил имя подпрограммы, или, если на момент проектирования имени подпрограммы еще не существует, то те действия, что подпрограмма будет совершать. Блок-схема для нашего коды будет выглядеть так: Задание: сделать таблицы и построить блок-схемы к остальным подпрограммам. Матрицы Матрица – это двумерные массивы. Матрицы бывают прямоугольными (nxm) и квадратными (nxn), в наших задачах мы рассмотрим и первые и вторые. Необходимо для работы с матрицей создать тип матрицы. Мы продолжаем работать со статическими массивами. type mas=array[1..100,1..100] of real; var a:mas; Для заполнения матрицы информацией нужно использовать кратный цикл (внешний цикл пойдет по строкам, а внутренний по столбцам), for i:=1 to n do begin for j:=1 to m do read(fa, a[i,j]); readln(fa); end Обращение к элементу матрицы A[i,j], где А – имя матрицы, i – номер строки, j – номер столбца. Особые области для квадратной матрицы и поиск сумм всех элементов в этих областях. Главная диагональ Побочная диагональ for i:=1 to n do s:=s+a[i,i] for i:=1 to n do s:=s + x[i][n-i] Над главной диагональю Над побочной диагональю for i:=1 to n-1 do for j:=i+1 to n do s:=s+a[i,j]; for i:=1 to n-1 do for j:=1 to n-i-1 do s:=s+a[i,j]; Под главной диагональю Под побочной диагональю for i:=2 to n do for j:=1 to i-1 do s:=s+a[i,j]; for i:=2 to n do for j:=n-i+1 to n do s:=s+a[i,j]; Особые области матрицы и поиск сумм всех элементов в этих областях. Левая половина Левая половина for i:=1 to n do for j:=1 to n div 2 do s:=s+a[i,j]; for i:=1 to n do for j:=n div 2 +1 to n do s:=s+a[i,j]; Верхняя половина Нижняя половина for i:=1 to n div 2 do for j:= 1 to n do s:=s+a[i,j]; for i:= n div 2 +1 to n do for j:= 1 to n do s:=s+a[i,j]; Задача: Транспонировать матрицу. Транспонирование матрицы это: Код данной программы выглядит так: type mas=array[1..100,1..100] of real; procedure Vvod (var x:mas; nx: integer; var fx: text); var i, j: integer; begin for i:=1 to nx do begin for j:=1 to nx do read (fx, x[i, j]); readln (fx); end; end; procedure Vivod (x:mas; nx: integer; var fx: text); var i, j: integer; begin for i:=1 to nx do begin for j:=1 to nx do write (fx, x[i,j]:5:2, ' '); writeln (fx); end; end; procedure Transpon (var x:mas; nx: integer); var i, j: integer; buf: real; begin for i:=1 to nx do for j:=1 to i-1 do Begin buf:=x[i,j]; x[i,j]:=x[j,i]; x[j,i]:=buf; end; end; var a: mas; n: integer; fin, fout: text; begin assign (fin, '1.txt'); assign (fout, 'out.txt'); reset (fin); rewrite(fout); write (fout, 'Исходная матрица'); readln (n); Vvod (a, n, fin); writeln(fout, ''); Vivod(a,n,fout); Transpon(a,n); writeln(fout, 'Матрица после транспонирования'); Vivod(a,n, fout); close(fin); close(fout); end. Попробуйте сами составить спецификацию и блок-схемы данной программы.
«Подпрограммы в Pascal» 👇
Готовые курсовые работы и рефераты
Купить от 250 ₽
Решение задач от ИИ за 2 минуты
Решить задачу
Помощь с рефератом от нейросети
Написать ИИ
Получи помощь с рефератом от ИИ-шки
ИИ ответит за 2 минуты

Тебе могут подойти лекции

Смотреть все 588 лекций
Все самое важное и интересное в Telegram

Все сервисы Справочника в твоем телефоне! Просто напиши Боту, что ты ищешь и он быстро найдет нужную статью, лекцию или пособие для тебя!

Перейти в Telegram Bot