
- •1. Подпрограммы
- •1.1. Описание подпрограмм
- •1.2. Обращение к подпрограммам
- •1.3. Виды параметров подпрограмм
- •1.3.1. Параметры-значения и параметры-переменные
- •1.3.2. Параметры процедурного типа
- •1.3.3. Параметры-константы
- •1.3.4. Нетипизированные параметры подпрограмм
- •1.3.5. Массивы и строки открытого типа
- •1.4. Рекурсивные подпрограммы
- •2. Файлы данных
- •2.1. Текстовые файлы
- •2.2. Типизированные файлы
- •2.3. Нетипизированные файлы
- •2.4. Обработка ошибок, возникающих в действиях с файлами
- •3. Указатели - ссылочные типы данных
- •4. Модули
- •5. Локальные и глобальные сети эвм
- •6. Базы данных
- •6.1. Модели организации данных
- •6.2. Нормализация данных
- •6.3. Типы связей между объектами
- •7. Основы компьютерной безопасности
- •7.1. Компьютерные вирусы
- •7.2. Защита информации в Интернете
- •Контрольные работы
- •Тема 1. Параметры-значения и параметры-переменные
- •Пример выполнения задания
- •Решение. Составляем алгоритм (изображен ниже), а затем программу.
- •Варианты задания
- •Тема 2. Процедурный тип Пример выполнения задания
- •Варианты задания
- •Тема 3. Рекурсия Пример выполнения задания
- •Варианты задания
- •Тема 4. Текстовые и типизированные файлы Пример выполнения задания
- •Варианты задания
- •Тема 5. Указатели Пример выполнения задания
- •Варианты задания
- •Тема 6. Модули Пример выполнения задания
- •Варианты задания
- •Библиографический список
- •Оглавление
- •1.1. Описание подпрограмм ……………………………………………… 1
1.3.5. Массивы и строки открытого типа
Кроме рассмотренных видов параметров подпрограмм, версия 7.0 языка позволяет использовать еще такие виды параметров, как одномерные массивы открытого типа и строки открытого типа. В качестве фактических параметров здесь могут выступать массивы и строки любого размера.
Массив открытого типа - это такой формальный параметр, тип индексов которого, т.е. размер, не объявляется. Массив открытого типа может быть параметром-переменной, параметром-значением и параметром-константой. Индексация элементов массива ведется от нуля, а индекс последней компоненты определяется с помощью функции High. Рассмотрим использование массива открытого типа на примере.
Пример 8. Применить параметр массив открытого типа к примеру 7.
program Otkr_Massiv;
const {Задаем исходные массивы}
a : array[6..10] of real = (1, 2, 3, 4, 5);
b : array[1..4] of real = (6, 7, 8, 9);
function Sum_Otkr(z : array of real) : real; {z - массив открытого типа}
var i : byte; s : real;
begin s := 0;
for i := 0 to High(z) do {Нумерация элементов z от нуля!}
s := s + z[i];
Sum_Otkr := s end; {Sum_Otkr}
begin {Основная программа}
writeln(‘Сумма элементов вектора a = ’, Sum_Otkr(a) : 2 : 0);
writeln(‘Сумма элементов вектора b = ’, Sum_Otkr(b) : 2 : 0);
end.
Итак, массив открытого типа позволяет сократить число передаваемых в подпрограмму параметров.
Для описания в заголовке подпрограммы строки открытого типа используется специально введенный тип данных - OpenString. Можно также применять тип String в сочетании с ключом {$P+}, указываемым перед заголовком подпрограммы. Данный параметр также может быть параметром-константой, параметром-значением и параметром-переменной.
1.4. Рекурсивные подпрограммы
Рекурсивными называют подпрограммы, которые для получения результата используют обращение к самим себе. Если такое обращение присутствует в собственном теле подпрограммы, то рекурсия будет прямой. При косвенной рекурсии обращение к себе содержится в другой подпрограмме. В последнем случае возникает ситуация, требующая предварительного описания одной из подпрограмм с помощью директивы forward, например так.
procedure P(x : t); forward; {Опережающее описание}
procedure Q(y : tt);
… {Описание локальных объектов процедуры Q}
begin
… {Набор действий}
P(a);
… {Набор действий}
end; { Q }
procedure P; {Сокращенный заголовок }
… {Описание локальных объектов процедуры P}
begin
… {Набор действий}
Q(b);
… {Набор действий}
end; { P }
Рассмотрим прямую рекурсию более подробно. Начнем с классического примера рекурсии – функции вычисления факториала. Воспользуемся очевидным представлением: k! = k(k-1)! = … = k(k-1)0!. При описании действий в рекурсивной подпрограмме обязательно должна присутствовать терминальная ситуация, в которой результат получается без рекурсивного обращения, т.е. он известен либо по определению, либо из логики вычислительного процесса. В нашем случае в качестве терминальной выступает ситуация, когда значение факториала числа известно – это 0! = 1.
Function fac(k : byte) : longint;
begin
if k = 0 then fac := 1 {Терминальная ситуация}
else fac := k * fac(k-1)
end;
Заметим, что с помощью этой функции можно вычислить факториалы чисел, не превышающих 12, т.к. результат будет соответствовать диапазону значений типа longint. Для больших значений аргумента k следует использовать тип real для описания значений, возвращаемых функцией fac. Следует обратить внимание на то, что все промежуточные значения k будут помещаться в стек (k – это параметр-значение), откуда они начнут извлекаться по достижении терминальной ситуации. Если таких значений много, то стек может переполняться.
Приведем другой пример описания и использования рекурсии – рекурсивной процедуры получения кода натурального числа.
program preobrazovanie;
uses Crt;
var
n : longint;
procedure dvb(k : longint);
begin
if K > 0 then { k = 0 – это терминальная ситуация }
begin
dvb(k div 2); { Рекуpсивное обpащение пpоцедуpы к самой себе }
write(k mod 2)
end
end; {dvb}
begin
clrscr;
writeln('Введите натуральное число');
readln(n);
writeln('Двоичный код этого числа:');
dvb(n);
writeln;
writeln('Нажмите ENTER');
readln
end.
Процедура использует известный алгоритм получения двоичного кода, основанный на делении исходного числа на 2 и выводе остатка от деления на 2 всех промежуточных частных от деления, начиная с последнего не равного нулю частного (оно в стеке будет первым), и до исходного числа.
В заключение разговора о рекурсии приведем еще один пример реализации рекурсивных действий.
Пример 9. Уточнить с погрешностью 0,0001 корень уравнения
ln(x)-x + 1,8 = 0 на отрезке [2, 3] методом дихотомии.
program rec_dih;
const
e = 0.0001;
var a, b, x : real;
function f(s : real) : real;
begin f := ln(s) - s + 1.8 end; {Решаемое уравнение}
function R_Dihotom(x : real) : real; {Рекуpсивная функция}
begin
if abs(f(x)) < e then R_Dihotom := x
else begin
x := (a + b)/2; {Делим отрезок пополам }
if f(a) * f(x) < 0 then b := x {и выбираем ту его половину,}
else a := x; {на которой функция меняет знак}
R_Dihotom := R_Dihotom(x) {Рекурсивное обращение}
end
end;
begin
writeln('Введите гpаницы отpезка');
readln(a, b);
x := R_Dihotom((a + b)/2);
writeln('коpень = ', x : 6 : 4);
writeln('Пpи этом функция = ', f(x) : 6 : 4);
writeln('Нажмите ENTER');
readln
end.