Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Непейвода Н.Н. -> "Основания программирования " -> 145

Основания программирования - Непейвода Н.Н.

Непейвода Н.Н., Скопин И.Н. Основания программирования — Институт компьютерных исследований , 2002. — 919 c.
Скачать (прямая ссылка): osnovanprogramm2002.pdf
Предыдущая << 1 .. 139 140 141 142 143 144 < 145 > 146 147 148 149 150 151 .. 316 >> Следующая

14 В Pascal это не так, хотя обратное автоматическое приведение целого к вещественному значению задействовано. Можете считать это способом сделать так, чтобы программист задумался, как нужно преобразовать действительное в целое: округлить или усечь дробную часть?
412
ГЛАВА 8. ПОДПРОГРАММЫ
для С/С++ и для Pascal в данном случае вгладит одинаково.
Пусть приведенныке выше описания погружены в контексты (для каждого языка этот контекст определяется по-своему, но отличия несущественны) с доступными целыми переменными a, b, c и массивом целых чисел M с индексом из интервала 0:3. Прокомментируем различные вызовы процедуры (см. рис. 8.4)
Передача параметра как переменной (короче — параметра-переменной) в Pascal синтаксически оформляется пометкой описания параметра слу-ебнм словом var:
procedure Q (varx : Integer);
Если тело этой процедуры содержит те же операторы, что и P:
begin a := x; x := 1; end; то погружение данного описания в указанный выше контекст позволяет употреблять процедуру, во-первых, для присваивания глобальной переменной a значения некоторой другой переменной, передаваемой процедуре в качестве фактического параметра, а во-вторх, — для здания единицы в качестве значения фактического параметра-переменной. Эта переменная должна иметь целочисленный тип. Таким образом, операторы
Q(23); Q(2 + 2); и Q(u); {u — нецелочисленная переменная}
являются некорректными, но допустимы вызовы, изображеные на рис. 8.5.
Последний оператор на рис. 8.5 заслуживает более пристального внимания. Пусть значения элементов массива M равны 4, 3, 2, 1, а значение переменной a равно 1. Тогда вызов Q(M[a]) корректен, он приведет к следующим действиям. Сначала параметр-переменная x вычислится как M[a], следовательно, как M[1], и именно M[a] будет рассматриваться в качестве фактического параметра. Далее, после входа в подпрограмму выполняется присваивание a значения M[1], т. е. a станет равно 3. аконец, вполняется оператор x:=1 , который присваивает значение 1 переменной с индексом M[1].
а языке С/С++ передача параметра как переменной моделируется с по-моь работ с указателями. Это моделирование будет рассматриваться при обсуждении механизма передачи параметров по ссылке.
Считается, что механизм передачи параметров-переменных реализует inout-параметризаци . днако есть принципиальное расхо дение меду этим механизмом и требованиями к inout-параметрам. inout-параметр является одновременно и входнм, и входнм параметром. ервое требует вкл чения имени формального параметра в локальный контекст процедуры, а второе —
8.5. ПАРАМЕТРИЗАЦИЯ
413
P ( 23 ); { a принимает значение 23, присваиваемое параметру на фазе выполнения алгоритма; другого (вненего для процедуры) эффекта вызов P не дает. }
P ( 23.2 ); {Это верно для языков, в которых предусматривается автоматическое приведение вещественного к целому. Соответственно, в Pascal этот взов оибочен, а в С корректен. a принимает значение 23, которое с точностью до округления выра-батвается так е, как в предыдуем случае. }
P ( b ); { корректно, если значение b до этого оператора было определено (для С/С++ данная оговорка лишена смысла, т. к. язык предусматривает инициализаци значений переменных); значение b не изменяется! }
P ( a ); { корректно, если значение a до этого оператора было определено (см., однако, преддуее замечание); этот взов дает: a = a;}
P ( 2+2 ); { значение выражения 2+2 вычисляется до выполнения операторов тела процедур , т. е. на фазе подготовки выполнения алгоритма. }
P ( M[2] ); { значение выражения M[2] вычисляется на фазе подготовки и присваивается переменной a на фазе выполнения процедуры; значение M[2] не изменяется! }
P ( M[a] ); {Для Pascal вызов корректен при корректности выражения M[a], т. е. при 0 ^ a ^ 3; Для С/С++ вызов корректен всегда, поскольку этот язык не берет на себя заботу о корректности индексации массивов. Эффект — присваивание значения M[a] переменной a; M[a] не изменяется! }
Рис. 8.4. Вызовы процедуры с различными параметрами
414
ГЛАВА 8. ПОДПРОГРАММЫ
Q ( b ); { если значение b до этого оператора определено, то это значение присваивается a, а b присваивается 1}
Q ( a ); { значение, получаемое переменной a, есть 1, оно врабатывается вторым оператором тела процедуры } Переменная с индексом возможна в качестве параметра-переменной:
Q (M[2]); { адрес переменной M[2] вычисляется до вполнения операторов тела процедуры; значение M[2] станет значением переменной a, затем M[2] получит новое значение — 1}
Q (M[a]); { вызов корректен при корректности вычисления адреса переменной M[a], т. е. при 0 ^ a ^ 3; эффект — присваивание значения M[a] переменной a и присваивание значения 1 переменной M[a'], где a' — старое значение a}
Рис. 8.5. Новые возможности вызова при передаче параметра как переменной
выполнения специальных действий по присваивани входнх значений на фазе заверения вполнения процедуры. Что е касается параметров-пе-ременнх, то их передача никак не связана с пополнением локального контекста, а специальные действия по присваивани значений переменнм не предусматриваются. Таким образом, эффект, требуемый inout-параметриза-цией, достигается лиь при последовательных вычислениях, однако при параллельных либо распределенных вчислениях он мо ет наруаться, поскольку нигде не фиксируется момент, когда параметр-переменная получит окончательное значение.
Предыдущая << 1 .. 139 140 141 142 143 144 < 145 > 146 147 148 149 150 151 .. 316 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100