Лабораторная работа n 7
Программирование процедур на Паскале
Задачи лабораторной работы
Вопросы, изучаемые в работе
- Изучение строения и использования процедур, механизма параметров процедур.
- Изучение строения и использования функций пользователя.
- Продолжение изучения основных алгоритмов сортировки.
- Освоение работы с файлами различных типов.
Задание (общее ко всем вариантам).
Написать программу работы с массивом с использованием процедур и функций распечатки и частичной обработки массива.
При написании подпрограмм не использовать глобальные переменные, кроме имен файлов. Все обмены данными между подпрограммами и вызывающей программой выполнять через параметры подпрограмм.
Исходные данные читать из существующего текстового или двоичного файла. Результаты расчета выводить в форматном виде в выходной текстовый файл.
Оформить отчет по лабораторной работе аналогично оформлению предыдущих работ.
Требования к программе и отчету по работе
· В таблице распределения памяти привести имена, используемые как в основной программе, так и в подпрограммах, в том числе и формальные параметры процедур и функций.
· Алгоритмы каждой подпрограммы и основной программы выполнить отдельно.
· Все значения, на которые по смыслу накладываются ограничения, должны при вводе проверяться.
· Все выводимые данные должны подписываться.
Содержание программы.
- Заголовок программы с комментарием;
- Описание типов массивов;
- Описание переменных основной программы;
- Описание процедур и функций;
- Ввод необходимых исходных данных с клавиатуры;
- Открытие входных и выводного файлов;
- Ввод необходимых исходных данных из файла;
- Вывод исходных данных, в том числе массива в выводной файл. При выводе массива использовать созданную процедуру;
- Обработка массива в соответствии с заданием с применением разработанной процедуры или функции;
- Вывод результатов обработки в выводной файл, возможно с применением процедуры;
- Закрытие всех файлов.
Пояснения к лабораторной работе
Общие пояснения к использованию процедур и функций.
Процедуры и функции пользователя являются двумя видами подпрограмм, которые необходимо описать в разделе описаний основной программы (или предварительно поместить в личную библиотеку) и вызывать по имени в нужных местах вызывающей программы.
И процедура, и функция состоят из заголовка, раздела описаний и выполняемого блока. Их описания должны находиться после других операторов описаний основной (вызывающей) программы, перед ее выполняемым блоком. В отличие от основной программы, заголовки процедуры и функции обязательны, и имеют вид:
PROCEDURE <имя процедуры>(<список параметров>); – для процедуры и
FUNCTION <имя функции>(<список аргументов>):<тип результата>; – для функции.
Список аргументов это, по существу, список входных параметров.
Раздел описаний процедуры или функции строится как раздел описаний основной программы, с учетом того, что все описанные переменные существуют только во время выполнения процедуры (функции) в виде локальных переменных и никак не связаны с переменными вызывающей программы.
Следует иметь в виду, что если во внешней программе переменная описана, а в процедуре – нет, ее использование в теле процедуры означает работу с переменной внешней программы (так называемые глобальные переменные).
Выполняемый блок (который должен быть заключен в скобки Begin .. End) заканчивается символом ";", а не точкой. В функции, в отличие от процедуры, в выполняемом блоке имени функции обязательно должно быть присвоено значение, которое и будет являться ее значением. Такое присваивание может встречаться несколько раз, конечным значением будет результат последнего присваивания. Внутри выражений тела функции ее имя встречаться не должно, если это не специальная рекурсивная функция.
Обращение (вызов) процедуры выполняется написанием имени процедуры в форме отдельного оператора. Обращение к функции выполняется только внутри выражения, входящего в состав оператора, аналогично обращению к стандартным (встроенным) функциям Турбо-Паскаля.
Механизм параметров
В список параметров включаются исходные данные для работы процедуры/функции (входные параметры) и, если надо, указания, куда поместить результаты работы процедуры (выходные параметры).
Существует два способа передачи данных через список параметров из вызывающей программы в процедуру. Первый способ заключается в том, что процедуре передается некоторое данное в виде его значения, например, если данное числового типа, передается само число. Второй способ заключается в том, что передается не значение данного, а адрес ячейки, где это данное находится (говорят, что передается имя переменной). Таким образом, параметры могут передаваться по значению и по имени. В каких случаях какой способ следует использовать? Обычно входные параметры передаются в процедуру по значению, а выходные – всегда по имени.
Есть некоторые особенности при передаче массивов (и других составных данных большого размера) в качестве фактических параметров. Даже если массив представляет собой входные данные и не меняется в процессе выполнения процедуры, его обычно передают по имени, так как это требует передачи только адреса начала массива, а не копии всего массива, как это потребовалось бы при передаче массива по значению. Кроме того, массив основной программы (фактический параметр) и массив в списке формальных параметров должны иметь один и тот же тип – т.е. должен использоваться один и тот же явный описатель.
Отметим, что когда параметры передаются по имени, они занимают в памяти по 4 байта. Подробнее об этом смотри лабораторную работу № 9.
Примеры написания списков формальных и фактических параметров:
..(A,B,C:real;VAR X1,X2:real;VAR N:integer); – формальные,
..(0.762,Alfa,C[3]-1.2,X,Y,Num); соответствующие фактические.
Для передачи массива в процедуру:
TYPE
Vect = array[1..10] of real;
Mas5x8 = array[1..5,1..8] of integer;
. . .
VAR
C1,C2: Vect;
A: Mas5x8;
Metod: Integer;
. . .
PROCEDURE GetMatr(M:integer; Var X,Y:Vect;
Var Z:Mas5x8;...);
VAR A1,C1:integer;
. . .
Begin
<Операторы тела процедуры >
End;
FUNCTION MinValueMatr( Var Z:Mas5x8; M,N:integer)
:Integer;
VAR MinZ, I, j :integer;
Begin
<Операторы тела функции >
MinValueMatr:= MinZ;
End;
BEGIN
<Операторы основной программы >
. . .
GetMatr(0, C2, C1, A,...); {обращение к процедуре}
. . .
If MinValueMatr(A,5,7) div 2 < 3 then {обращение к функции}
. . .
END.
Разбор контрольного варианта
Задание
Таблица 24. Данные к заданию 31 варианта
№ вар. | Программа | Процедуры (Функции) | M<= | N<= | Файл с данными |
Прямоугольный массив заполнить числами из файла, начиная с 33 числа. С помощью функции в исходном массиве сделать элементы последнего столбца равными сумме всех четных элементов соответствующей строки. | 1)Исходный и полученный массивы печатать процедурой. 2)Построить функцию, которая возвращает сумму четных по значению элементов заказанной строки прямоугольного массива. | DATI.BIN |
Таблица идентификаторов
Составляется как для основной программы, так и для каждой подпрограммы пользователя.
Таблица 25. Идентификаторы программы 31 варианта
Имя | Тип | Р-р (байт) | Назначение |
Основная программа | |||
KorrMass | Имя программы | - | Обработка массива |
Massiv | Описатель типа | - | Описатель целочисл. массивов |
Stroka | Описатель типа | - | Описатель строки до 30 символов |
M | Целое | Количество строк массива | |
N | Целое | Количество столбцов массива | |
i | Целое | Номер текущей строки массива | |
j | Целое | Номер текущего столбца массива | |
Fin | Двоичный файл прямого доступа | Файл с исходн. целыми числами | |
Fout | Последовательный символьный файл | Файл с результатами работы | |
Ouest1 | Инициализирован-ная строка | Запрос числа строк массива | |
Ouest2 | Инициализирован-ная строка | Запрос числа столбцов массива | |
A | Целочисленный массив | Обрабатываемый массив | |
InpMN | Имя процедуры | - | Ввод размеров массива |
PrintMas | Имя процедуры | - | Вывод массива в файл протокола |
DATI.BIN | Строка – константа | Имя набора данных с числами | |
Umnik_7.res | Строка – константа | Имя набора данных с протоколом | |
Sum | Имя функции | - | Суммирование четных значений |
InpMN –-Процедура ввода размеров массива | |||
Txt | Строка | Формальный параметр – строка запроса | |
Kol | Адрес целочисленной переменной | Формальный параметр – имя переменной для результата ввода | |
MaxK | Целое | Формальный параметр – предельное возможное значение | |
PrintMas–- Процедура вывода массива в файл протокола (распечатки массива) | |||
Txt | Строка | Формальный параметр – текст заголовка | |
Mas | Адрес массива | Формальный параметр – имя выводимого массива | |
NStr | Целое | Формальный параметр – число строк массива | |
NKol | Целое | Формальный параметр – число столбцов массива | |
i | Целое | Номер строки | |
j | Целое | Номер столбца | |
Sum – Функция вычисления суммы четных элементов заданной строки массива | |||
Mas | Адрес массива | Формальный параметр – имя исходного массива | |
N | Целое | Формальный параметр – число столбцов массива | |
St | Целое | Формальный параметр – номер обрабатываемой строки | |
J | Целое | Номер элемента | |
S | Целое | Сумма | |
Odd | Стандартная логическая функция | - | Проверка нечетности аргумента |
Блок-схема алгоритма
Текст программы.
PROGRAM KorrMas;
{ Лабораторная работа N 7 Вариант N 31
Обработка массива
А.Я.Умненькая, ст. гр. Я-007 }
TYPE
Massiv = array[1..13,1..10] of integer;
Stroka = string[30];
CONST Quest1: Stroka='Задайте число строк массива';
Quest2: Stroka='Задайте число столбцов массива';
VAR A :Massiv;
M,N,I,j : integer;
Fin : file of integer;
Fout : file of text;
{ Процедура ввода размеров массива }
PROCEDURE InpMN(Txt:Stroka; MaxK:integer;
Var Kol:integer);
Begin
WriteLn; WriteLn(Txt);
Repeat
Readln(Kol);
If Kol>MaxKol then
Writeln('Можно не более ',MaxK,'задайте снова');
until Kol<=MaxK;
End;
{ Процедура вывода массива в файл протокола }
PROCEDURE PrintMas(Txt: string; Var Mas: Massiv;
NStr,NKol: integer);
VAR i,j : integer;
Begin
Writeln(Fout,Txt);
For i:= 1 to NStr do
begin
For j:= 1 to Nkol do Write(Fout,Mas[I,j]:7);
WriteLn(Fout);
end;
End;
{ Функция вычисления суммы четных элементов заданной строки массива }
FUNCTION Sum(Var Mas: Massiv; N,St: integer)
:integer;
VAR j,S : integer;
Begin
S:=0;
For j:=1 to N do
If not Odd(Mas[St,j]) then S:=S+Mas[St,j];
Sum:=S;
End;
BEGIN { Основная программа }
InpMn(Quest1,13,M);
InpMn(Quest2,10,N);
Assign(Fout,'Umnik7.res');
ReWrite(Fout);
WriteLn(Fout,'Сумма четных элем. в последний столбец');
Assign(Fin,'D:\LAB1\DATI.BIN');
ReSet(Fin);
Seek(Fin,32);
for i:=1 to M do
for j:=1 to N do Read(Fin,A[I,j]);
Close(Fin);
PrintMas (' Исходный массив', A,M,N);
for I:=1 to M do A[I,N]:=Sum(A,N,I);
PrintMas (' Обработанный массив', A,M,N);
Close(Fout);
END.
Содержимое набора данных UMNIK7.RES:
Сумма четных элем. в последний столбец
Исходный массив
9 8 0 -7 0 -5 7 -5 5
6 9 9 2 -2 -8 3 -8 -9
8 -4 -4 1 3 6 4 0 -5
4 1 -2 4 2 1 -2 -6 -5
-1 5 0 9 4 -3 -6 -691 885
-709 800 382 -396 -140 -841 923 368 -686
737 624 169 -610 458 -188 -423 126 355
Обработанный массив
9 8 0 -7 0 -5 7 -5 8
6 9 9 2 -2 -8 3 -8 -10
8 -4 -4 1 3 6 4 0 10
4 1 -2 4 2 1 -2 -6 0
-1 5 0 9 4 -3 -6 -691 -2
-709 800 382 -396 -140 -841 923 368 328
737 624 169 -610 458 -188 -423 126 410
Варианты заданий
Таблица 26. Варианты заданий лабораторной работы №7