49522 (Языки и технология программирования), страница 4

2016-07-30СтудИзба

Описание файла

Документ из архива "Языки и технология программирования", который расположен в категории "". Всё это находится в предмете "информатика" из 1 семестр, которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "курсовые/домашние работы", в предмете "информатика, программирование" в общих файлах.

Онлайн просмотр документа "49522"

Текст 4 страницы из документа "49522"

Формальные параметры ВА также относятся к его локальным переменным. Локальные данные создаются, т.е. им выделяется память, при вызове ВА, а освобождение этой памяти происходит при завершении работы ВА. В том случае, когда локальная переменная имеет тот же идентификатор, что и глобальная, алгоритм работает с локальной. При этом, значение глобальной переменной сохраняется в специальной области памяти, которая называется стек.

По способу передачи параметры в Турбо Паскале делятся на три типа:

параметры-значения,

параметры-переменные,

параметры-константы.

Параметры-значения

При вызове процедур и функций формальным параметрам-значениям выделяется новое место в памяти и присваиваются значения фактических параметров. При этом на месте фактических параметров могут стоять выражения. Совместимость типов определяется возможностями присваивания. После выполнения подпрограммы место формальных параметров освобождается. Изменение формальных параметров не сказывается на значении фактических. Заголовок процедуры с параметрами-значениями имеет вид:

Procedure MyProc1(par1,par2 : type1; par3,par4 : type2);

Параметры-переменные

При вызове процедур и функций формальные параметры-переменные занимают то же самое место в памяти, что и соответствующие им фактические параметры. Таким образом, дополнительное место в памяти не выделяется и изменения формального параметра приводят к изменениям фактического. Параметры-переменные, как правило, используются для передачи результатов из процедур в вызывающий алгоритм.

Такой механизм передачи данных требует, чтобы фактические параметры были переменными, причем в точности того же типа, что и формальные параметры. При описании ВА перед параметрами-переменными должно присутствовать слово var. Заголовок процедуры с параметрами-переменными имеет вид:

Procedure MyProc2(var par1,par2 : type1; var par3,par4 : type2);

Параметры-константы

Работа с формальными параметрами-константами внутри ВА ведется как с обычными локальными константами. Только эти константы принимают значения выражений, которые находятся в фактических параметрах. Им не выделяется новая память как локальным переменным. Запрещается изменять их значения во время выполнения подпрограммы и контроль за этим осуществляется на уровне компилятора, как для обычных констант.

Использовать параметры-константы рекомендуется при передаче данных большого объема с гарантией сохранения их значений. Заголовок процедуры с параметрами-константами имеет вид:

Procedure MyProc3(const par1,par2 : type1; const par3,par4 : type2);

ОТКРЫТЫЕ ПАРАМЕТРЫ-МАССИВЫ

Открытые параметры-массивы могут быть параметрами-значениями, параметрами-переменными и параметрами-константами. Они используются для передачи массивов произвольной размерности. Заголовок процедуры с открытыми параметрами-массивами имеет вид:

Procedure OpenArray(Vector : array of MyType);

Формальный параметр при этом является массивом элементов некоторого типа MyType с нулевой базой, т.е. Array [0..N-1] of MyType; где N - количество элементов массива, которое можно определить с помощью стандартной функции High.

ПРИМЕР: Увеличение вдвое всех элементов массива.

program DoubleProgram;

const n=10; m=20;

type T1 = array[1..n] of integer;

T2 = array[-m..m] of integer;

var A : T1; B : T2; k : integer;

Procedure Double(var X : array of integer);

var i : byte;

begin

for i:=0 to High(X)-1 do X[i]:=X[i]*2;

end;

begin

for k:=1 to n do read(A[k]);

for k:=-m to m do read(B[k]);

Double(A); {увеличение в 2 раза элементов массива A}

Double(B); {увеличение в 2 раза элементов массива B}

Double(k); {то же самое, что и присваивание k:=k*2}

writeln('k=',k); {напечатается: k=40 }

for k:=1 to n do write(A[k],' ');

writeln;

for k:=-m to m do write(B[k],' ');

end.

БЕСТИПОВЫЕ ПАРАМЕТРЫ

В Турбо Паскале существует возможность создания процедур и функций с параметрами, не имеющими типа. Бестиповые параметры могут быть параметрами-переменными и параметрами-константами, так как передаются только по адресу. Заголовок процедуры с параметрами, не имеющими типа может выглядеть таким образом:

Procedure MyProc(var par1,par2; const par3,par4);

Перед использованием формальных параметров необходимо выполнить их приведение к какому-либо типу. Использование бестиповых параметров дает большую гибкость программе, но ответственность за их корректное применение возлагается на программиста.

ПРИМЕР: Сложение первых N байт, начиная с того же места, что и X.

program without_type;

var N:word; s:string;

{$R-} (* отключение контроля за границами диапазонов *)

function Sum(var X; N:byte):word;

type A=array[1..1] of byte;

var i:byte; s:word;

begin

s:=0;

for i:=1 to n do S:=S+A(X)[i];

Sum:=s;

end;

begin

readln(s);

writeln(Sum(s,1)); {длина строки s}

writeln(Sum(s[1],1)); {код первого символа строки s}

writeln(Sum(s[1],length(s)));

{сумма кодов всех символов строки s}

read(N);

writeln(Sum(N,2));

{сумма двух байт, из которых состоит N типа word}

end.

ПРОЦЕДУРНЫЕ ТИПЫ

В Турбо Паскале существует два процедурных типа: тип-процедура и тип-функция. Для объявления процедурного типа используется заголовок процедуры или функции без имени.

ПРИМЕР:

type Proc1 = Procedure (a,b,c : integer; x:real);

Proc2 = Procedure (var a,b);

Proc3 = Procedure;

Func1 = Function : real;

Func2 = Function (n:integer) : boolean;

Можно описывать переменные этих типов, например: var p1,p2:Proc1; f1,f2:Func2; Переменным процедурных типов можно присваивать в качестве значений имена соответствующих ВА. При этом нельзя использовать стандартные процедуры и функции. После такого присваивания имя переменной становится синонимом имени ВА. Переменные процедурного типа можно, также передавать в подпрограммы в виде параметров. Благодаря этому, имеется возможность создания более гибких вспомогательных алгоритмов.

РЕКУРСИЯ

Рекурсия - это способ организации вычислительного процесса, при котором подпрограмма в ходе выполнения обращается сама к себе. С идейной точки зрения рекурсия аналогична методу математической индукции. Базе индукции соответствует база рекурсии. Предположению индукции соответствует предположение о том, что нужный ВА уже написан. Наконец, шагу индукции соответствует вызов создаваемого рекурсивного ВА. В любой рекурсии необходимо предусмотреть условие завершения процесса, т.е. когда вызова больше не происходит.

ПРИМЕР: Вычислить N-е число Фиббоначчи. (Смотри тему Циклы)

program Fib;

var n:byte;

function F(k:byte):word;

begin

if k<2 then F:=1 else F:=F(k-1)+F(k-2); {рекурсивный вызов}

end;

begin

write('введите номер числа Фиббоначчи ');

readln(N);

writeln(N,'-е число Фиббоначчи =',F(N));

readln

end.

Рекурсивный вызов может быть косвенным, или неявным. Например это происходит в случае, когда один ВА вызывает другой, а тот в свою очередь - первый. При использовании такой программной конструкции необходимо опережающее описание процедур и функций с директивой Forward. Сначала пишется только заголовок ВА со словом Forward, а реализация приводится ниже. При этом, в ней можно писать в заголовке либо только имя ВА, либо полностью повторять заголовок.

ПРИМЕР: Неявная рекурсия.

Procedure B(x:byte); forward;

Procedure A(y:byte);

begin

- - -

B(y);

- - -

end;

Procedure B;

begin

- - -

A(x);

- - -

end;

РЕКОМЕНДАЦИИ: Необходимо по возможности избегать применения рекурсии, так как большая глубина рекурсивных вызовов часто приводит к переполнению стека. В некоторых случаях проблему можно устранить, установив новый размер стека от 1024 до 65520 байт с помощью директивы

{$M размер стека, нижняя граница, верхняя граница памяти}

ТИПИЗИРОВАННЫЕ КОНСТАНТЫ

Кроме обычных констант в Турбо Паскале можно использовать типизированные константы, которые фактически являются переменными с начальными значениями. Они описываются в разделе Const в форме:

: = ;

ПРИМЕР:

const x : integer = 10; y : real = 3.14;

A : array[1..5] of integer = (1,2,-3,24,0);

B : array[1..2,-1..1] of byte = ((1,2,3),(4,5,6));

R : record m : string[10]; d,y : integer; end =

(m : 'January'; d : 20; y : 1999);

S : string[4] = 'abcd';

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

ПРИМЕР: Использование типизированных констант

program typed_const;

var N:integer;

procedure Test;

const k:integer=1;

begin

if k

begin

writeln(k,'-й вызов процедуры');

k:=k+1;

Test;

end

else writeln('последний вызов процедуры');

end;

begin

read(N);

if N>0 then Test;

end.

МОДУЛИ

Модуль (Unit) в паскале - это специальным образом оформленная библиотека определений типов, констант, переменных, а также процедур и функций. Модуль компилируется отдельно, в результате чего создается файл с расширением tpu (turbo pascal unit). Он не может быть запущен на выполнение самостоятельно, а может использоваться только из других программ. Для этого в программах указывается список имен используемых модулей в разделе Uses, после чего программа может использовать константы, типы и переменные, описанные в этих модулях.

В Турбо Паскале существует несколько стандартных модулей: System, Crt, Dos, Printer, Overlay, которые составляют библиотеку Турбо Паскаля: файл turbo.tpl (turbo pascal library). К числу стандартных модулей также относится модуль Graph.

Существует возможность создавать новые модули. Файл модуля имеет следующую структуру:

UNIT ;

INTERFACE

IMPLEMENTATION

Begin

End.

Имя модуля должно совпадать с именем файла, в котором он хранится. Раздел объявлений или интерфейсная часть содержит объявления всех глобальных объектов модуля (типов, констант, переменных и подпрограмм), которые будут доступны программам, использующим этот модуль. Подпрограммы в этом разделе объявляются только заголовками. В интерфейсной части модулей нельзя использовать опережающее описание, т.е. директиву forward.

Раздел реализации или исполняемая часть модуля содержит описание локальных объектов модуля : типов, констант, переменных и подпрограмм. Здесь же содержится описание подпрограмм, объявленных в интерфейсной части. Для этих подпрограмм заголовок может указываться либо без параметров, либо с параметрами, которые в точности повторяют описание из раздела объявлений. Локальные объекты модуля доступны в пределах модуля, но не доступны программам, использующим модуль.

Раздел инициализации может отсутствовать. В этом случае можно даже не писать слово Begin, а сразу завершать модуль, написав End. В раздел инициализации входят операторы, которые будут выполняться при запуске программы, использующей модуль, перед выполнением основной программы. Разделы инициализаций выполняются в том порядке, в котором подключаются модули.

ПРИМЕР: Модуль для работы с одномерными массивами до 100 целых чисел.

{модуль описаний, глобальных для основной программы и всех модулей}

Unit Globals;

Interface

const Len=100;

type Vector = array[1..Len] of integer;

Implementation

End.

Unit Vectors;

Interface

uses Globals;

{находит максимальный элемент массива}

function Max_V(A:Vector; n:byte):integer;

{поэлементное сложение двух векторов}

procedure Add_V(A,B:Vector; n:byte; var C:Vector);

{скалярное произведение векторов}

function Scal_V(A,B:Vector; n:byte):integer;

Implementation

function Max_V; {заголовок без параметров}

var i,max:integer;

begin

max:=A[1];

for i:=2 to n do if A[i]>max then max:=A[i];

Max_V:=max;

end;

procedure Add_V;

var i:integer;

begin

for i:=1 to n do C[i]:=A[i]+B[i];

end;

function Scal_V(A,B:Vector; n:byte):integer;

{заголовок из interface}

var s:integer; i:byte;

begin

s:=0;

for i:=1 to n do s:=s+A[i]*B[i];

Scal_V:=s;

end;

End. {раздел инициализации модуля отсутствует}

АЛГОРИТМЫ ПОИСКА

Алгоритмы поиска применяются для нахождения, например, в массиве элемента с нужными свойствами. Обычно различают постановки задачи поиска для первого и последнего вхождения элемента. Во всех ниже изложенных алгоритмах будем считать, что производится поиск в массиве A из N целых чисел элемента, равного X.

ЛИНЕЙНЫЙ ПОИСК

Линейный поиск осуществляется циклом (while или repeat - until) с двойным условием. Первое условие контролирует индекс на принадлежность массиву, например, (i<=N). Второе условие - это условие поиска. В нашем случае в цикле while это условие продолжения поиска: (A[i]<>X), а в цикле repeat - until это условие завершения поиска: (A[i]=X). В теле цикла обычно пишется только один оператор: изменение индекса в массиве.

После выхода из цикла необходимо проверить, по какому из условий мы вышли. В операторе if обычно повторяют первое условие цикла. Можно говорить об успешном поиске с циклом while при выполнении этого условия, а с циклом repeat - until при его нарушении.

ПРИМЕР: Линейный поиск

program Poisk1;

var A:array[1..100] of integer;

N, X, i:integer;

begin

read(N); {N<=100}

for i:=1 to N do read(A[i]);

read(X);

i:=1; {i:=0;}

while (i<=N) and (A[i]<>X) do i:=i+1;

{repeat i:=i+1; until (i>N) or (A[i]=X);}

if i<=N then write('первое вхождение числа ',X,'

в массив A на ',i,' месте')

else write('не нашли');

end.

При поиске последнего вхождения после ввода должны идти операторы:

i:=N; {i:=N+1;}

while (i>=1) and (A[i]<>X) do i:=i-1;

{repeat i:=i-1; until (i<1) or (A[i]=X);}

if i>=1 then write('последнее вхождение числа ',X,' в массив A на ',i,' месте')

else write('не нашли');

ПОИСК С БАРЬЕРОМ

Идея поиска с барьером состоит в том, чтобы не проверять каждый раз в цикле условие, связанное с границами массива. Это можно обеспечить, установив в массив так называемый барьер: любой элемент, который удовлетворяет условию поиска. Тем самым будет ограничено изменение индекса.

Выход из цикла, в котором теперь остается только условие поиска, может произойти либо на найденном элементе, либо на барьере. Таким образом, после выхода из цикла проверяется, не барьер ли мы нашли? Вычислительная сложность поиска с барьером меньше, чем у линейного поиска, но также является величиной того же порядка, что и N - количество элементов массива.

Существует два способа установки барьера: дополнительным элементом или вместо крайнего элемента массива.

ПРИМЕР: Поиск с барьером

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Нет! Мы не выполняем работы на заказ, однако Вы можете попросить что-то выложить в наших социальных сетях.
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
4123
Авторов
на СтудИзбе
667
Средний доход
с одного платного файла
Обучение Подробнее