|
|
Назад
Раздел "Программирование"
Пользовательские процедуры
Цель: освоить опыт модульного программирования при решении задач на языке Паскаль;
изучить особенности пользовательских процедур; передачу параметров по значению и по ссылке (или по адресу);
выяснить, когда нужны var-параметры.
Введение. При решении сложных задач обычно используют метод пошаговой детализации, иначе,
методу программирования сверху вниз. Одним из видов подпрограмм являются пользовательские процедуры.
В Паскале существуют два принципиально различных механизма передачи параметров подпрограммам.
1. Передача параметра по значению. Суть этого механизма в следующем. При обращении
к подпрограмме сначала вычисляется значение аргумента, передаваемого из главной программы,
затем результат вычисления назначается соответствующему формальному параметру подпрограммы.
В дальнейшем изменения в значении такого формального параметра, производимые подпрограммой,
никак не отразятся на значении соответствующего фактического значения в главной программе.
По умолчанию в Паскале действует механизм передачи параметра по значению.
2. Передача параметра по ссылке (или по адресу).
В этом случае формальный параметр в заголовке процедуры описывется
с атрибутом var.
В главной программе передаваемым аргументом должна
быть переменная, но не константа и не выражение. При обращении к подпрограмме последняя
получает не значение аргумента, а его адрес. При каждом упоминании параметра
в подпрограмме-процедуре, передаваемого по ссылке, компилятор будет использовать область памяти,
отведенную для аргумента из главной программы.Таким, образом, всякое изменение формального параметра
фактически будет и изменением в значении соответствующего аргумента.
Примечание. Необходимо помнить о следующих особенностях подпрограммы-процедуры:
Процедура в отличии от функции может возвращать не обязательно одно конкретное значение.
В заголовке процедуры отсутствует указание о типе возвращаемого значения.
Параметры var нужны процедуре, чтобы в ходе своего выполнения она могла изменять их значения.
Процедуры могут вообще не иметь параметров.
Все, что может сделать функция, можно осуществить с помощью процедуры.
Функция или процедура - когда что?
Решая, какой модуль - процедуру или функцию - использовать при написании программы,
опираются на следующие соображения.
Если очевидно, что подпрограмма должна возвратить единственный результат (например, квадратный корень из заданного числа),
то ее следует оформить в виде функции.
Если необходимо выдать несколько значений (например, массив чисел, список фамилий) или же она должна выполнить несколько действий
(например, найти минимальное и максимальное значение из последовательности заданных
чисел, выполнить сортировку ряда чисел), то такую подпрограмму следует записать как процедуру.
Примеры пользовательских процедур
Процедуры очень удобно использовать при решении задач, в которых выполняется обработка структурированных данных - массивов и строк.
При этом необходимо помнить, что при описании формальных параметров нельзя задавать тип данных
с указанием конкретной размерности массива или конкретной длины строки -
для структурированных типов данных необходимо вводить пользовательское имя.
Например,
type mas=array[1..n] of integer;
type stroka=string[30];
var
a:mas;
fio, name:stroka;
procedure(var b:mas; n:integer);
procedurt(var st:stroka,m:integer);
Во многих задачах возникает необходимость обрабатывать
последоватльности чисел, символов, строк, рядов.
Пример 1. Процедура печатает все делители заданного целого числа number и сообщает,
является ли число простым или нет.
procedure printdivisors(j: word; var flag:boolean);
{j не меняет свое значение, а переменная flag изменяет свое значение }
var
m :word; {возможные делители}
begin
flag:=true;{гипотеза, что число простое}
{Проверка производится до первого делителя}
m:=2; {первый возможный делитель}
while (m <j) and flag do
begin
if j mod m=0 then
begin
flag:=false;
write(m,' ');
end;
m:=m+1
end;{while}
end;{printdivisors}
Если в главной программе объявлены переменные
n:word; prime: boolean;
то вызов процедуры в главной программе выполняют операторы:
printdivisors(n,prime);
if prime then writeln(n,'- простое');
Пример 2. Создание массива.
Вариант 1. Ввод чисел с клавиатуры.
procedure inputmas(var b : mas; n:integer);
var
i: integer;
begin
for i:= 1 to n do
readln(b[i]);
enf; {inputmas}
Вариант 2. Заполнение массива случайными числами.
procedure inputmas(var b : mas; n:integer);
var
i: integer;
begin
for i:= 1 to n do
b[i]:=random(100);
enf; {inputmas}
Пример 3. Вывод массива на экран.
procedure outmas(var b : mas; n:integer);
var
i: integer;
begin
for i : = 1 to n do
write(b[i],' ');
writeln;
end; {outmas}
Пример 4. Сортировка массива целых чисел методом "пузырька"
Идея: Внешний цикл repeat ... until "прокручивает" внутренний цикл for...,
пока не обнаружит, что при очередном просмотре ряда не произошло ни одной перестановки элементов.
procedure sort(var a: mas; n : intejer);
{упорядочение по возрастанию}
var
i : integer;
begin
repeat
flag:=false;
for i:=1 to n-1 do
if a[i]>a[i+1] then
begin {перестановка двух соседних элементов массива}
flag:=true;
temp:=a[i];
a[i]:=a[i+1];
a[i+1]:=temp
end; {if...then}
until flag=false
end; {sort}
Упражнения
Написать подпрограммы-процедуры:
расчета количества четных чисел в массиве n целых положительных чисел;
замены всех четных чисел в массиве нулями, а кратных трем - единицами;
заполнения массива заданным целым числом;
Perest(var a : mas; k, m : integer); для перестановки двух элементов с индексами k и m.
|
|