Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
delphi / песни о паскале.pdf
Скачиваний:
66
Добавлен:
26.03.2016
Размер:
5.16 Mб
Скачать

Глава 20 Процедуры: первый опыт

Переходим к третьему этапу, где можно забыть о главной программе и сосредоточиться на теле процедуры Scan. Напомню, что ей поручено заменить в строке буквы «A» на буквы «B». С этой несложной работой справится цикл, содержащий вложенный в него условный оператор.

for k:=1 to Length(arg) do

if arg[k]=’A’ then arg[k]:=’B’;

Напомню, что arg — это переданная в процедуру строка, а k — счетчик цикла. Вставив этот цикл в тело процедуры Scan, получим готовенькую программу.

{ P_20_1 – третий этап разработки }

var S: string; k: integer;

procedure Scan(arg : string); begin

 

for k:=1 to Length(arg) do

end;

if arg[k]=’A’ then arg[k]:=’B’;

 

begin

{--- главная программа ---}

 

for k:=1 to 3 do begin

 

Write(’Введите строку: ’); Readln(S);

 

Scan(S);

 

Writeln(S);

end.

end;

 

Обратите внимание на счетчик циклов k. Он — счетчик — используется нами в двух местах: в главной программе и в процедуре. Налицо экономия памяти, не так ли? Насколько оправдана эта надежда? Скоро узнаем.

Для пишущих на Delphi. Компилятор Delphi не позволит использовать счетчик k так, как сделано в этой программе, — но об этом чуть позже.

Первые раны

Теперь запустите наше творение. Если вам это удалось, значит компилятор не нашёл ошибок. Но вот незадача, — работает программа неправильно! Во-первых, буква «A» не меняется на букву «B». Ещё печальней то, что перестал работать цикл в главной программе. Она, что называется, зациклилась, запрашивая непрестанно всё новые и новые строки. А ведь на скелете цикл работал, — мы проверяли!

131

Глава 20 Процедуры: первый опыт

Впрочем, если ввести строку из трех символов, программа чудесным образом завершится. Это наводит на размышление, — ведь цикл главной программы тоже считает до трех. Не промахнулись ли мы, доверив переменной k «служить двум господам», работая в двух циклах? Ведь внутри процедуры значение счетчика k изменяется, что нарушает работу цикла в главной программе. И лишь когда счетчик случайно станет равен трём, программа завершается.

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

Глобальные и локальные

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

const c1 = ’Глобальная’;

procedure Local; begin

end;

Writeln(c1);

 

begin

{--- главная программа ---}

 

Local;

 

Writeln(c1);

end.

Readln;

 

Очевидно, программа дважды напечатает константу C1, — проверьте меня. Теперь добавим объявление локальной константы с тем же именем C1, но поместив его между заголовком процедуры Local и её телом. К совпадающим именам я прибегнул не от бедности фантазии, — мой умысел скоро прояснится.

132

Глава 20 Процедуры: первый опыт

const c1 = ’Глобальная’;

procedure Local;

const c1 = ’Локальная’; begin

end;

Writeln(c1);

 

begin

{--- главная программа ---}

 

Local;

 

Writeln(c1);

end.

Readln;

 

Известно, что компилятор не допускает совпадающих имен, но здесь — иное дело. Локальная константа C1 «спряталась» внутри своей процедуры и, как говорят программисты, не видна за её пределами.

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

локальные объекты (константы, переменные и прочие) видны лишь внутри тех подпрограмм, в которых они объявлены;

при совпадении имен локального и глобального объектов, внутри подпрограммы имеет силу локальный объект; при этом глобальный объект скрывается локальным.

Сучетом сказанного нашу неработающую программу исправим так.

{P_20_1 – вариант программы с локальной переменной }

var S: string;

k: integer; { глобальная переменная }

procedure Scan(arg : string);

var k: integer; { локальная переменная } begin

for k:=1 to Length(arg) do

if arg[k]=’A’ then arg[k]:=’B’;

end;

133

Глава 20 Процедуры: первый опыт

begin { главная программа }

for k:=1 to 3 do begin

Write(’Введите строку: ’); Readln(S);

Scan(S);

Writeln(S);

end;

end.

Теперь совпадение имен локальной и глобальной переменных k не нарушает работу программы, поскольку это разные переменные. Они могли бы иметь даже разные типы! Убедитесь, что отныне путаницы в циклах нет.

Локально – это разумно!

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

Во-первых, они облегчают многотрудную жизнь программиста. Если какие-то объекты нужны только внутри процедуры, их следует объявить там же, то есть как локальные. И тогда не придётся гадать, повлияют ли они на другие части программы.

Другой выигрыш заключается в экономии памяти. Все переменные занимают оперативную память (оперативку). Чем больше переменных, тем больше памяти им подавай. Глобальные переменные занимают память в течение всего времени работы программы. А для локальных память выделяется лишь на время работы соответствующей процедуры или функции. Завершилась подпрограмма — освободилась память.

Неподдающаяся строка

Теперь вновь проверим нашу программу. В ответ на запрос строки введите что-нибудь вроде «QAAAW». Если всё нормально, программа напечатает «QBBBW» (буква «A» заменяется буквой «B»). Не вышло? Что ж, тогда идем «на поклон» к отладчику, — мы сделаем это в следующей главе.

Итоги

Программа упрощается, если вынести части алгоритма в отдельные подпрограммы — процедуры и функции.

Объекты, используемые лишь внутри подпрограмм, следует объявлять там же — как локальные.

Локальные объекты (константы, переменные и прочие) доступны лишь внутри тех подпрограмм, где они объявлены.

134

Глава 20 Процедуры: первый опыт

Если имя локального объекта совпадает с глобальным, то внутри подпрограммы действует локальный объект, а глобальный становится «невидимкой».

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

Аслабо?

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

Б) Создайте процедуру, печатающую все числа, кроме единицы, на которые без остатка делится число N, где N — параметр процедуры. Напишите программу для проверки этой процедуры.

В) Два сотрудника подали своему начальнику заявления на отпуск. Первый попросил отпустить его с A1 по B1 день (дни отсчитываются с начала года), второй

— с A2 по B2 день (полагаем, что A1<B1 и A2<B2). Однако дело требует, чтобы кто-то из сотрудников находился на рабочем месте. Мало того, при смене отдыхающих необходимо не менее 3-х дней их совместной работы — для передачи дел. Напишите программу с процедурой, принимающей четыре указанных выше параметра, и печатающей заключение о том, удовлетворяют ли заявления работников требованиям начальника.

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

∙ Параметр A = true, если горит зеленый;

∙ Параметр B = true, если поблизости опасно движется транспорт; ∙ Параметр C – это число, определяющее характер пешехода так:

1 - послушный и осторожный — учитывает и светофор и опасность; 2 - послушный, но беспечный — смотрит только на светофор;

3 - хитрый вольнодумец — идет только на красный, если это ничем не грозит; 4 - непримиримый вольнодумец — идет только на красный; 5 - экстремал — идет только на красный, и так, чтобы грозила опасность; 6 - «безбашенный» — идет, несмотря ни на что;

7 - запуганный — никогда не идет через дорогу, а ищет подземный переход.

135

Соседние файлы в папке delphi