Песни о Паскале
Шрифт:
Впрочем, если ввести строку из трех символов, программа чудесным образом завершится. Это наводит на размышление, – ведь цикл главной программы тоже считает до трех. Не промахнулись ли мы, доверив переменной k «служить двум господам», работая в двух циклах? Ведь внутри процедуры значение счетчика k изменяется, что нарушает работу цикла в главной программе. И лишь когда счетчик случайно станет равен трем, программа завершается.
Как исправить ошибку? Объявить для счетчика внутреннего цикла переменную с другим именем? Да, можно. Но я воспользуюсь
Глобальные и локальные
Процедуры и функции не зря называют подпрограммами. Так же, как в главной программе, внутри подпрограмм можно объявлять свои собственные константы и переменные, – их называют локальными, то есть местными. А всё, что объявлено за пределами подпрограмм, называют глобальным, или всеобщим. Рассмотрим механизм действия локальных объектов и связанные с этим выгоды, для чего исследуем следующую программу.
const c1 = ’Глобальная’;
procedure Local;
begin
Writeln(c1);
end;
begin {--- главная программа ---}
Local;
Writeln(c1);
Readln;
end.
Очевидно, программа дважды напечатает константу C1, – проверьте меня. Теперь добавим объявление локальной константы с тем же именем C1, поместив его между заголовком процедуры Local и её телом. К совпадающим именам я прибегнул не от бедности фантазии, – мой умысел скоро прояснится.
const c1 = ’Глобальная’;
procedure Local;
const c1 = ’Локальная’;
begin
Writeln(c1);
end;
begin {--- главная программа ---}
Local;
Writeln(c1);
Readln;
end.
Известно, что компилятор не допускает совпадающих имен, но здесь – иное дело. Локальная константа 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;
begin { главная программа }
for k:=1 to 3 do begin
Write(’Введите строку: ’); Readln(S);
Scan(S);
Writeln(S);
end;
end.
Теперь совпадение имен локальной и глобальной переменных k не нарушает работу программы, поскольку это разные переменные. Они могли бы иметь даже разные типы! Убедитесь, что отныне путаницы в циклах нет.
Локально – это разумно!
Локальные объекты – константы, переменные и прочие – отличное средство для разумного распределения данных в пространстве вашей программы.
Во-первых, они облегчают многотрудную жизнь программиста. Если некоторые объекты нужны только внутри процедуры, их следует объявить там же, то есть как локальные. И тогда не придется гадать, повлияют ли они на другие части программы.
Другой выигрыш заключается в экономии памяти. Все переменные занимают оперативную память («оперативку»). Чем больше переменных, тем больше памяти им подавай. Глобальные переменные занимают память в течение всего времени работы программы. А для локальных память выделяется лишь на время работы соответствующей процедуры или функции. Завершилась подпрограмма – освободилась память.
Неподдающаяся строка
Теперь вновь проверим нашу программу. В ответ на запрос строки введите что-нибудь вроде «QAAAW». Если все нормально, программа напечатает «QBBBW» (буква «A» заменяется буквой «B»). Не вышло? Что ж, тогда идем «на поклон» к отладчику, – мы сделаем это в следующей главе.
Итоги
• Программа упрощается, если вынести части алгоритма в отдельные подпрограммы — процедуры и функции.
• Объекты, используемые лишь внутри подпрограмм, следует объявлять там же, – как локальные.
• Локальные объекты (константы, переменные и прочие) видны, то есть доступны, лишь внутри тех подпрограмм, где они объявлены.
• Если имя локального объекта совпадает с глобальным, то внутри подпрограммы действует локальный объект, а глобальный делается «невидимкой».
• Локальные объекты упрощают программирование, придают программам надежность и экономят оперативную память.
А слабо?