
- •Часть 2
- •Это связано с правилом соответствия типов: два структурированных элемента принадлежат одному типу (идентичному), если они принадлежат ранее описанному типу либо описаны одной командой.
- •Лабораторная работа №2. Использование подпрограмм при обработке массивов
- •Лабораторная работа №3. Программирование процессов обработки символьной и строковой информации
- •Список литературы
- •Приложение 1. Варианты заданий для самостоятельного решения Задачи на обработку одномерных массивов
- •Нахождение экстремумов в одномерных массивах
- •Задачи на обработку двумерных массивов
- •Задачи на формирование массивов
- •Вычисления с диагональными элементами в квадратных матрицах
- •Задачи на обработку двумерных массивов
- •Приложение2. Варианты заданий для самостоятельного решения
Лабораторная работа №2. Использование подпрограмм при обработке массивов
Цель работы: изучение особенностей алгоритмизации и программирования массивов данных с использованием подпрограмм.
Подпрограммы. Общие понятия
В практике программирования часто встречаются ситуации, когда одну и ту же группу операторов, выполняющих законченную последовательность действий, требуется повторить без изменений при различных исходных данных. В 1957 г. Маврис Уилкс предложил идею подпрограммы. Суть идеи в том, чтобы повторяющейся группе операторов дать имя, выделить ее из текста основной программы и обращаться к ней по мере необходимости.
Подпрограмма – это автономная часть программы, которая реализует определенный алгоритм и допускает обращение к ней из различных частей основной программы. Подпрограммы оформляются в виде замкнутых участков программы, которые имеют четко обозначенный вход и выход. Использование подпрограммы позволяет реализовать один из прогрессивных методов программирования – структурное программирование. Идея подпрограммы реализована во всех современных языках программирования. Использование подпрограмм позволяет:
сократить сроки разработки программы (распараллелить работу нескольких программистов);
повысить качество и надежность программы (отладить отдельные фрагменты, а затем всю программу целиком);
упростить модификацию программы (изменение одной подпрограммы не влияет на другие);
значительно сэкономить память ЭВМ, т.к. многократно использованные фрагменты хранятся только один раз;
накапливать подпрограммы, создавая библиотеки (модули). В идеале основная программа должна содержать только обращение к подпрограмме.
Подпрограммы языка Паскаль можно разделить на следующие группы:
внутренние (стандартные). Они являются частью языка и могут использоваться без предварительного описания. (По умолчанию они описаны в модуле System sin(x), cos(x), ln(x) и т.п.)
библиотечные. Известны системе программирования, собраны в библиотеках (модулях) и перед использованием требуют явного указания модуля (стандартного или пользовательского). Пример: ClrScr –- использует стандартную библиотеку Crt.
определенные пользователем. Создаются программистом. Должны быть описаны перед использованием.
В языке программирования Паскаль используются два вида подпрограмм: процедура (Procedure) и функция (Function).
Структура подпрограммы включает те же разделы, что и основная программа: заголовок (обязательный раздел), раздел описаний, раздел операторов (рис. 2.1). Описание подпрограмм осуществляется в разделе описаний (Procedure, Function) основной программы. Вызов подпрограмм организован в разделе операторов основной программы.
Program <имя программы>[{< список параметров>}];
$директива<…>; {раздел глобальных директив компилятора}
Uses <…>; {раздел используемых модулей}
Label <…>; {раздел описания меток}
Type <…>; {раздел определения типов}
Const <…>; {раздел определения констант}
Var <…>; {раздел описания переменных}
Procedure, Function < P1>; {раздел процедур и функций}
<раздел описаний>
Begin
<раздел операторов подпрограммы>;
End;
Begin
<оператор 1>;
< оператор вызова подпрограммы P1>
<оператор n-1>;
<оператор n>
End.
Рис. 2.1. Пример структуры программы с подпрограммой
Выполнение программы начинается с операторов основной программы. При наличии оператора вызова подпрограммы управление передается подпрограмме, и начинают действовать ее операторы. После завершения подпрограммы управление передается основной программе – оператору, следующему за оператором вызова подпрограммы.
С точки зрения области действия переменных, выделяют локальные и глобальные.
Глобальная переменная – переменная, которая описана в основной программе, может использоваться как в основной программе, так и подпрограммах. Локальная переменная – переменная, которая определена и действует в этой подпрограмме и в пределах описанных в ней подпрограмм. Если глобальная и локальная переменные имеют одно имя, то это разные переменные. Обращение к таким переменным в теле подпрограммы трактуется как обращение к локальным переменным, т.е. глобальные переменные недоступны (локальные переменные «закрывают» глобальные).
Процедуры
Процедура представляет собой группу операторов, имеющую имя (заголовок процедуры), выполняющую определенную задачу и вызываемую для выполнения по имени из основной программы.
Структура процедуры:
Procedure<имя процедуры>[(<список формальных параметров>)];
<раздел описаний локальных переменных и подпрограмм>;
begin
<раздел операторов >;
end;
Для обращения к процедуре используется оператор вызова процедуры. Он состоит из имени процедуры и списка фактических параметров, заключенных в круглые скобки. Формат оператора вызова процедуры:
<имя процедуры>[<список фактических параметров>];
При вызове процедуры происходит передача значений фактических параметров формальным параметрам. Каждый формальный параметр указывается вместе со своим типом, а соответствующий ему фактический параметр – без типа. Между формальными и фактическими параметрами должно быть соответствие по количеству параметров, их типу и порядку следования. В качестве фактических параметров могут быть константы, переменные и выражения.Процедура может не иметь параметров, тогда и в операторе вызова процедуры они будут отсутствовать.
Среди формальных параметров процедуры выделяют:
параметры-значения (передача параметров по значению);
параметры-переменные (передача параметров по ссылке).
Параметры-значения выполняют роль входных параметров процедуры, они могут получать значения фактических параметров, но не могут возвращать свои значения вызывающей подпрограмме (программы).
Параметры – переменные выполняют роль как входных, так и выходных параметров процедуры. Они могут получать значения фактических параметров, изменять их и возвращать новые значения в «вызывающую» подпрограмму (программу) фактическим параметрам. Для выделения параметров переменных перед ними ставится служебное слово var.
Пример
1: даны
значения переменных: А=23.5, В=13.1, Z=10.2.
Оформить в виде процедуры следующие
вычисления: C=
;
Y=А+В+С;
Программа вычисления суммы примет следующий вид:
Program H;
Var Y1: real; {глобальная переменная}
Procedure SUM (A,B,Z:real; var Y:real); {формальные параметры}
Var C:real; {локальная переменная}
Begin
C:=SQR(Z); Y:= A+B+C;
End;
Begin
SUM(23.5, 13.1, 10.2, Y1); {фактические параметры}
Writeln ('Y1=', Y1:3:1);
End.
Формальные входные параметры А, В, Z принимают значения соответствующих им фактических параметров: А=23.5, В=13.1, Z=10.2. При этих значениях выполняется процедура SUM. Результатом выполнения процедуры является переменная Y, которая передает свои значения фактическому параметру Y1. Передача возможна, т.к. Y является параметром-переменной. Допускается одинаковое обозначение соответствующих формальных и фактических параметров. Например: SUM(23.5,13.1,10.2,Y);
Функции
Отличительные особенности функции:
она имеет только одно значение результата выполнения;
результат обозначается именем функции и передается в основную программу (подпрограмму верхнего уровня);
в заголовке функции указывается тип результата выполнения данной функции;
cреди операторов функции должен быть хотя бы один оператор присваивания, в левой части которого указано имя функции, а в правой – выражение, задающее результат выполнения функции.
Структура функции:
Function <имя функции>[(<список формальных параметров>)]:<тип результата>;
<раздел описаний локальных переменных и подпрограмм>;
begin
<раздел операторов >;
<имя функции>:= < результат выполнения функции>;
end;
В заголовке указывается служебное слово function, далее имя функции, в скобках формальные параметры с указанием типа каждого параметра. Среди формальных параметров только параметры значения. Затем тип результата функции.
Оператор вызова функции имеет вид:
< переменная>:=<имя функции> [<список фактических параметров>)] ;
При вызове функции передача ей фактических параметров (если они есть) производится по тем же принципам, что и при вызове процедуры.
В качестве примера рассмотрим решенную ранее задачу, но вычисления организуем через функцию.
Пример 2: даны значения переменных: А=23.5, В=13.1, Z=10.2. Оформить в виде функции следующие вычисления: C= ; Y=А+В+С;
Программа вычисления суммы примет следующий вид:
Program H1;
Var Y1: real; {глобальная переменная}
Function SUM (A,B,Z:real): real; {формальные параметры}
Var C,Y:real; {локальная переменная}
Begin
C:=SQR(Z);
Y:=A+B+C;
SUM:=Y;
End;
Begin
Y1:=SUM(23.5, 13.1, 10.2); {фактические параметры}
Writeln ('Y1=', Y1:3:1);
End.
Использование подпрограмм при обработке массивов данных
Часто возникает ситуация, когда в процедуру в качестве параметра нужно передать не одно значение, а массив. Тогда в качестве фактического параметра выступает имя массива. Если массив изменятся внутри подпрограммы, то в качестве формального параметра используется параметр-переменная (var) с указанием типа массива. Само описание массива делается в основной программе в разделе type. Например, описание массива А в основной программе имеет вид:
Const N=10;
Type Mas = array [1..N] of real;
Var A: Mas;
Тогда формальные параметры процедуры X будут представлены следующим образом: Procedure PRIM (M: integer; var X:mass);
а вызов процедуры PRIM (N, A);
Формальный параметр M принимает значение фактического параметра N, а параметр-переменная X принимает значение массива А. В процедуре значения массива Х могут измениться, и массив А получит новые значения.
Алгоритмы и программы обработки массивов с использованием процедур и функций.
Задача 2.1. Даны матрицы B: i=1,nb , j=1,mb и С: i:=1,nc , j:=1,mc, где nb, mb, nc, mc<=10(nb – количество строк матрицы В; mb – количество столбцов матрицы В; nc, mc – аналогичные величины в матрице С). Найти минимальные элементы второго столбца исходных матриц. Ввод-вывод матриц, нахождение минимальных элементов организовать через подпрограммы.
В задаче ввод и вывод исходных массивов целесообразно организовать через процедуру, а для вычисления минимального элемента можно использовать как процедуру, так и функцию. Рассмотрим оба варианта.
Первый вариант решения задачи 2.1
В данном варианте для организации ввода-вывода массива и нахождения минимального элемента используются процедуры. Блок-схемы алгоритмов процедур и основной программы представлены на рис. 2.2 – 2.5. В процедуре ввода Inp формальными параметрами являются: параметры-значения n и m (количество строк и столбцов в массиве) и параметр-переменная, задающая имя массива А. Ввод переменных n и m организован в основной программе. Результатом вызова процедуры Inp(nb,mb,B) с параметрами является формирование массива В, а процедуры Inp( nс,mс,С) формирование массива С. Это возможно за счет передачи параметров по ссылке.
Процедура Out выводит на экран элементы обрабатываемого массива. В ней не происходит изменений локальных переменных, поэтому все формальные параметры являются параметрами-значениями (var не ставится).
|
|
Рис. 2.2. Блок-схема процедуры Inр Рис. 2.3. Блок-схема процедуры Out
Рис. 2.4. Блок-схема основной программы
Рис. 2.5. Блок-схема процедуры Minimum |
program p1; Uses Crt; Type mass=array[1..10,1..10]of integer; Var B,C:mass; i,j,nb,nc,mb,mc:integer; minb,minc:integer; Procedure Inp(n,m:integer;var A:mass); begin for i:=1 to n do for j:=1 to m do A[i,j]:=random(50); end; Procedure Out( n,m:integer; A:mass); begin for i:=1 to n do begin for j:=1 to m do write('A[',i,',',j,']=',A[i,j]:3,' '); writeln; end; end; Procedure Minimum(n:integer; A:mass; var min:integer); begin min:=A[1,2]; for i:=1 to n do if A[i,2]<min then min:=A[i,2]; end; begin Clrscr; randomize; writeln('введите nb,mb'); readln(nb,mb); Inp( nb,mb,B); writeln('введите nc,mc'); readln(nc,mc); Inp( nc,mc,C); writeln('массив B'); Out( nb,mb,B); writeln('массив C'); Out( nc,mc,C); Minimum(nb,B,minB); Minimum(nc,C,minC); writeln('minB=',minB:3); writeln('minC=',minC:3); readln end. В процедуре Minimum входными параметрами являются: n (количество строк в массиве) и переменная А, принимающая имя обрабатываемого массива( В или С). Значения этих параметров не меняются в процессе выполнения процедуры, и не требуется их передача в основную программу, поэтому они являются параметрами-значениями (var не ставится). Выходным параметром (результатом) является переменная min, ее значение передается в основную программу по ссылке, она является параметром-переменной (var ). Результаты выполнения программы:
введите nb,mb: 2 2 введите nc,mc: 2 3 массив B: A[1,1]= 12 A[1,2]= 31 A[2,1]= 14 A[2,2]= 32 массив C: A[1,1]= 24 A[1,2]= 44 A[1,3]= 20 A[2,1]= 0 A[2,2]= 25 A[2,3]= 30 minB= 31 minC= 25
|
Второй вариант решения задачи 2.1
В данном варианте для организации ввода-вывода массива используются процедуры, а для нахождения минимального элемента – функция. Блок-схемы алгоритмов процедур и основной программы представлены на рис. 2.3, 2.6 – 2.8.
В процедуре Inp ввод размерности массива n и m производится в самой процедуре, все ее формальные параметры являются параметрами-значениями, т. к. они передаются в основную программу. В процедуре Out изменений нет, она рассматривалась ранее.
В функции Minimum все формальные параметры являются параметрами-значениями: n (количество строк в массиве) и сам массив А. Результат выполнения функции – переменная min передается в основную программу через присвоение ее значения имени функции, поэтому функция может иметь только один результат.
На языке Паскаль программа будет иметь следующий вид:
Рис. 2.6. Блок-схема процедуры Inp
Рис. 2.7. Блок-схема основной программы |
Program f6; Uses Crt; Type mass=array[1..10,1..10] of integer; var b,c:mass; i,j,mc,mb,nc,nb: integer; minc,minb: integer; Procedure Inp(var n,m:integer; var A:mass); begin read(n,m); for i:=1 to n do for j:=1 to m do A[i,j]:=random(50); end; Procedure Out( n,m:integer; A:mass); begin for i:=1 to n do begin for j:=1 to m do write('A[',i,',',j,']=',A[i,j]:3,' '); writeln; end; end; Function Minimum(n:integer;a:mass):integer; var min:integer; begin min:=a[1,2]; for i:=1 to n do if a[i,2]<min then min:=a[i,2]; minimum:=min; end; begin Clrscr; randomize; writeln('ввод nb,mb'); Inp( nb,mb,B); writeln('ввод nc,mc'); Inp( nc,mc,C); writeln('вывод B'); Out( nb,mb,B); writeln('вывод C'); Out( nc,mc,C); minb:=Minimum(nb,b); minc:=Minimum(nc,c); writeln('minb=',minb:3); writeln('minc=',minc:3); end.
Р ввод nb,mb 2 2 ввод nc,mc 2 2 вывод B A[1,1]= 35 A[1,2]= 42 A[2,1]= 9 A[2,2]= 8 вывод C A[1,1]= 44 A[1,2]= 3 A[2,1]= 9 A[2,2]= 16 minb= 8 minc= 3
|
Рис. 2.8. Блок-схема алгоритма функции Minimum
Задача 2.2: Даны два двумерных массива: Bij, где i:=1nb, j:=1 nb; Cij, i:=1nc, j:=1 nc; nb, nc – целые числа, не больше 10. Сформировать массивы B1 и C1 из положительных элементов исходных.
В процессе решения задачи целесообразно организовать следующие процедуры:
процедуру ввода двумерного массива для организации ввода массивов В и С (Procedure Vvod);
процедуру формирования одномерного массива из двумерного (Procedure Form);
процедуру вывода одномерного массива для вывода массивов В1 и С1 (Procedure Out).
Блок-схемы алгоритмов процедур и основной программы представлены на рис. 2.2, 2.9 – 2.11.
Рис. 2.9. Блок-схема процедуры Form
Рис. 2.10. Блок-схема процедуры Out
Рис. 2.11. Блок-схема основной программы |
program p3; uses Crt; type mass=array[1..10,1..10]of real; mass1=array[1..100] of real; var B,C:mass; B1,C1:mass1; nb,nc,mb,mc:integer; Procedure Vvod(var n:integer;var D:mass; name:string); var i,j:integer; begin write(' введите количество строк и столбцов массива', name,' n='); readln(n); writeln('введите массив ',name); for i:=1 to n do for j:=1 to n do read(D[i,j]); end; Procedure Form(D:mass;n:integer; var D1:mass1;var m:integer); var i,j:integer; begin m:=0; for i:=1 to n do for j:=1 to n do if D[i,j]>0 then begin m:=m+1; D1[m]:=D[i,j]; end; end; Procedure Out(m:integer; var D1:mass1;nameD1:string); var i:integer; begin writeln('вывод ', nameD1); for i:=1 to m do write(D1[i]:5:2,' '); writeln ; end; begin ClrScr; Vvod(nb,B,'B'); Vvod(nc,C,'C');
Form(B,nb,B1,mb); Form(C,nc,C1,mc); Out (mb,B1,'B1'); Out (mc,C1,'C1'); end.
Результаты выполнения программы:
введите количество строк и столбцов массива B: n=2 введите массив B 5 6 -7 4 введите количество строк и столбцов масива С: n=2 введите C 4 -7 -6 12 вывод B1 5.00 6.00 4.00 вывод C1 4.00 12.00
|
Примечание: В данной задаче формирование одномерного массива из двумерного можно организовать только через процедуру, т. К. результатом является не одно значение, а целый массив. В процедуре form входными параметрами являются: n (количество строк в массиве) и переменная D, принимающая значения обрабатываемого массива. Выходными параметрами (результатом процедуры) являются переменная m (размерность полученного одномерного массива) и сам одномерный массив D1, они являются параметрами- переменными (var).