
11.3. Примеры
Пример 1. В первом примере рассмотрим программу, в которой используется подпрограмма, обменивающаяся с вызывающей программой посредством параметров.
Задача:
Данные о служащих содержат фамилию и оклад.
Требуется занести данные с клавиатуры в массив записей и вывести фамилии служащих, имеющих оклад выше среднего.
Ограничение: число служащих не больше 10-ти.
Порядок ввода данных:
число служащих;
последовательность строк, содержащих фамилию и оклад служащих, разделенные пробелом.
Порядок вывода результата:
после строки "Результат: " – фамилии служащих, имеющих оклад выше среднего на отдельных строках.
Прежде всего, выберем структура данных в памяти программы. Пусть она имеет следующий вид :
Data |
Name |
Name |
... |
Name |
... |
Name |
|
|
Salary |
Salary |
|
Salary |
|
Salary |
|
Sum | |
[1] |
[2] |
|
[i] |
|
[N] |
|
|
Здесь
Data – массив записей, каждая из которых состоит из двух полей (Name, Salary) и содержит сведения об одном служащем;
Sum – переменная, в которой будет записана сумма окладов всех служащих.
Д
const
MaxSize
= 10;
{Максимальное
число служащих} type
TData
= record
{тип записи о служащем}
Name:
string[20];
{фамилия}
Salary:
real;{оклад;
стандартный тип Real выбран для
представления
чисел больше 32767; в Turbo
Pascal
может быть использован тип Longint}
end;
И
var
Data:
array[1..MaxSize]
of
TData; {массив записей
о
служащих} N:
Integer; {число служащих}
Sum:
Integer; {суммарный оклад}
MeanSalary:
Real; {средний оклад
Т
Алг
’Demo’ Начало
Ввод
массивов записей {в массив Data}
Вычисление
среднего оклада
{В переменной Mean}
Вывод
фамилий сотрудников Конец
Ввод сведений об одном служащем будем производить в отдельной подпрограмме, оформив ее как функцию с именем ReadData. Текст функции приведен на следующей странице.
Обратите внимание, что параметр Rec этой функции имеет атрибут var, показывая, что это возвращаемый (выходной) параметр и что информация передается в программу по ссылке (по адресу переменной в вызыващей программе). Результат работы функции – число, свидетельствующее об успешности ввода.
{
Функция ввода записи о служащем
} {
Формат строки ввода:
} {
<фамилия><пробел><оклад>
} {
Результаты функции - код ошибки при
вводе:
} {
при
успешном вводе результат = 0
} {
если строка пустая, результат = -1
} {
если оклад не задан или задан неверно,
результат = 1 } {
При отсутствии ошибки в переменной
Rec возвращаются
} {
сведения
о сотруднике.
} {
Примечание: для пользователя удобнее
при вводе
} {
отдельно
запрашивать имя и оклад } {
}
function
ReadData(var
Rec: TData): Integer; var S:
string[80];{
строка ввода } P:
integer;{ номер позиции в строке }
SalaryS:
string[10];{
строка, содержащая оклад }
ErrorCode:
integer;{код
ошибки при преобразовании
строки
в число} begin
readln(S); if
S = '' then
{Строка
пустая ?}
ReadData
:= -1
else
begin
P
:= Pos(' ',S);
if
P = 0 then {Пробела
нет ?}
ReadData
:= 1
else
begin
Rec.Name
:= Copy(S, 1, P-1);
SalaryS
:= Copy(S, P+1, 255{до конца строки});
Val(SalaryS,
Rec.Salary, ErrorCode);
if
ErrorCode <> 0 then
{Ошибка
?}
ReadData
:= 1
else
ReadData
:= 0; {end
if}
end;
{if}
end; end;
Т
program
Demo;
{Программа
заносит данные с клавиатуры в массив
записей} {и
выводит фамилии сотрудников, имеющих
оклад выше среднего}
<Здесь
вставить объявление константы
MaxSize, типа
TData и
текст функции
ReadData
(приведены
выше)>
Продолжение текста – на следующей странице.
var
Data:
array[1..MaxSize]
of
TData;
{массив
записей о служащих} N:
integer;
{число служащих}
ReadResult:
integer;
{результат ввода записи}
Sum:
real;
{суммарный оклад}
MeanSalary:
real;
{средний оклад} i:
integer;
{номер очередного элемента массива}
begin
writeln('Программа
заносит данные с клавиатуры в массив
',
'записей
и');
writeln('выводит
фамилии сотрудников, имеющих оклад
выше ',
'среднего.');
{Ввод
числа записей}
repeat
write('Задайте
число служащих (1..',MaxSize,') ');
readln(N);
if
(N <= 0) or (N
> MaxSize) then
writeln('Вы
ошиблись! Повторите!');
until
(N > 0) and
(N <= MaxSize);
{Ввод
массива записей}
writeln('Введите
фамилии служащих и через пробел их
оклад'); for
i := 1 to
N do
begin
repeat
ReadResult
:= ReadData(Data[i]);
if
ReadResult <> 0 then
writeln('Вы
ошиблись! Повторите!'); {end
if}
until
ReadResult = 0;
end;
{Вычисление
среднего оклада} Sum
:= 0; for
i
:= 1 to
N do
Sum
:= Sum + Data[i].Salary;
MeanSalary
:= Sum / N;
{Вывод
фамилий сотрудников}
writeln('Результат:'); for
i
:= 1 to
N do
if
Data[i].Salary
> MeanSalary then
writeln(Data[i].Name); {end
if} {end
for}
end.
Вызов подпрограммы функции в программе производится в операторе
ReadResult := ReadData(Data[i]);
Здесь Data[i] – фактический параметр функции ReadData. В него возвращается прочитанная запись о служащем.
Пример 2. В данном примере для той же самой задачи, что и в первом примере, подпрограмма ввода записи о служащем оформлена как процедура.
Здесь приведем только текст процедуры и оператор вызова ее в программе. Остальные операторы программы полностью совпадают с приведенными выше.
Итак, текст подпрограммы-процедуры:
{
Процедура ввода записи о служащем
} {
Формат строки ввода:
} {
<фамилия><пробел><оклад>
} {
Результаты функции - код ошибки при
вводе
( 0 или 1 )
} {
При отсутствии ошибки в переменной Rec
возвращаются
} {
сведения
о сотруднике.
} {
}
procedure
ReadData(var
Rec: Tdata;
var
ErrorCode:
Integer); var S:
string[80];{
строка ввода } P:
integer;{ номер позиции в строке }
SalaryS:
string[10];{
строка, содержащая оклад } begin
readln(S); if
S = '' then
{Строка
пустая ?}
ErrorCode
:= -1
else
begin
P
:= Pos(' ',S);
if
P = 0 then {Пробела
нет ?}
ErrorCode
:= 1
else
begin
Rec.Name
:= Copy(S, 1, P-1);
SalaryS
:= Copy(S, P+1, 255{до конца строки});
Val(SalaryS,
Rec.Salary, ErrorCode);
if
ErrorCode <> 0 then
{Ошибка
?}
ErrorCode
:= 1
else
ErrorCode
:= 0; {end
if}
end;
{if}
end; end;
А вызов процедуры в программе оформляется отдельным оператором вида:
ReadData(Data[i], ReadResult);