Учебное пособие по дисциплине Разработка языков программирования высокого уровня
Скачать 1.74 Mb.
|
4.6. Механизм реализации моделей передачи параметровОбмен параметрами при реализации описанных режимов и моделей происходит через стек выполняемой программы. Стек выполняемой программы инициализируется и поддерживает системой поддержки выполнения программ. Параметры, передаваемые по значению, копируется в ячейки стека. Эти ячейки затем служат хранилищем для соответствующих формальных параметров. Передача параметров по результату реализуется как противоположность передаче параметров по значению. Значения, присвоенные фактическим параметрам, передаваемым по результату, помещаются в стек, откуда они могут быть извлечены вызывающим программным модулем после завершения работы вызванной подпрограммы. Передача параметров по значению и результату может быть реализована в соответствии со своей семантикой как комбинация передачи по значению и передачи по результату. Ячейка стека инициализируется вызовом и затем пользуется как локальная переменная в вызываемой подпрограмме. Передача параметров по ссылке наиболее проста для реализации. Независимо от типа фактического параметра в стек должен помещаться лишь его адрес. Если параметр является выражением, то компилятор должен построить код для вычисления выражения непосредственно перед передачей управления в вызываемую подпрограмму. Адрес ячейки памяти, в которую код помещает результат своих вычислений, затем записывается в стек. При передаче по ссылке может возникнуть следующая проблема. Допустим, что подпрограмма завершилась аварийно (возникла исключительная ситуация). В этом случае фактический параметр, передаваемый по значению и результату, не изменится, в то время как при передаче параметров по ссылке соответствующий фактический параметр может измениться до появления ошибки. Описанный механизм демонстрирует рисунок 4.4. Рисунок 4.4. Механизм работы стека 4.7. Параметры, являющиеся именами подпрограммЧасто возникают ситуации, когда имена подпрограмм передаются другим подпрограммам. B частности, при передаче в подпрограмму имени математической функции. При этом возникает проблема проверки типов параметров-подпрограмм. Если возможна независимая компиляция (см. ниже), то компилятор не позволяет проверить даже правильность количества параметров. При раздельной компиляции проверка совместимости параметров возможна, но представляет собой крайне сложную задачу и обычно не выполняется. В языке Algol-68 или в позднейших версиях языка Pascal, типы формальных параметров включаются в список формальных параметров, получаемых подпрограммой, так что совместимость типов параметров, передаваемых в подпрограмму можно выполнить статически. В языках С и С++ функции не могут передаваться как параметры, но указатели на функции – могут. Тип указателя на функции определяется её протоколом. Поскольку протокол содержит типы всех параметров, такие параметры, вообще говоря, могут быть полностью проверены на совместимость типов. 4.8. Понятие полиморфизмаПонятие полиморфизма означает, что одно и то же имя может использоваться для логически связанных, но разных целей, т.е. имя определяет набор действий, которые в зависимости от типа данных могут существенно отличаться. Полиморфизм широко используется в императивных языках на уровне знаков операций. Например, привычные нам символы арифметических операций «+», «-», «*», «/» и др. являются перегруженными (их реализация осуществляется в идеологии полиморфизма) в любом ЯПВУ, т.е. один и тот же символ олицетворяет и действие для целого типа, и для вещественного. А в языках С, С++ реализована перегрузка операций <<, >>, которые имеют двоякий смысл - поразрядный сдвиг или вывод на консоль. Когда перегружается знак операции, компилятор анализируют тип операндов и в зависимости от этого делает выбор. Помимо операций в императивном подмножестве языка программирования полиморфизм реализуется также и для определенных видов подпрограмм. Это – перегруженные и настраиваемые подпрограммы. 4.8.1. Перегруженные подпрограммыПерегруженная подпрограмма представляет собой разновидность специального полиморфизма, реализуемого также в статике. Перегруженная подпрограмма - это подпрограмма, имя которой совпадает с именем другой подпрограммы, но при этом каждая версия перегруженной подпрограммы должна иметь свой уникальный протокол, т.е. она должна отличаться от других версий количеством, порядком, типами своих параметров или типом возвращаемого значения, если она является функцией. Ярким примером перегруженных подпрограмм являются подпрограммы (процедуры в Pascal или функции в С) ввода/вывода данных, которые имеют такую значимость в языках программирования, что воспринимаются наряду с остальными операторами языка как обычные команды. Как правило, подпрограммы ввода/вывода являются встроенными в язык. Например, язык Ada имеет несколько версий функции вывода PUT. Наиболее широко используются версии этой функции, принимающие в качестве параметров строку, целое число и числа с плавающей точкой. Поскольку каждая версия функции PUT имеет уникальные типы параметров, компилятор может однозначно различать вызовы функции PUT с различными типами параметров. В языках Ada, Java и C++ пользователи также могут создавать свои перегруженные подпрограммы, т.е. создавать несколько версий подпрограмм с одним и тем же именем. 4.8.2. Настраиваемые подпрограммыНастраиваемые подпрограммы представляет собой динамическую разновидность параметрического полиморфизма. Настраиваемая подпрограмма - это подпрограмма, при каждом вызове которой загружаются фактические значения разных типов, т.е. параметрами здесь являются типы формальных переменных. Изначально типы формальных параметров не определяются, они связываются в динамике с типами фактических значений. Такие подпрограммы позволяют использовать один и тот же алгоритм для данных различных типов. Реализованы в языках Ada, в С и с++ настраиваемые функции называются шаблонные функции или шаблоны. |