CFA LogoCFA Logo Computer
Загрузка поиска
Новости Компьютеры Прайс-лист [Новое] Прайс-лист [Б/У] Для ноутбуков Конфигуратор ПК Заказ, Оплата, Доставка Сервис объявления Драйвера Статьи Как нас найти Контакты
Новости
RSS канал новостей
Компания ASRock представила мировой общественности материнскую плату H110-STX MXM, которая рассчитана ...
Компания MSI в рамках серии Arsenal Gaming представляет пользователям материнские платы линейки ...
По данным наших коллег, в этом месяце компания Huawei официально представит свой новый смартфон. ...
Поколение процессоров Broadwell-EX, представленное Intel в июне прошлого года, обзавелось новым ...
Что мы с вами знаем о принтерах? На бытовом уровне, конечно, есть определённое представление. – ...
Самое интересное
Программаторы 25 SPI FLASH Адаптеры Optibay HDD Caddy Драйвера nVidia GeForce Драйвера AMD Radeon HD Игры на DVD Сравнение видеокарт Сравнение процессоров

АРХИВ СТАТЕЙ ЖУРНАЛА «МОЙ КОМПЬЮТЕР» ЗА 2002 ГОД

Мысли о Паскале

Владислав ДЕМЬЯНИШИН nitromanit@mail.ru

(Продолжение, начало см. МК №46, 51—52, 4, 6—7, 10, 12—13, 16—18, 22, 24, 29, 34, 41 (165, 170—171, 175, 177—178, 181, 183—184, 187—189, 193, 195, 200, 205, 212))

Процедуры и функции. Блочная структура программы

В начале было слово «Begin».

В конце было слово «End».

А между ними было еще много слов,

Смысл которых был известен ему одному…

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

Например, есть некоторая задача, состоящая в выводе текста на экран. Если пренебречь мудрыми советами и все-таки соорудить программу в виде одного блока Begin…End. (найдутся и такие умельцы :-)), то малейшее вмешательство в ее функции, будь то переделка уже имеющихся или добавление новых, поставит серьезную проблему перед ее разработчиком.

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

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

Для этого достаточно всего лишь обособить некоторые фрагменты кода. Например, две процедуры: одна — для вывода строки текста на экран в заданной позиции и заданной длины, чтобы длинная строка урезалась до ширины экрана; другая — для вывода определенного количества строк в пределах окна, начиная с некоторой строки.

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

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

Так что же такое подпрограмма?

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

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

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

Общая структура подпрограмм

Из вышесказанного уже, наверно, стало понятно, что структура подпрограммы строится так же, как и вся программа.

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

входной и выходной интерфейсы подпрограммы, обеспечивающие ее нормальный вызов;

описания локальных объектов;

составной оператор Begin..End, содержащий все необходимые действия.

Существуют два вида подпрограмм:

процедуры могут иметь (или не иметь) входные параметры и предназначены для выполнения некоторой задачи.

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

Итак, описания процедур и функций очень похожи. Описание процедур начинается со служебного слова procedure, а функций ( со служебного слова function. Далее следует указать имя описываемой подпрограммы, а вслед за ним в скобках указать список входных параметров. Для функций за списком параметров следует указать тип возвращаемого результата, которым может быть простой, строчный или ссылочный тип. Примеры:

Тело подпрограммы. Области действия имен

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

Будем рассматривать возможную структуру программы на следующем примере:

На этом примере буквой A обозначен самый внешний (главный) блок программы. B и E — блоки подпрограмм, описанных во внешнем блоке A. C и D — блоки, вложенные в подпрограмму B (т.е. описанные в ней).

Организация структуры блоков требует определенных правил для доступа к объектам:

объекты, описанные в некотором блоке, известны в пределах этого блока, а также во всех вложенных блоках;

идентификаторы объектов, описанных в блоке, не должны повторяться в пределах данного блока, но могут совпадать с именами из других блоков;

Если в некотором вложенном блоке описан локальный объект, имя которого совпадает с именем объекта, описанного в объемлющем (внешнем) блоке, то во вложенном блоке это имя будет ассоциироваться с одноименным локальным объектом. Т.е. одноименный объект из внешнего блока будет перекрыт локальным одноименным объектом.

Подпрограмма B будет известна (видна) не только в блоке A, но и в блоке E. Подпрограмма C будет известна не только в блоке B, но и в блоке D. Таким образом, вложенные подпрограммы будут видеть все объекты, описанные во внешних блоках. Т.е. в блоке C и D будут известны все объекты, описанные в блоках B и A. В блоке E будут известны объекты из блока A.

Исходя из оглашенных правил следует, что при составлении процедур и функций можно пользоваться именами для локальных объектов, независимо от того, встречаются ли эти имена в других блоках. Думаю, теперь значение термина «обособленный» должно быть понятно даже тем, кому доселе он был незнаком.

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

Программа содержит три процедуры, каждая из которых решает частную подзадачу:

PrepareItems(count : word; max : integer) — заполняет Count элементов массива Items целыми числами в диапазоне –Max..Max и инициализирует глобальные переменные;

Calculation( count : word ) вычисляет суммы чисел;

Report — выводит результат на экран.

Процедура Calculation содержит две вложенные подпрограммы и управляет вложенными процедурами в соответствии со знаком очередного числа.

Блок процедуры PrepareItems имеет свой список описаний параметров и переменных, которые можно использовать только в блоке этой процедуры. Переменные-параметры Count и Max считаются локальными переменными, они видны только в блоке процедуры PrepareItems.

Блок процедуры Report не имеет описания локальных переменных ( эта процедура работает с глобальными переменными.

Следует также объяснить значение Random(range:word):word — стандартная функция Turbo Pascal, которая формирует случайное положительное число X в диапазоне 0 < X < range. Следует учитывать, что результат X никогда не будет равен range, т.е. возможные значения результата будут лежать в диапазоне 0 < X < (range -1).

Таким образом, в процедуре PrepareItems в теле цикла стоят строки

цель которых ( получить случайное число, которое всегда будет 0 или 1, и в соответствии с этим установить значение переменной sign в 1 или в –1, чтобы потом в строке

сформировать случайное положительное число в пределах Max, умножить его на переменную sign, что может привести к изменению знака формируемого числа для инициализации очередного элемента массива Items. В итоге получим массив, заполненный положительными и отрицательными случайными числами.

Еще следует упомянуть о стандартной процедуре Inc( var x ; n : longint ), которая увеличивает целочисленный параметр X на целую величину N, а если последняя опущена (это допустимо), то приращение происходит на единицу. Т.е. эта процедура производит инкремент аргумента.

Раз уж я рассказал о процедуре Inc, то стоит замолвить словцо и о ее сестренке :-), процедуре Dec( var x ; n : longint ), которая делает все то же с точностью до наоборот, т.е. эта процедура производит уменьшение аргумента X на величину N, а если последняя опущена, то просто производит декремент аргумента (уменьшение на единицу).

(Продолжение следует)

Рекомендуем ещё прочитать:






Данную страницу никто не комментировал. Вы можете стать первым.

Ваше имя:
Ваша почта:

RSS
Комментарий:
Введите символы: *
captcha
Обновить






Рейтинг@Mail.ru
Хостинг на серверах в Украине, США и Германии. © www.sector.biz.ua 2006-2015 design by Vadim Popov