Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Часть2. Структурное программирование.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
2.4 Mб
Скачать

Лабораторная работа №2. Использование подпрограмм при обработке массивов

Цель работы: изучение особенностей алгоритмизации и программирования массивов данных с использованием подпрограмм.

Подпрограммы. Общие понятия

В практике программирования часто встречаются ситуации, когда одну и ту же группу операторов, выполняющих законченную последовательность действий, требуется повторить без изменений при различных исходных данных. В 1957 г. Маврис Уилкс предложил идею подпрограммы. Суть идеи в том, чтобы повторяющейся группе операторов дать имя, выделить ее из текста основной программы и обращаться к ней по мере необходимости.

Подпрограмма – это автономная часть программы, которая реализует определенный алгоритм и допускает обращение к ней из различных частей основной программы. Подпрограммы оформляются в виде замкнутых участков программы, которые имеют четко обозначенный вход и выход. Использование подпрограммы позволяет реализовать один из прогрессивных методов программирования – структурное программирование. Идея подпрограммы реализована во всех современных языках программирования. Использование подпрограмм позволяет:

  1. сократить сроки разработки программы (распараллелить работу нескольких программистов);

  2. повысить качество и надежность программы (отладить отдельные фрагменты, а затем всю программу целиком);

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

  4. значительно сэкономить память ЭВМ, т.к. многократно использованные фрагменты хранятся только один раз;

  5. накапливать подпрограммы, создавая библиотеки (модули). В идеале основная программа должна содержать только обращение к подпрограмме.

Подпрограммы языка Паскаль можно разделить на следующие группы:

  1. внутренние (стандартные). Они являются частью языка и могут использоваться без предварительного описания. (По умолчанию они описаны в модуле System sin(x), cos(x), ln(x) и т.п.)

  2. библиотечные. Известны системе программирования, собраны в библиотеках (модулях) и перед использованием требуют явного указания модуля (стандартного или пользовательского). Пример: ClrScr- использует стандартную библиотеку Crt.

  3. определенные пользователем. Создаются программистом. Должны быть описаны перед использованием.

В языке программирования Паскаль используются два вида подпрограмм: процедура (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:=1nb, j:=1 nb; Cij, i:=1nc, j:=1 nc; nb, nc – целые числа, не больше 10. Сформировать массивы B1 и C1 из положительных элементов исходных.

В процессе решения задачи целесообразно организовать следующие процедуры:

  1. процедуру ввода двумерного массива для организации ввода массивов В и С (Procedure Vvod);

  2. процедуру формирования одномерного массива из двумерного (Procedure Form);

  3. процедуру вывода одномерного массива для вывода массивов В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).