Make your own free website on Tripod.com

יסודות מדעי המחשב. יסודות- 2. מחברים: פרופ' מרדכי בן-ארי, דר' ארנה ליכטנשטיין, חנה מחלב, אלה צור, נורית רייך. צוות הפיתוח: פרופ' מרדכי בן-ארי, דר' דוד גינת, דר' ארנה ליכטנשטיין, חנה מחלב, אלה צור, יפעת קוליקנט, נורית רייך. מהדורה ניסויית, 1998

Основания компьютерных наук. Основания-2. Разработчики: проф. Мордехай Бен-Ари, д-р Давид Гинат, д-р Орна Лихтенштейн, Хана Махлев, Эла Цур, Ифат Куликант, Нурит Райх. Пробное издание, 1998

 

Предисловие

Изучение Оснований компьютерных наук_2 расширяет и углубляет темы и понятия, которые мы изучали в Основаниях _1. Мы добавим много средств для разработки алгоритмов и их реализации в программе на языке Паскаль. Для подготовки к изучению этой книжки рекомендуется вернуться к Основаниям_1, чтобы освежить знания о массивах и функциях. Основными темами изучения являются: (a)использование процедур при решении сложных задач; (b)типы и структуры данных; (c)такие продвинутые алгоритмы, как классификация и слияние; (d)рекурсия. Некоторые главы и параграфы отмечаются как расширение. Они не проверяются на экзаменах на аттестат зрелости(багрут) по Основаниям, но они очень важны при подготовке к продолжению изучения компьютерных наук и в особенности к курсу Программный дизайн.

Сперва разработай алгоритм и только после этого реализуй его на Паскале. Строго следи за правильным написанием и проверкой программы.

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

Внимательно читай эту книжку

ֺКлюч к обозначениям на полях: s - задача; D - алгоритм; - пример; 1 - определение; - законы Паскаля; " - рекомендуемый стиль написания, который не является законом Паскаля.

 

Глава 1. Разложение на задания и процедуры

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

На секунду задумаемся Что отличает существование современного промышленного общества от жизни в прошедшие времена?

В стародавнем обществе люди сеяли и косили траву на корм своей скотине. Они доили коров и делали из молока сыр, а потом ели его с хлебом, который они же пекли в домашней печи. А ты заказываешь пиццу в пиццерии, которая покупает сыр молочного завода, приобретающего молоко у фермера, который кормит коров смесями предприятия, покупающего злаковые, которые доставляются в Страну на пароходах из-за границы. В стародавнем обществе большинство работ человек делал сам. В промышленном обществе производство поделено между множеством предприятий, специализирующихся каждое на ином виде работ. Подобно тому, что мы не требуем от пиццерии производить сыр самостоятельно, так и решая сложные алгоритмические задачи мы хотим сосредоточиться и специализироваться на разработке частичных алгоритмов, составляющих решение задачи в целом. Допустим, ты хочешь разработать компьютерную игру. Нет нужды в том, чтобы всю работу ты сделал сам. Купи операционную систему у одной фирме, графическую библиотеку у другой, программу, которая задействует аудиосистему, в третьей фирме.

В Основаниях _1 требовалось решать задачу при помощи ее деления на подзадания и составления алгоритма до реализации на Паскале. Многие уверены, что это требование излишнее, и что возможно оно верно, когда речь идет о простых алгоритмах. В Основаниях_2 рассматриваются более длинные алгоритмы, и невозможно сесть сразу за компьютер и начать стучать по клавишам. Необходимо пройти предварительный этап планирования решения: деление на задания и описание вычислений без строгого соблюдения синтаксиса

Паскаля. У этой главы две цели:

Упражнения в делении на подзадания больших задач.

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

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

 

1.1. Деление задачи на задания

sРазработай алгоритм строительства дома

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

На секунду задумаемся А для чего нужен алгоритм постройки дома?

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

Отдельные задания из этого списка требуют детализации в виде небольших подзаданий. Например, Подготовка площадки состоит из: Снос старого строения Удаление обломков Вырубка деревьев Выравнивание поверхности Рытье ям под фундаменты

Для других заданий мы можем уже сейчас приступить к написпнию алгоритма:

D Алгоритм настилание_полов_дома

для каждой комнаты дома исполни

настилание_полов_комнаты длиной L и шириной W плитками размером Size

 

D Алгоритм

настилание_полов_комнаты длиной L и шириной W плитками размером Size

для I от 1 до L div Size исполни

для J от 1 до W div Size исполни

положи плитку на место J в ряду I

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

Обрати внимание на то, что в Основаниях_2 мы не строго соблюдаем различие между перечнем подзаданий и написанием алгоритмов подзаданий на псевдокоде. Ты можешь выбирать по необходимости один из двух методов. Вместе с тем мы продолжим настаивать на разработке алгоритмов перед написанием программы Паскаля. Дробление алгоритма будет продолжено до ликвидации сомнений в возможности реализовать его на Паскале.

Вопрос 1.1. Разработай алгоритм возведения стены. Не забудь про окна и двери!

Вопрос 1.2. Разработай алгоритм приведения в действие пиццерии.

 

1.2. Решение задачи черчения цифр

В этом параграфе мы решим алгоритмическую задачу с помощью ее деления на

подзадания и реализации подзаданий процедурами Паскаля. Цель задачи состоит

в представлении цифр в форме, похожей на их вид в дигитальных (цифровых) часах и в калькуляторах: (Рис.) Сформулируем ее в виде алгоритмической задачи,

представляющей требуемый вывод для любого ввода.

sВвод: нечетное целое число больше 3-х

Вывод: цифра 2, а под ней цифра 5. Каждая цифра выводится на экран звездочками в квадрате изображения с длиной стороны, данной на вводе

Ниже дан вывод для ввода 7:

*******

*

*

*******

*

*

*******

 

*******

*

*

*******

*

*

*******

На секунду задумаемся Как приступить к разработке искомого алгоритма?

Начнем деление задачи с ввода переменной Size, хранящей длину стороны квадрата изображения, и с определения двух подзаданий из ее описания.

D Алгоритм НАЧЕРТИ ЦИФРУ 2 И ЦИФРУ 5

введи в Size нечетное число больше 3

НАЧЕРТИ_ЦИФРУ_2_РАЗМЕРОМ Size

НАЧЕРТИ_ЦИФРУ_5_РАЗМЕРОМ_Size

На секунду задумаемся Как чертят цифру?

Чертеж каждой цифры можно описать как монтаж трех следующих форм:

Строка: *******

Левый столбец: *

*

Правый столбец: *

*

Вопрос 1.3. a, b).Сколько форм используется для сборки цифры 2? 5?

Задание начертить цифру 2 или цифру 5 можно разбить на более простые подзадания черчения трех элементов, составляющих эти цифры:

1.начерти_строку_длиной_Width

2.начерти_левый_столбец_длиной_Height

3.начерти_правый_столбец_длиной_ Height _у_края_строк_длиной_Width

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

D Алгоритм НАЧЕРТИ_ЦИФРУ_2_РАЗМЕРОМ Size

начерти_строку_длиной________

начерти_правый_столбец_длиной_____у_края_строк_длиной____

начерти_строку_длиной________

начерти_левый_столбец_длиной_____

начерти_строку_длиной________

На секунду задумаемся Как вычислить число звездочек в каждом отрезке чертежа цифры?

Один простой случай: черчение строки выполняется путем вывода Size звездочек

по строке экрана.

На секунду задумаемся А какова длина каждого столбца на чертеже?

Весь чертеж занимает Size строк, у каждой строки вертикальный размер равен 1, а всего на чертеже 3 строки. Поэтому длина двух столбцов вместе равна (Size-3). Известно, что Size есть число нечетное, поэтому Size-3 - четное, отсюда длина каждого столбца равна (Size-3) div 2 .

В начале параграфа можно видеть изображении цифры 2 для Size = 7. Строка состоит из 7 звездочек, а длина столбца есть (7-3)/2 = 2.

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

D Алгоритм НАЧЕРТИ_ЦИФРУ_2_РАЗМЕРОМ Size

начерти_строку_длиной Size

подставь (Size-3) div 2 в Height

начерти_правый_столбец_длиной Height у_края_строк_длиной Size

начерти_строку_длиной Size

начерти_левый_столбец_длиной Height

начерти_строку_длиной Size

Не будем больше дробить алгоритм, т.к. можно с легкостью реализовать на Паскале каждое подзадание.

Вопрос 1.4. Проследи за выполнением черчения цифры 2 размером 5.

Теперь обратимся к алгоритму подзадания черчение_цифры_5_размером Size .

Обрати внимание на то, что чертеж цифры 5 очень похож на чертеж цифры 2. Разница между ними в том, что у цифры 2 правый столбец появляется перед левым, а у цифры 5 после него. И у цифры 5 столбцы будут той же длины.

Вопрос 1.5. Разработай алгоритм черчения цифры 5 размером Size.

Полный алгоритм решения задачи составляется из первого алгоритма(черчения цифры 2 и цифры 5) сочетанием алгоритмов, разработанных нами для рисования 2 и 5. Обратимся теперь к реализации нашего алгоритма в программе Паскаля.

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

начерти_строку_длиной Size

НАЧЕРТИ_ЦИФРУ_2_РАЗМЕРОМ Size

В Основаниях_1 ты учил, что есть в Паскале функции, вроде trunc, определенные заранее, и еще ты учил, как объявлять самому дополнительные функции. Функция используется как упаковка вычисления, которое возвращает значение. Теперь вместо вычисления значения мы хотим упаковать фрагмент алгоритма. Следующие определения подобны тем определениям, которые ты учил относительно функций.

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

(Слово процедура есть транскрипция английского слова procedure, которое и означает процедуру или процесс). В Паскале существуют и процедуры, определенные заранее(вроде write, read), но можно объявлять дополнительные процедуры.

Ниже идут заголовки процедур DrawLine для черчения строки, DrawLeftCol для черчения левого столбца и DrawRighhtCol для черчения правого столбца. Заголовок содержит объявление имени процедуры, имен параметров и описания входа и выхода.

procedure DrawLine(Length: integer); {На входе: Length > 0}

{На выходе: выводится строка из Length звездочек(*)}

procedure DrawLeftCol(Length: integer); { На входе: Length > 0}

{На выходе: выводится столбец длиной Length звездочек(*)}

procedure DrawRightCol(Length: integer; Space: integer);

{На входе: Lenghth > 0, Space > 0}

{На выходе: выводится столбец из Length * под краем строки из Space *}

 

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

Исполнение обращения DrawLine(6) приведет к выводу строки из 6 звездочек:

******

Исполнение DrawLeftCol(6) приведет к выводу левого столбца длиной 2:

*

*

Исполнение DrawRightCol(6) приведет к выводу правого столбца длиной 2:

*

*

С помощью этих процедур легко реализуется алгоритм черчения цифры 2:

DrawLine(Size);

Height := (Size-3) div 2;

DrawRightCol(Height, Size);

DrawLine(Size);

DrawLeftCol(Height);

DrawLine(Size);

Оператор DrawLine(Size) есть обращение к процедуре DrawLine, т.е. просьба исполнить процедуру DrawLine, когда значение параметра Height есть значение переменной Size. Оператор DrawRightCol(Height, Size) есть обращение к процедуре DrawRightCol, когда значение параметра Length есть значение переменной Height, а значение параметра Space есть значение переменной Size.

Вопрос 1.6. Напиши фрагмент программы черчения цифры 5 размером Size .

Обрати внимание на то, что операторы фрагментов программ черчения 2 и черчения 5 - одинаковые, кроме порядка обращения к прроцедурам.

Теперь посмотрим на декларации процедур DrawLine и DrawRightCol:

procedure DrawLine(Length: integer); {На входе: Length > 0}

{На выходе: выводится строка из Length звездочек(*)}

var I: integer;

begin

for I := 1 to Length do write('*');

writeln

end {DrawLine};

procedure DrawRightCol(Length: integer; Space: integer);

{На входе: Lenghth > 0, Space > 0}

{На выходе: выводится столбец из Length * под краем строки из Space *}

var I: integer;

begin

for I := 1 to Length do writeln('':Space-1,'*');

end {DrawRightCol};

Вопрос 1.7. Напиши объявление процедуры DrawLeftCol .

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

1ПРЕДЛОЖЕНИЕ ВХОДА(На входе) описывает значения параметров.

ПРЕДЛОЖЕНИЕ ВЫХОДА(На выходе) дает результаты выполнения процедуры.

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

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

procedure Draw2(Size: integer); {На входе: нечетное Size > 3}

{На выходе: выводится звездочками цифра 2 в квадрате изображения}

{со стороной из Size позиций}

var Height: integer; {длина левого столбца и правого столбца}

begin

DrawLine(Size);

Height := (Size-3) div 2;

DrawRightCol(Height, Size);

DrawLine(Size);

DrawLeftCol(Height);

DrawLine(Size);

end {Draw2};

Обрати внимание: Height есть локальная переменная процедуры Draw2.

Вопрос 1.8. Напиши процедуру черчения цифры 5

Подконец осталось только реализовать первый алгоритм, который был изложен в начале параграфа. Этот алгоритм мы будем реализовать без использования еще какой-нибудь процедуры, но посредством операторов Паскаля между begin и end.

Принято называть эти операторы главной программой.

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

writeln('Введи целое нечетное число > 3 ');

readln(Size);

Draw2(Size);

Draw5(Size);

end.

Чтобы увидеть решение полностью, представим программу ниже.

program Draw25; {Ввод: вводится нечетное целое число > 3}

{Вывод: выводит на экран звездочками в пределах квадрата изображения}

{со стороной, длина которого дана на вводе, цифру 2, а под ней цифру 5}

var Size: integer; {размер цифры}

procedure DrawLine(Length: integer); {На входе: Length > 0}

{На выходе: выводится строка из Length звездочек(*)}

var I: integer;

begin

for I := 1 to Length do write('*');

writeln

end {DrawLine};

procedure DrawLeftCol(Length: integer); { На входе: Length > 0}

{На выходе: выводится столбец длиной Length звездочек(*)}

var I: integer;

begin

for I := 1 to Length do writeln('*');

end {DrawLeftCol};

procedure DrawRightCol(Length: integer; Space: integer);

{На входе: Lenghth > 0, Space > 0}

{На выходе: выводится столбец из Length * под краем строки из Space *}

var I: integer;

begin

for I := 1 to Length do writeln('':Space-1,'*');

end {DrawRightCol};

procedure Draw2(Size: integer); {На входе: нечетное Size > 3}

{На выходе: выводится звездочками цифра 2 в квадрате изображения}

{со стороной из Size позиций}

var Height: integer; {длина левого столбца и правого столбца}

begin

DrawLine(Size);

Height := (Size-3) div 2;

DrawRightCol(Height, Size);

DrawLine(Size);

DrawLeftCol(Height);

DrawLine(Size);

end {Draw2};

procedure Draw5(Size: integer); { На входе: нечетное Size > 3}

{ На выходе: выводится звездочками цифра 5 в квадрате изображения }

{ со стороной из Size позиций }

var Height: integer; { длина левого столбца и правого столбца }

begin

DrawLine(Size);

Height := (Size-3) div 2;

DrawLeftCol(Height);

DrawLine(Size);

DrawRightCol(Height, Size);

DrawLine(Size);

end {Draw5};

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

writeln('Введи целое нечетное число > 3 ');

readln(Size);

Draw2(Size);

Draw5(Size);

end.

Обрати внимание: процедуры DrawRightCol, DrawLineRight и DrawLeftCol провозглашены в программе до процедур Draw2 и Draw5. Это связано с тем, что процедуру надо объявлять до обращения к ней.

Вопрос 1.9. Измени программу Draw25 так, чтобы она выводила цифры посредством символа, полученного на вводе, вместо постоянного символа *.

Вопрос 1.10. a).Напиши процедуру Draw3 для черчения цифры 3 размером Size. Пусть заголовок этой процедуры будет таким:

procedure Draw3(Size: integer); {На входе: нечетное Size > 3}

{На выходе: выводится звездочками цифра 3 в квадрате изображения}

{со стороной из Size позиций}

b).Напиши процедуру Draw1 для черчения цифры 1 размером Size. Не забывай писать предложения входа и выхода процедуры.

c).Измени программу Draw25 на программу NewDraw2135, которая выведет одну под другой цифры 2, 1, 3, 5 все размером Size.

Вопрос 1.11. a).Из скольки основных форм монтируется цифра 7 и какие они? b).Напиши фрагмент программы для черчения цифры 7 размером Size.

 

1.3.Процедуры Паскаля

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

 

1.3.1.Объявление процедуры

ДЕКЛАРАЦИЯ ПРОЦЕДУРЫ(procedure declaration) появляется в разделе объявлений программы после объявления ее переменных.

Общая структура объявления процедуры на языке Паскаль такова:

procedure имя_процедуры(параметры); {Заголовок}

объявления {Раздел объявлений}

begin

операторы {Исполняемая часть}

end ;

 

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

ЗАГОЛОВОК ПРОЦЕДУРЫ состоит из: слова procedure; имени процедуры идентификатора Паскаля; ПАРАМЕТРОВ и их типов в круглых скобках; можно писать процедуры без параметров.

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

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

procedure DrawRightCol();

end {DrawRightCol};

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

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

procedure Greet; {На выходе: выводятся сообщения приветствия}

У процедуры Equation два вещественных параметра А и В:

procedure Equation(A, B: real);{На входе: А и В коэффициенты уравнения АХ+В=0}

{На выходе: вывод решения уравнения АХ+В=0 согласно значенииям}

{коэффициентов: А <> 0, A = 0 и В = 0, А = 0 и В <> 0}

У процедуры DrawLine один целый параметр:

procedure DrawLine(Length: integer); {На входе: Length > 0}

{На выходе: выводится строка из Length звездочек(*)}

Следом за заголовком идет раздел деклараций процедуры. Эта ее часть предназначена для локальных переменных, а иногда и для процедур и функций, которые процедура использует сама. Раздел деклараций присутствует у процедуры не всегда. Следом за разделом деклараций процедуры идет исполняемая часть или тело процедуры. Оно начинается словом begin и завершается словом end, между которыми находятся операторы языка Паскаль.

У процедуры Greet нет раздела деклараций, а ее исполняемая часть состоит из двух операторов.

procedure Greet; {На выходе: выводятся сообщения приветствия}

begin

writeln(Доброе утро);

writeln(желает тебе твой верный компьютер);

end {Greet};

У процедуры Equation нет раздела объявлений, а исполняемая часть составлена из одного вложенного оператора if.

procedure Equation(A, B: real);{На входе: А и В коэффициенты уравнения АХ+В=0}

{На выходе: вывод решения уравнения АХ+В=0 согласно значенииям}

{коэффициентов: А <> 0, A = 0 и В = 0, А = 0 и В <> 0}

begin

if A <> 0 then writeln(X = , -B/A)

else

if B = 0 then writeln уравнения бесконечное число решений)

else

writeln уравнения нет решения)

end {Equation};

У процедуры DrawLine есть раздел декларраций, объявляющий локальную целую переменную I. Исполняемая часть составлена из оператора for и оператора writeln.

procedure DrawLine(Length: integer); {На входе: Length > 0}

{На выходе: выводится строка из Length звездочек(*)}

var I: integer;

begin

for I := 1 to Length do write('*');

writeln

end {DrawLine};

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

Два следующих заголовка равносильны: procedure Sum(A: real; B: real);

procedure Sum(A, B: real);

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

procedure Example(Letter: char; Digit: integer);

Вопрос 1.12. Относительно процедур DrawLeftCol(вопрос 1.7) и Draw3(вопрос 1.10): a).Какие параметры есть в обеих процедурах? b).Есть ли у этих процедур раздел объявлений? Если да, то каков он? c).Сколько операторов имеется в исполняемой части каждой из процедур?

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

 

1.3.2.Обращение к процедуре

ОПЕРАТОР ОБРАЩЕНИЯ К ПРОЦЕДУРЕ(procedure call) появляется в исполняемой части главной программы(или другой процедуры/функции). Его выполнение приводит к осуществлению операторов процедуры.

Общая структура оператора обращения к процедуре в Паскале такова:

ИМЯ_ПРОЦЕДУРЫ(СПИСОК_ВЫРАЖЕНИЙ);

Списка выражений нет, если у процедуры нет параметров. В примерах, которые перед тобой, представлены операторы обращения к процедурам, чьи объявления мы уже видели: Draw(Size); DrawRightCol(Height, Size-2); Equation(3.5, 4.2); Greet;

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

Вызов процедуры с параметром приводит к : 1).выделению в памяти компьютера ячейки для параметра; 2).вычислению значения выражения, соответствующего параметру; 3).подстановке этого значения в ячейку памяти параметра; 4).выполнению операторов процедуры.

Вопрос 1.14. Опиши, не пользуясь компьютером, вывод программы из илл. 1.1

program OneTwoThree;

var I, N: integer; {размер цифры}

procedure Proc1;

begin

write('Один ')

end {Proc1};

procedure Proc2;

begin

write('Два ')

end {Proc2};

procedure Proc3;

begin

write('Три ')

end {Proc3};

begin

writeln('Введи, сколько раз надо вывести сообщение: ');

readln(N);

for I := 1 to N do

begin Proc1; Proc2; Proc3; writeln end

end.

Иллюстрация 1.1. Упражнение

 

1.3.3.Приведение параметров к соответствию

Необходимо соответствие между заголовком процедуры и оператором ее вызова. Выражения в операторе обращения соответствуют слева направо параметрам заголовка.

Положим, что в главной программе есть объявление var Number: integer;. И также положим, что в ней объявлена процедура Example с таким заголовком:

procedure Example(I: integer; J: integer);

Соответствие оператора вызова Example с описанным заголовком в этой схеме:

procedure Example(I: integer; J: integer);

Example (175, Number);

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

Оператор вызова Example(A, B, C) с тремя выражениями ошибочен.

Тип выражения в операторе вызова процедуры должен быть тождественным типу соответствующего ему параметра.

Для деклараций процедур с заголовками

procedure Example1(I: integer; J: integer); procedure Example1(I: real; J: real);

оператор обращения Example1(8, 4.2); - ошибочен, т.к значение 4.2 вещественного типа, а процедура ожидает для параметра J целое выражение. Но оператор Example2(8, 4.2); - законный: подобно возможности присвоить целое значение вещественной переменной, разрешено задавать целое значение в обращении, предполагающем вещественный параметр.

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

Далее в главе мы изучим и иной вид параметра, который не охватывается этим правилом.

Пусть процедура Rectangle печатает периметр и площадь прямоугольника:

procedure Rectangle(Length, Width: real);

Каждый из следующих операторов обращения к ней законный(Х и У вещественного типа):

Rectangle(7.3, 8.0); Rectangle(X, Y); Rectangle(7.3, X+1.2); Rectangle(7+Y, Y/X); .

НЕТ НЕОБХОДИМОСТИ ПРИВОДИТЬ В СООТВЕТСТВИЕ ИМЕНА ПЕРЕМЕННЫХ В ОПРЕДЕЛЕНИИ ПРОЦЕДУРЫ И В ОБРАЩЕНИИ К НЕЙ. СОТВЕТСТВИЕ УСТАНАВЛИВАЕТСЯ ИСКЛЮЧИТЕЛЬНО ПО МЕСТУ ПАРАМЕТРА.

Каждый из следующих операторов обращения законный для вещественных L, W, Length и Width:

Rectangle(L, W); Rectangle(W, L); Rectangle(Width, Length); Rectangle(Length, Width); .

Вопрос 1.15. Для деклараций

var Val: integer; Low: integer; High: real;

procedure Test(High: integer; Low: real);

установи законность следующих операторов вызова. Если оператор незаконный, объясни почему. a).Test(10.0, 5.0); b).Test(Val, 5.3, 9); c).Test(Val, 1.7*3.0); d).Test(10, 5); e).Test(9); f).Test(Val+3, Val/2); g).Test(Low, High); h).Test(High, Low);.

РЕЗЮМЕ. В обращении к процедуре должно быть по выражению для каждого параметра в ее заголовке. Типы выражения и параметра должны быть одинаковыми(кроме разрешенного случая целого выражения для вещественного параметра).

1.3.4. Сокращенная таблица слежения

До того, как мы займемся таблицей слежения для процедур, опишем способ сокращения таблиц, которыми мы занимались в Основаниях_1. Вместо двух строк для каждого состояния вычислений(значения переменных, вывод и следующий исполняемый оператор) ограничимся одной строкой. Сокращенные таблицы легче в построении, и они позволяют строить таблицы и для больших программ. Например, рассмотрим отрезок программы:

Temp := C;

C := B;

B := A;

A := Temp;

Выполнение этого фрагмента программы приводит к перемещению по кругу значений переменных А, В, С: начальное значение А станет конечным значением

В, начальное значение В станет конечным значением С, и начальное значение С станет конечным значением А. Проверим это посредством таблицы слежения. Пусть начальные значения А, В, С будут, соответственно, 2, 4, 7. Таблица слежения по правилам Оснований_1 будет такой:

Следующий исполняемый оператор

А

В

С

Temp

Temp := C;

2

4

7

?

 

2

4

7

7

C := B;

2

4

7

7

 

2

4

4

7

B := A;

2

4

4

7

 

2

2

4

7

A := Temp;

2

2

4

7

 

7

2

4

7

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

Следующий исполняемый оператор

А

В

С

Temp

Temp := C;

2

4

7

?

C := B;

2

4

7

7

B := A;

2

4

4

7

A := Temp;

2

2

4

7

 

7

2

4

7

 

1.3.5. Таблица слежения для процедур

Построим таблицу слежения за исполнением программы OneColumn:

program OneColumn;

var L, S: integer; {длина колонки звездочек, размер интервала}

procedure DrawRightCol(Length: integer;Space: integer);

{На входе: Lenghth > 0, Space > 0}

{На выходе: вывод столбца из Length * по позиции Space строк}

var I: integer;

begin

for I := 1 to Length do writeln('':Space-1,'*');

end {DrawRightCol};

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

writeln('Введи число строк и позицию столбца ');

readln(L,S);

DrawRightCol(L,S);

writeln('Конец')

end.

Пусть ввод программы будет 3 5 . Таблица слежения начнется строками исполнения главной программы до обращения к процедуре:

След. исполн. оператор

L

S

Вывод

Writeln('Введи ');

?

?

Readln(L,S);

?

?

Введи

DrawRightCol(L,S);

3

5

На секунду задумаемся Что происходит при обращении к процедуре и как следить за ее исполнением?

Способ подобен тому, который ты изучал для построения таблицы слежения за

исполнением функции. На входе в процедуру DrawRightCol мы нуждаемся в двух новых ячейках памяти для параметров Length и Space, и еще в ячейке для локальной переменной I. Компьютер выделяет их и копирует в них значения параметров из обращения(S и L). Начальное значение локальной переменной I не

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

След. исполнимый оператор

L

S

 

 

 

Вывод

Writeln('Введи ');

?

?

 

 

 

Readln(L,S);

?

?

 

 

 

Введи

DrawRightCol(L,S);

3

5

 

 

 

 

 

 

Length

Space

I

 

For I :=

3

5

3

5

?

 

Writeln();

3

5

3

5

1

 

Writeln();

3

5

3

5

2

*

Writeln();

3

5

3

5

3

*

 

3

5

3

5

?

*

На секунду задумаемся Что происходит по завершении исполнения последнего оператора процедуры?

Исполнение главной программы OneColumn продолжается, выполняется оператор writeln('Конец'), следующий за обращением к процедуре. По завершению исполнения процедуры параметры Length и Space и локальная переменная I завершили исполнение своих ролей, поэтому их столбцы исчезают из таблицы. Обрати внимание на то, что главная программа не имеет отношения к значениям параметров и локальных переменных процедуры. Полная таблица слежения за исполнением программы OneColumn для ввода 3 5 будет такой:

След. исполн. оператор

L

S

 

 

 

Вывод

Writeln('Введи ');

?

?

 

 

 

Readln(L,S);

?

?

 

 

 

Введи

DrawRightCol(L,S);

3

5

 

 

 

 

 

 

Length

Space

I

 

For I :=

3

5

3

5

?

 

Writeln();

3

5

3

5

1

 

Writeln();

3

5

3

5

2

*

Writeln();

3

5

3

5

3

*

 

3

5

3

5

?

*

Writeln('Конец')

3

5

 

 

 

 

 

3

5

 

 

 

Конец

 

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

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

 

1.3.6.Упражнения

ПРОГРАММА БЕЗ ПРОЦЕДУР НЕ БУДЕТ ПРИНЯТА! Построй таблицу слежения хотя бы за одним обращением к каждой процедуре.

Вопрос 1.16. Разработай и реализуй алгоритм, на вводе которого двузначное число N, а на выводе три числа, получающиеся при перемене местами цифр чисел N-1, N и N+1. Например, для ввода 36 три числа вывода будут 53 63 73, они получаются переменой цифр у чисел 35 36 37.

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

abc acb bac bca cab cba

abd adb bad bda dab dba

acd adc cad cda dac dca

bcd bdc cbd cdb dbc dcb

Вопрос 1.18. Разработай и реализуй алгоритм, на вводе которого целое положительное число N и последовательность букв длиной N, а вывод последовательность этих букв, закодированных согласно следующим правилам: каждая буква, находящаяся на нечетном месте в последовательности кодируется

следующей за ней буквой АВС(abc), а буквы, находящиеся на нечетном месте последовательности, кодируются предыдущей буквой алфавита(буквы Z, z меняются с А, а, соответственно). Пример, для ввода 4 azqq буквы а и первая q шифруются следующими за ними буквами b и r, соответственно. z и вторая q шифруются предыдущими буквами у и р. Вывод будет byrp.

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

Вопрос 1.20. Разработай и реализуй алгоритм решения квадратного уравнения. Воспользуйся процедурой Equation из этого параграфа.

Вопрос 1.21. Разработай и реализуй алгоритм, на вводе которого размер стороны квадратной плитки в см, число комнат и для каждой комнаты ее длина и ширина в метрах, а на выводе - число плиток, нужное для настилания пола в каждой из них. Например, для ввода 30 2 3.0 1.5 6.0 3.0 вывод будет 50 200. Площадь первой комнаты равна 4.5 кв.м., а площадь плитки 0.09 м.кв., поэтому для первой комнаты требуется 4.5/0.09 = 50 плиток. Иной путь вычислений использовать кв.см.!

1.4.Решение задачи определения призеров по результативности

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

На секунду задумаемся Можно ли ограничиться параметрами-значениями?

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

sПо завершении баскетбольного матча между Апоэль Ям-Амелах и Маккаби Ям-Амелах спортивные журналисты решили учредить приз для команды с наиболее высоким средним количеством очков и еще один приз для команды, игрок которой набрал наибольшее количество очков. При равенстве средних результатов или наибольшего числа очков у обеих команд соответствующий приз не вручается. Разработай и реализуй алгоритм, который выводит на экран имена команд, удостоившихся призов.

Ввод. Последовательности целых чисел, которые представляют собой количество очков, набранных игроками Маккаби, а затем игроками Апоэля. Каждая последовательность завершается постовым -1.

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

--***--

Dвведи_последовательность_очков Маккаби и_вычисли_среднее_и_максимум

введи_последовательность_очков Апоэля и_вычисли_среднее_и_максимум

сравни средние и выдай сообщение

сравни максимальные результаты и выдай сообщение

Реализуем два первых подзадания как процедуру, к которой будем обращаться дважды. Назовем процедуру CheckPoints, а ее параметрами будут Max и Avg. Заголовок процедуры:

procedure CheckPoints(var Max: integer; var Avg: real);

{На входе: с клавиатуры вводит до постового -1 список очков}

{На выходе: возвращает в Avg средний и в Max лучший результаты списка}

Использование параметров Max и Avg отличается от того, что мы видели до сих пор. Нам неинтересны значения, которые находятся в этих параметрах в момент обращения к процедуре, но по ее завершению параметры возвращают значения в вызывающую программу, чтобы использовать их для определения призеров. В действительности начальные значения этих параметров не имеют никакого значения. Мы объявляем два этих параметра как параметры-переменные, вместо параметров-значений. Резервированное слово var, стоящее перед объявлением параметра, и обозначает, что это параметр-переменная.

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

В главной программе объявим переменные и будем с ними обращаться к процедуре:

var MaxMaccabi, MaxHaPoel: integer; {максимальные результат в командах}

AvgMaccabi, AvgHaPoel: real; {средние результаты команд}

CheckPoints(MaxMaccabi, AvgMaccabi);

CheckPoints(MaxHaPoel, AvgHaPoel);

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

Вопрос 1.22. a).Каковы начальные значения параметров MaxMaccabi и AvgMaccabi на входе в процедуру? b).Почему(в оригинале) не описано предложение

входа в процедуру CheckPoint?

Полная программа дана на илл. 1.2.(Программа определения призеров)

program ComparePoint;

{Ввод: две последовательности очков, в конце каждой постовой -1}

{Вывод: имена команд, выигравших приз по среднему и лучшему результатам}

var MaxMaccabi, MaxHaPoel: integer; {максимальные результат в командах}

AvgMaccabi, AvgHaPoel: real; {средние результаты команд}

procedure CheckPoints(var Max: integer; var Avg: real);

{На входе: с клавиатуры вводит до постового -1 список очков}

{На выходе: возвращает в Avg средний и в Max лучший результаты списка}

var Count: integer; {счетчик игроков}

Sum: integer; {накопитель очков}

Points: integer; {переменная ввода}

begin

Max := 0; Sum := 0; Count := 0;

read(Points);

while Points >= 0 do

begin

Sum := Sum + Points; Count := Count + 1;

if Points > Max then Max := Points;

read(Points);

end;

if Count > 0 then Avg := Sum/Count

else Avg := 0.0;

end {CheckPoints};

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

writeln('Введи список очков Маккаби ');

CheckPoints(MaxMaccabi, AvgMaccabi);

writeln(' Введи список очков Апоэля ');

CheckPoints(MaxHaPoel, AvgHaPoel);

write('Приз за наилучший личный результат ');

if MaxMaccabi < MaxHaPoel then writeln(' выиграла Апоэль')

else if MaxMaccabi > MaxHaPoel then writeln(' выиграла Маккаби')

else writeln(' не выиграл никто');

write(' Приз за наилучший личный результат ');

if AvgMaccabi < AvgHaPoel then writeln(' выиграла Апоэль')

else if AvgMaccabi > AvgHaPoel then writeln(' выиграла Маккаби')

else writeln(' не выиграл никто');

end.

Фрагмент таблицы слежения за программой приведен ниже. Внимательно рассмотри ее после изучения в следующем параграфе таблиц слежения за процедурами с параметрами-переменными.

Следующий оператор

MaxM

AvgM

MaxHP

AvgHp

 

 

 

Check(MaxM, AvgM);

?

?

?

?

 

 

 

 

Max

Avg

 

 

Cnt

Sum

Pnts

Max := 0;

?

?

?

?

?

?

?

Sum := 0;

0

Count := 0;

0

.

0

 

34

15

?

?

8

120

-1

 

MaxM

AvgM

MaxHP

AvgHp

 

 

 

Check(MaxHP, AvgHP);

34

15

?

?

 

 

 

 

 

 

Max

Avg

Cnt

Sum

Pnts

 

34

15

?

?

?

?

?

 

34

15

49

14.6

7

95

-1

 

MaxM

AvgM

MaxHP

AvgHp

 

 

 

 

34

15

49

14.6

 

 

 

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

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

1.5.Параметры-переменные

1.5.1. Объявление процедуры с параметрами-переменными

В определении параметра-переменной до его имени должно появиться слово var. Без этого слова объявлен будет параметр-значение.

В процедуре CheckPoints два-параметра-переменных: Avg вещественного типа и Max целого типа. Примечание. Выбор слова var намекает на связь параметра с переменной в обращении.

Рассмотрим декларацию процедуры Swap. У этой процедуры два параметра-переменных вещественного типа Х и У.

procedure Swap(var X: real; var Y: real);

{На входе: начальные значения параметров Х и У}

{На выходе: процедура меняет местами значения перрременных Х и У}

var Temp: real;

begin

Temp := X;

X := Y;

Y := Temp;

end {Swap};

Вопрос 1.23. Почему мы воспользовались параметрами-перременными в процедуре Swap?

1 ТИП параметра какого он типа: целого, символьного и т.п. ВИД параметра является ли он параметром-значением или параметром-переменной.

 

Если несколько параметров одного ТИПА объявляют вместе, они должны быть одного ВИДА: параметрами-переменными, если слово var идет перед ними, а иначе параметрами-значениями.

Два первых из следующих заголовков равносильны, т.к. у обоих два параметра-переменных. Третий заголовок иной, в нем второй есть параметр-значение. Четвертый заголовок объявляет два параметра-значения.

procedure Swap(var X: real; var Y: real); {эта декларация равносильна следующей}

procedure Swap(var X, Y: real);

procedure Swap(var X: real; Y: real); {У параметр-значение, Х параметр-перемен.}

procedure Swap(X, Y: real); {Оба параметры-значения}

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

Вопрос 1.24. Оцени каждое из следующих обращений законное оно или нет. Если нет кратко аргументируй. a).Swap(A1,B1); b).Swap(A1,B1,C1); c).Swap(A1,5);

Вопрос 1.25. Рассмотри процедуру Order и ответь на следующие вопросы.

procedure Order(var X: real; var Y: real);

begin

if X > Y then Swap(X, Y)

end {Order};

a).Какого типа параметры этой процедуры?

b).Какого они вида: параметры-значения или параметры-переменные?

Вопрос 1.26. Дана следующая пррограмма:

program Strange;

var I, J: integer;

procedure Swap();

var Temp: integer;

begin

Temp := X; X := Y; Y := Temp;

end {Swap};

 

begin

I := 10; J := 3;

Swap(I, J);

writeln(I,J:3)

end.

Дополни заголовок процедуры Swap так, чтобы вывод получился 10 10.

 

1.5.2.Обращение к процедурам с параметрами-переменными

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

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

Обращение Swap(5, X+1) незаконно, т.к. оба параметра в декларации Swap есть параметры-переменные, а обращаться к процедуре с постоянными или выражениями в качестве параметров - запрещено.

На секунду задумаемся В чем причина такого правила?

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

На секунду задумаемся Как выполняется оператор обращения к процедуре с параметрами-переменными?

Обращение к процедуре приводит к исполнению ее операторов, которые принимают переменную, заданную в соответствующем месте обращения, в качестве параметра-переменной. Иными словами: параметр-переменная есть ЕЩЕ ОДНО ИМЯ переменной из обращения к процедуре.

 

1.5.3.Таблица слежения за параметрами-переменными

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

A := 3.0; B := 4.5; Swap(A, B); writeln(A, B);

A := 2*A; B := B 1; writeln(A, B); swap(A, B); writeln(A, B);

Построим таблицу слежения поэтапно, сначала до первого обращения к процедуре Swap.

Следующий исполняемый оператор

А

В

 

Вывод

A := 3.0;

?

?

 

 

B := 4.5;

3.0

?

 

 

Swap(A, B);

3.0

4.5

 

 

На секунду задумаемся Что происходит во время исполнения оператора Swap(A, B)?

Компьютер приводит в соответствие обращение к процедуре и ее заголовок. В заголове есть два параметра-переменных Х и У. Поэтому исполнение оператора обращения Swap(A, B) приведет к осуществлению процедуры, когда параметру Х соответствует переменная А, а параметру У переменная В. Иными словами во время исполнения нашей процедуры у переменной А есть еще одно имя Х, а у переменной В есть дополнитьельное имя У. Переменная Temp описана в разделе объявлений процедуры, поэтому во время исполнения операторов процедуры и для нее будет выделена ячейка памяти. Ниже приведена таблица слежения вплоть до исполнения последнего оператора процедуры. Обрати внимание на то, что параметры-переменные не требуют новых столбцов в таблице, а приводят к дополнительному имени в существующем столбце. Итак, любое изменение значения параметра-переменной будет сохранено и после обращения к процедуре.

Следующий исполняемый оператор

А

В

 

Вывод

A := 3.0;

?

?

 

 

B := 4.5;

3.0

?

 

 

Swap(A, B);

3.0

4.5

 

 

 

Х

У

Temp

 

Temp := X;

3.0

4.5

?

 

X := Y;

3.0

4.5

3.0

 

Y := Temp;

4.5

4.5

3.0

 

 

4.5

3.0

3.0

 

На секунду задумаемся Что происходит по завершении исполнения последнего оператора процедуры?

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

Следующий исполняемый оператор

А

В

 

Вывод

A := 3.0;

?

?

 

 

B := 4.5;

3.0

?

 

 

Swap(A, B);

3.0

4.5

 

 

 

Х

У

Temp

 

Temp := X;

3.0

4.5

?

 

X := Y;

3.0

4.5

3.0

 

Y := Temp;

4.5

4.5

3.0

 

 

4.5

3.0

3.0

 

 

А

В

 

 

Writeln(A, B);

4.5

3.0

 

 

A := 2*A;

4.5

3.0

 

4.5 3.0

B := B 1;

9.0

3.0

 

 

Writeln(A, B);

9.0

2.0

 

 

Swap(A, B);

9.0

2.0

 

9.0 2.0

 

Х

У

Temp

 

Temp := X;

9.0

2.0

?

 

X := Y;

9.0

2.0

9.0

 

Y := Temp;

2.0

2.0

9.0

 

 

2.0

9.0

9.0

 

 

А

В

 

 

Writeln(A, B);

2.0

9.0

 

 

2.0

9.0

 

2.0 9.0

Обрати внимание на изменение значения переменной в обращении к процедуре. Перед исполнением первого оператора Swap(A, B) значение А было 3.0, а после его исполнения значение А стало равным 4.5.

Вопрос 1.27. Какие значения у параметров А и В до и после второго исполнения оператора Swap(A, B)?

 

1.5.4.Сравнение параметра-переменной с параметром-значением

На секунду задумаемся Когда следует использовать параметр-значение, k