Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Описание подпрограммы



Описание подпрограммы состоит из заголовка и тела подпрограммы.

Заголовок процедуры имеет вид:

Procedure < имя > [список формальных параметров];

Заголовок функции:

Function < имя > [список формальных параметров]: тип возвращае­мого функцией результата.

Список формальных параметров необязателен и может отсутство­вать. Если же он есть, то в нем должны быть перечислены имена формаль­ных параметров и их типы, например:

Procedure SB (a: real; b;integer; c:char),

Параметры в списке отделяются друг от дру­га точками с запятой. Несколько следующих подряд однотипных парамет­ров можно объединить в подсписки, например,

Вместо a: real; b: real можно написать а,b: real. Операторы тела подпрограммы рассматривают список формальных параметров как своеобразное расширение раздела описаний: все перемен­ные из этого списка могут использоваться в любых выражениях внутри подпрограммы. Так осуществляется настройка алгоритма подпрограммы на конкретную задачу.

Пример программы, которая заполняет область экрана 8´8 символов в соответствии с рисунком:

 
 


Program DemoProcedure;

Uses CRT;

Var x,y: integer;

Procedure A1;

begin

for y:=1 to 4 do

for x:=1 to 4 do

begin

gotoxy(x,y);

write(#176);

end;

end;

Procedure A2;

begin

for y:=5 to 8 do

for x:=5 to 8 do

begin

gotoxy(x,y);

write(#176);

end;

end;

Procedure A3;

begin

for y:=1 to 4 do

for x:=5 to 8 do

begin

gotoxy(x,y);

write(#178);

end;

end;

Procedure A4;

begin

for y:=5 to 8 do

for x:=1 to 4 do

begin

gotoxy(x,y);

write(#178);

end;

end;

Begin

a1;

a2;

a3;

a4;

readln;

End.

Пример наглядно демонстрирует структуру программ с использованием процедур, когда раздел описаний больше, чем исполнительная часть программы.

Задача существенно упрощается, если использовать процедуры с параметрами.

Program DemoProcedureParam;

Uses CRT;

Var x,y: integer;

Procedure A1(a,b,c,d:integer);

begin

for y:=a to b do

for x:=c to d do

begin

gotoxy(x,y);

write(#176);

end;

end;

Procedure A2(a,b,c,d:integer);

begin

for y:=a to b do

for x:=c to d do

begin

gotoxy(x,y);

write(#178);

end;

end;

Begin

clrscr;

a1(1,4,1,4);

a2(5,8,1,4);

a2(1,4,5,8);

a1(5,8,5,8);

readln;

End.

Если ввести параметр символьного типа, то в данной задаче можно вообще ограничится обной процедурой.

Program DemoProcedure;

Uses CRT;

Var x,y: integer;

Procedure A1(a,b,c,d:integer; ch:char);

begin

for y:=a to b do

for x:=c to d do

begin

gotoxy(x,y);

write(ch);

end;

end;

Begin

clrscr;

a1(1,4,1,4,#176);

a1(5,8,1,4,#178);

a1(1,4,5,8,#178);

a1(5,8,5,8,#176);

readln;

End.

Таким образом, выигрыш в использовании процедур с параметрами в больших задачах налицо. Здесь проявляется еще одно преимущество использования процедур – процедуру описывают один раз, а вызывать можно столько, сколько потребуется.

Рассмотрим пример использования функций. В Турбо Паскаль нет операции возведения в степень, однако, с помощью встроенных функций Ln(x) и ехр(х) можно создать функцию с новым именем, например, stepen, которая будет возво­дить любое вещественное число в любую вещественную степень.

Пример:

Var

х,у: real;

Function Stepen (a,b: real): real;

Begin { Stepen }

if a>0 then Stepen: = exp(b* ln(a»

else if a<0 then Stepen: = exp (b* ln(abs(a)))

else if b=0 then Stepen:=l

else Stepen:=0

End { Stepen }

Begin

repeat

readln (x,y);

writeln (Stepen (x,y): 12:10; Stepen (x,-y): 15:5;

Until EOF

End.

В программе вводится пара чисел X и Y и выводится на экран дис­плея результат возведения X сначала в степень +Y, а затем в степень -Y. Для выхода из программы нужно ввести Ctrl -Z и Enter.

Для вызова функции Stepen мы просто указали ее в качестве пара­метра при обращении к встроенной процедуре Writeln. Параметры X, Y в момент обращения к функции - это фактические параметры. Они подстав­ляются вместо формальных параметров А и В в заголовке функции и затем над ними осуществляются нужные действия. Полученный результат при­сваивается идентификатору функции - именно он и будет возвращен как значение функции при выходе из нее. В программе функция Stepen вызы­вается дважды - сначала с параметрами X и Y, а затем X и - Y, поэтому получатся два новых результата.

Механизм замены формальных параметров на фактические позво­ляет нужным образом настроить алгоритм, реализованный в подпрограм­ме. Необходимо следить за тем, чтобы количество и тип формальных па­раметров строго соответствовали количеству и типам фактических пара­метров в момент обращения к подпрограмме. Смысл используемых фак­тических параметров зависит от того, в каком порядке они перечислены при вызове подпрограммы. В примере первый по порядку фактический параметр будет возводиться в степень, задаваемую вторым параметром, а не наоборот. Необходимо следить за правильным порядком перечисления фактических параметров при обращении к подпрограмме.

Любой из формальных параметров подпрограммы может быть либо параметром-значением, либо параметром-константой. Если параметры оп­ределяются как параметры-переменные, перед ними необходимо ставить слово Var, если константы - слово Const, например:

Procedure MyProcedure(Var a: real;b: real; const c: string);

Здесь, a - параметр-переменная, b - параметр-значение, с - пара­метр-константа.

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

Например, если для предыдущего примера был бы использован та­кой заголовок функции

Function Stepen(var a,b: real): real;

то при втором обращении к функции компилятор указал бы на не­соответствие типа фактических и формальных параметров. (Параметр - Y есть выражение, в то время как соответствующий ему формальный пара­метр описан как параметр-переменная).

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

Если параметр определен как параметр-значение, то перед вызовом подпрограммы это значение вычисляется, полученный результат копиру­ется во внутреннюю память и передается подпрограмме. Важно учесть, что даже если в качестве фактического параметра указано простейшее вы­ражение в виде переменной или константы, все равно подпрограмме будет передана лишь копия переменной (константы). Любые возможные изме­нения в подпрограмме параметра-значения никак не воспринимаются вы­зывающей программой, так как в этом случае изменяется копия фактиче­ского параметра.

Если параметр определен как параметр-переменная, то при вызове подпрограммы передается сама переменная, а не ее копия {фактически в этом случае подпрограмме передается адрес переменной). Изменение па­раметра переменной приводит к изменению самого фактического пара­метра в вызывающей подпрограмме.

В случае если параметр определен как параметр-константа, в под­программу также передается адрес области памяти, в которой располага­ется переменная или вычисленное значение. Однако компилятор блокиру­ет любые присваивания параметру-константе нового значения в теле под­программы.

Пример:

Program DemoConst;

Сonst

a: integer=5;

b: integer =7;

procedure Inc2 (Var c: integer; b: integer);

Begin

c: = c+c;

b: = b+b;

writeln ('удвоенные:', с:5, b:5)

End;

Begin

writeln ('исходные:', а:5, b:5);

Inc2 (a,b);

writeln ('результат:', a:5, b;5)

End.

В результате выполнения программы будет выведено:

исходные: 5 7

удвоенные: 10 14

результат; 10 7

Поясним программу. В ней задаются два целых числа 5 и 7. Эти числа передаются процедуре Inc2, в которой они удваиваются. Один из параметров передается как параметр-переменная, другой - как параметр-значение. Значения параметров до и после вызова процедуры, а также ре­зультат их удвоения выводятся на экран. Удвоение второго формального параметра в процедуре Inc2 не вызвало изменения фактической перемен­ной В, поскольку он описан в заголовке процедуры как параметр-значение. Этот пример может служить еще и иллюстрацией механизма «закрывания» глобальной переменной одноименной локальной. Перемен­ная В объявлена как глобальная, в теле процедуры ее «закрыла» локальная переменная В, объявлена как параметр-значение.

Основные понятия структурного программирования

Фактически подпрограммы представляют собой инструмент, с по­мощью которого любая программа может быть разбита на ряд, в известной степени, независимых друг от друга частей. Такое разбиение бывает необ­ходимо по двум причинам:

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

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

Как известно, любое имя в программе должно быть обязательно описано, перед тем как оно появится среди исполняемых операторов. Не делается исключения и в отношении подпрограмм: каждую свою процеду­ру и функцию программисту необходимо описать в разделе описаний.

Программа    
  Подпрограмма А  
        Подпрограмма AI        
        Подпрограмма А2        
           
               
  Подпрограмма В    
        Подпрограмма В1        
        П Подпрограмма В2          
            Подпрограмма В21            
            Подпрограмма В22            
   
                         
                 

Пример структуры программы

Описать подпрограмму – это значит указать ее заголовок и тело. В заголовке объявляются имя подпрограммы и формальные параметры, если они есть. Для функции, кроме того, указывается тип возвращаемого ею ре­зультата. За заголовком следует тело подпрограммы, которое, подобно программе состоит из раздела описаний и раздела исполняемых операто­ров. В разделе описаний подпрограммы могут встретиться описания под­программ низшего уровня, в тех - описания других подпрограмм и т.д.

Иерархия описаний для программы, структура которой показана выше, имеет вид:

Program...;

Procedure A;

Procedure Al;

Begin

……..

End {Al};

Procedure A2:

Begin

………

End {A2};

Begin {A}

………

End {A},

Procedure В;

Procedure ВI

Begin

…….

End;{Bl};

Procedure B2;

Procedure B21,

и т.д.

Подпрограмма любого уровня имеет обычно множество имен кон­стант, переменных, типов и вложенных в нее подпрограмм низшего уров­ня. Считается, что все имена, описанные внутри подпрограммы, локадизуются в ней, т.е. они как бы невидимы снаружи подпрограммы. Таким образом, со стороны операторов, использующих обращение к подпро­грамме, она трактуется как «черный ящик», в котором реализуется тот или иной алгоритм. Все детали этой реализации скрыты от глаз пользователя подпрограммы, и поэтому недоступны ему. Так, в рассмотренном выше примере из основной программы можно обратиться к процедурам А и В, но нельзя вызвать ни одну из вложенных в них процедур А1, А2, В1 и т.д.

Это относится не только к именам подпрограмм, но и вообще к лю­бым именам (идентификаторам), объявленным в них константам, пере­менным, меткам и т.д. все имена (идентификаторы) в пределах подпро­граммы должны быть уникальными и не могут совпадать с именем самой подпрограммы.

При входе в подпрограмму низшего уровня становятся доступными не только объявленные в ней имена, но и сохраняется доступ ко всем име­нам верхнего уровня. Образно говоря, любая подпрограмма как бы окру­жена полупрозрачными стенками; снаружи подпрограммы мы не видим ее внутренности, но, попав в подпрограмму, можем наблюдать все, что дела­ется снаружи. Так, например, из подпрограммы В21 мы можем вызвать подпрограмму А, использовать имена, объявленные в основной програм­ме, в подпрограммах В и В2. И даже обратиться к ним. Любая подпро­грамма может, наконец, вызвать саму себя - такой способ вызова называ­ется рекурсией.

Пусть имеем такое написание:

Program..,;

VarVl:....;

Procedure A;

VarV2:..,;

Procedure В;

VarV3...;

Procedure В1;

VarV4:...;

Procedure B11;

VarV5;

Из процедуры В11 доступны все пять переменных VI,... V5, из процедуры В1 доступны переменные VI,... V4, из центральной програм­мы -только VI.

При взаимодействии подпрограмм одного уровня иерархии вступа­ет в силу основное правило Турбо Паскаль: любая подпрограмма перед ее использованием должны быть описана. Поэтому из подпрограммы В мож­но вызвать подпрограмму А, но из А вызвать В невозможно. Подпрограм­ме доступны только те объекты верхнего уровня, которые описаны до описания данной программы. Эти объекты называются глобальными по отношению к подпрограмме.

В отличие от стандартного Паскаля, в Турбо Паскаль допускается произвольная последовательность описания констант, переменных, типов, меток и подпрограмм. Например, раздел Var описания переменных может появляться в пределах раздела описаний одной и той же подпрограммы много раз и перемежаться с объявлениями других объектов и подпро­грамм. Для Турбо Паскаль безразличен порядок следования и количество разделов Var, Const, Type, Label, но при определении области действия этих описаний следует помнить, что имена (идентификаторы), описанные ниже по тексту программы, недоступны из ранее описанных подпрограмм, например:

Var VI:...;

Procedure S;

VarV2:...;

End{S};

VarV3:...;

Из процедуры S можно обратиться к переменным VI и V2, но нель­зя использовать V3, поскольку описание V3 следует в программе за опи­санием процедуры S.

Локальные имена (идентификаторы) в подпрограмме могут совпа­дать с ранее объявленными глобальными именами. В этом случае считает­ся, что локальное имя как бы закрывает глобальное и делает его недоступ­ным, например:

Var i: integer;

Procedure P;

Var

i: integer;

Begin

Writeln (i)

End{P};

Begin

I:=1;

P;

End.

Эта программа выведет на экран произвольное значение внутрен­ней переменной. Если убрать описание переменной из процедуры Р, то на экран будет выведено значение глобальной переменной I, т.е. 1.

Таким образом, одноименные глобальные и локальные переменные – это разные переменные. Любое обращение к таким переменным в теле подпрограммы трактуется как обращение к локальным переменным, т.е. глобальные переменные в этом случае попросту недоступны.

Пример процедуры, работающей со строками.

При использовании функции Up Case программист, не владеющий анпийским языком, сталкивается с существенными ограничениями сферы применения своих программ. Возникает необходимость в построении функции, преобразующей строчные литеры русского алфавита в пропис­ные. Program MyFunctionUpCase;

Uses CRT;

Var

Words: string;

Procedure MyUpCase (Var Words: string);

(Данная программа обеспечивает полное преобразование строчных литер в прописные, включая литеры русского алфавита}

Var

i: BYTE

Procedure StringManipulation(Var Words: String; i: BYTE);

(Данная процедура осуществляет посимвольное преобразование строки}

Begin

Words [i] of

'a':Words[i]: = 'A';

'6':Words[i]: = 'E';

'в': Words [i]: = 'B';

……………

end;

End;

Begin

for i: = 1 to Length(Words) do StringManipulation(Words, i);

CirScr;

Words: = ‘Современная гуманитарная академия’;

MyUpcase(Words);

Writeln(Words);

End.

В процедуре MyUpcase объявляется только одна переменная. Это переменная типа BYTE, предназначенная в качестве счетчика. Для пере­менной i был выбран тип BYTE, поскольку максимальная длина строки равна 255 символов, а переменная BYTE как раз обеспечивает хранение чисел с величиной до 255.

В процедуре StringMampulation сначала производится попытка пре­образования символов с помощью функции UpCase. Затем для символов русского алфавита, не преобразуемых этой функцией, реализуется прямое преобразование с помощью конструкции CASE OF.

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

Program DemoProcedures;

Uses CRT;

Procedure dvigenie;

Var a,b,x,y:integer;

ch:char;

Procedure Okno;

begin

TextBackGround(blue);

Window(10,1,60,15);

Clrscr;

end;

Procedure Kubik;

begin

TextBackGround(white);

Window(x,y,x+1,y);

ClrScr;

end;

Procedure Dvig;

begin

repeat

Okno;

x:=x+a;

y:=y+b;

kubik;

delay(2000);

until (x>=59) or (x<=10) or (y<=1) or (y>=15);

end;

begin

x:=10;

y:=1;

a:=1;

b:=1;

repeat

if keypressed

then ch:=readkey;

dvig;

if (x<=10) and ((a=-1) and (b=1)) then a:=1;

if (x<=10) and ((a=-1) and (b=-1)) then a:=1;

if (y>=15) and ((a=1) and (b=1)) then b:=-1;

if (y>=15) and ((a=-1) and (b=1)) then b:=-1;

if (x>=59) and ((a=1) and (b=1)) then a:=-1;

if (x>=59) and ((a=1) and (b=-1)) then a:=-1;

if (y<=1) and ((a=1) and (b=-1)) then b:=1;

if (y<=1) and ((a=-1) and (b=-1)) then b:=1;

until ch=#32;

end;

Begin

TextBackGround(0);

ClrScr;

dvigenie;

End.

Задния

Создать программу, имитирующую на экране стакан с чаем, в который падает кусочек сахара. Пока сахар тонет, он тает. Около нижней грани он исчезает.

Создать программу, имитирующую движение в окне надписи, при столкновении с гранью окна, она отскакивает по закону отражения.

Создать программу, имитирующую тараканьи бега. При запуске программы по экрану начинают двигаться пять кубиков слева направо:

а) кубики движутся с разными скоростями, которые устанавливаются в момент запуска программы;

б) скорость кубиков меняется периодически во время движения;

в) скорость кубиков меняется случайным образом у кубиков произвольно во время движения.

Создать программу, имитирующую попарное мигание двух кубиков в разных частях экрана.

Литература

Абрамов С.А., Зима Е.В. Начала информатики. - М.: Наука, 1989.

Алексеев В.Е., Ваулие А.С., Петрова Г.Б. Вычислительная техника и программирование. Практикум по программированию: Практическое пособие / Под ред. А.В. Петрова. М.: Высшая школа, 1991.

Вострокнутов И.Е. Турбо Паскаль. Теория, примеры, задания. Часть 1. Ядро. Арзамас. АГПИ 2000.

Гуденко Д., Петроченко Д. Сборник задач по программированию. СПб.: Питер, 2003.

Жидкова О.А., Кудрявцева Е.К. Алгоритмы и основы программирования. М.: Интеллект-Центр, 1999.

Жидкова О.А., Кудрявцева Е.К. Справочные материалы для программирования на языке Паскаль. М.: Интеллект-Центр, 2001

Жилин С.А., Жилина Н.Б. Информатика: Теория и практика решения задач. М.: РКНК, 2001.

Зеленяк О.П. Практикум программирования на Turbo Pascal: Задачи, алгоритмы и решения. К.: Диа Софт, 2001.

Культин Н.Б. Turbo Pascal в задачах и примерах. СПб.: БХВ – Петербург, 2000.

Культин Н. С/С++ в задачах и примерах. - СПб.: БХВ - Петербург, 2001.

Марченко А.И. Марченко А.А. Программирование в среде Турбо Паскаль 7.0. - М.: Бином Универсал, К.: ЮНИОР, 1997.

Милов А.В. Основы программирования в задачах и примерах: Учебный курс. Харьков: Фолио, 2002.

Семашко Г.А., Салтыков А.И. Программирование на языке Паскаль. М.: Наука, 1988.

Фаронов В.В. Турбо Паскаль 7.0. Начальный курс. Учебное пособие. - М.: Нолидж, 1997.

Федоренко А. Алгоритмы и программы на Turbo Pascal: Учебный курс. СПб.: Питер, 2001.





Дата публикования: 2015-06-12; Прочитано: 242 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.042 с)...