Песни о Паскале - страница 42

Шрифт
Интервал

стр.


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

>var S: string; k: integer;


>      {--- Заглушка процедуры –--}

>procedure Scan(arg : string);

>begin

>end;


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

>      for k:=1 to 3 do begin

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

>      Scan(S);

>      Writeln(S);

>      end;

>end.


Процедура Scan принимает строковый параметр arg (это сокращение от слова argument). Аргумент – так ещё называют параметр процедуры или функции. Теперь снова запустите программу. Если все в порядке, значит вызов процедуры Scan(S), как говорят программисты, видит описание этой процедуры, и его фактический параметр S отвечает формальному параметру процедуры arg.

Переходим к третьему этапу, где можно забыть о главной программе и сосредоточиться на теле процедуры 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

>      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. Он – счетчик – используется нами в двух местах: в главной программе и в процедуре. Налицо экономия памяти, не так ли? Насколько оправдана эта надежда? Скоро узнаем.

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

Первые раны

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

Впрочем, если ввести строку из трех символов, программа чудесным образом завершится. Это наводит на размышление, – ведь цикл главной программы тоже считает до трех. Не промахнулись ли мы, доверив переменной 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 «спряталась» внутри своей процедуры и, как говорят программисты, не видна за её пределами.


стр.

Похожие книги