Р.У. Себеста - Основные копцепции языков программирования (2001) (1160794), страница 93
Текст из файла (страница 93)
Сначала мы сосредоточимся на основных семантических моделях передачи параметров. Затем обсудим различные средства реализации, изобретенные разработчиками языка для этих семантических моделей. Далее мы сделаем обзор проектных решений для различных императивных языков и рассмотрим реальные методы воплощения моделей реализации. В заключение мы рассмотрим вопросы разработки, встающие перед разработчиком языка при выборе метода передачи параметров.
8.5.1. Семантические модели передачи лар аметров Формальные параметры характеризуются одной из трех различных семантических моделей: 1) они могут получать данные от соответствующих фактических параметров; 2) они могут передавать данные фактическим параметрам; 3) они могут делать и то, и другое. Эти три семантические модели были названы режимом ввода (гп воде), режимом вывода (ош шог(е) и режимом ввода-вывода (!пош тоде). соответственно. Существуют две концептуальные модели передачи данных при передаче параметров: либо фактическое значение физически перемещается (в вызывающий модуль, в вызываемый модуль или в обоих направлениях), либо передается путь доступа к ней. Чаше всего путь доступа представляет собой обычный указатель. На рис.
8.1 показаны три семантические модели передачи параметров с использованием физического перемещения. 354 Глава 8. Подпрограммы Ввеыватцнй модуль (ЗОЬ ~а, Ь, т ) Вызветнвв яодярвгрзымз (ргооооого ЗОЬ (х, у, М) рохин ввоав Возврат ВЫЗОВ Рис. 8.1. Три семантические модели передачи параметров с испачьэаваниеы физического перемен(ения 8.5.2. Модели реализации передачи параметров Разработчиками языков программирования было создано великое множество моделей :-: описания реализации трех основных режимов передачи параметров. В следующем : пледе мы обсудим некоторые из ннх и оценим их достоинства и недостатки. В.5.2.1. Передача по значению Когда параметр передается по значению (раиед Ьу ча)це), значение фактического . =:зметра используется лля инициализации соответствующего формального параметра, ° .
-Орый в дальнейшем действует как локальная переменная в подпрограмме, реализуя - ы им образом семантику режима ввода. Передача по значению обычно реализуется путем реальной передачи данных, ног:льву доступ к ннм с помощью именно этого метода более эффективен. Эта передача -." ке может быть реализована с помощью передачи пути доступа к значению фактиче:;о параметра в вызывающем модуле, однако при этом может потребоваться, чтобы : -зчение хранилось в ячейке памяти, защищенной от записи (доступной только лля чте- ° ь Защита ячейки памяти от записи не всегда является легким делом.
Предположим, - -: полпрограмма, в которую передается параметр, в свою очередь передает его в дру- -. подпрограмму. Это — вторая причина использования физической передачи. Как мы з и-нм в разделе 8.5.3, язык С++ предоставляет удобный и эффективный метод зашиты - записи параметров. которые передаются с помощью передачи пути доступа к ним. Основной недостаток метода передачи по значению на основе физических перемеще- л данных заключается в том, что для хранения формального параметра требуется до-:лннтельная память либо в вызываемой подпрограмме, либо в некоторой области вне гг:ывающего модуля и вызываемой подпрограммы.
Кроме того, фактический параметр "лжен физически перемешаться в область памяти, отведенную для хранения формаль- 355 5. Методы передачи параметров ного параметра. Объем памяти и операции перемещения могут быть дорогостоящими, если параметр имеет большой размер, как, например, длинный массив данных. 8.5.2.2. Передача ло результату Передача по результату (разя-Ьу-ча1це) представляет собой модель реализации режима вывода. Когда параметр передается по результату, никакое значение в подпрограмму не передается. Соответствующий формальный параметр действует как локальная переменная, но непосредственно перед возвращением управления обратно в вызывающий модуль его значение передается фактическому параметру, который лолжен представлять собой переменную.
(Каким образом в вызывающем модуле можно было бы ссылаться на вычисленный результат, если бы он был литералом или выражением".) Если возвращается значение (а не путь доступа к нему), как это обычно происходит, передача по результату также требует дополнительной памяти и операций копирования, необходимых лля передачи по значению. Как и при передаче по значению, трудности реализации передачи по результату с помощью передачи пути доступа к данным обычно приводят к тому, что она реализуется на основе физического перемещения данных.
В этом случае необходимо гарантировать, что первоначальное значение фактического параметра ие используется в вызывающем модуле. Одна из проблем, связанных с моделью передачи по результату, состоит в том, что может возникнуть коллизия фактических параметров, как в следующем примере: вцЬ(р1, р1) В подпрограмме асЬ двум ее формальным параметрам, очевидно.
можно присвоить два разных значения, предполагая. что они имеют разные имена. Если какой-либо из формальных параметров присваивается соответствующему фактическому параметру, это значение присваивается переменной р1. Таким образом, порядок присваивания определяет значения фактических параметров. Поскольку этот порялок обычно зависит от вида реализации, может возникнуть проблема мобильности.
которую трудно обнаружить. Вызов процедуры с двумя идентичными параметрами может привести также к различным проблемам и при использовании других методов перелачи параметров, как показано в разделе 8.5.2.4. Другая проблема, которая может возникнуть при передаче по результату, заключается в том, что разработчик средств реализации языка должен слелать выбор. когда именно вычислять адрес фактического параметра: во время вызова подпрограммы или при возвращении из нее. Предположим.
что подпрограмма имеет параметр 11вГ [1паех]. Если переменная 1пс)ех изменяется подпрограммой либо через глобальный доступ, либо как формальный параметр, то адрес переменной 11яс (' пс)ех] изменится в промежутке между вызовом и возвращением из подпрограммы. Разработчик средств реализации языка должен выбрать, когда именно определяется адрес ячейки памяти. в которую должно быть возвращено значение: в момент вызова подпрограммы или в момент возвращения из подпрограммы. Это делает невозможным перенос программы между различными реализациями языка, в которых сделан разный выбор этого момента времени. 8.5.2.3.
Передача ло зиаченню и результату Передача по значению и результату (разя-Ьу-ча!ие-гезц11) представляет собой модель реализации режима ввода-вывода, в котором фактические значения физически перемещаются. В действительности эта модель представляет собой комбинацию передачи 356 Глава 8. Подпрограммы -. значению и перелачи по результату. Значение фактического параметра используется -я инициализации соответствующего фактического параметра, который затем действует з' локальная переменная. Фактически.
при передаче по значению и результату фар° зьные параметры должны храниться в локальной области памяти, связанной с вызы- "мой подпрограммой. При завершении выполнения подпрограммы значение формазь-: -о параметра передается обратно факгическому параметру. Передача по значению и результату иногда называется передачей по копии. поскольфактический параметр вначале копируется в формальный параметр в точке входа в - .
зпрограмму, а затем — при ее завершении. Недостаток передачи по значению и результату. как и передачи по значению и пере: -»л по результату, рассмотренных отдельно, заключается в необходимости хранить па. четры в нескольких местах и тратить время на копирование их значений. Как н пере:ча по результату, передача по значению и результату имеет проблемы, связанные с по: ==ком присваивания значений фактическим параметрам.
В.5.2.4. Йередеча ло ссылке Передача по ссылке (раза-Ьу-гегегепсе) — это вторая модель реализации режима ввоз-вывода. Вместо того, чтобы передавать данные туда и обратно, как при передаче по зна.:нию и результату, метод передачи по ссылке передает путь доступа к данным (обычно— -г.кто адрес) в вызываемую подпрограмму.
Это открывает доступ к ячейке памяти. хра-:.лей фактический параметр. Таким образом, вызываемая подпрограмма может получить ::;туп к фактическому параметру в вызывающем программном модуле. В действительно- .-,. фактический параметр используется совместно с вызываемой подпрограммой. Преимушество передачи по ссылке состоит в том.
что процесс передачи эффективен .:ч по себе с точки зрения как времени, так и пространства. Не требуется ни тнражиро. :з-ь память, ни копировать что-либо. Однако у метода передачи по ссылке есть несколько недостатков. Во-первых, очень :". оятно, что доступ к формальным параметрам будет медленнее, поскольку необходим е один уровень косвенной адресации при передаче данных, как и прн передаче по зна-:нию и результату. Во-вторых, если требуется только односторонняя связь с вызывае. й подпрограммой, то могут возникнуть неумышленные и ошибочные изменения фак- ческого параметра.
Другая серьезная проблема, связанная с передачей по ссылке, заключается в том, что : тг возникнуть альтернативные имена (айазез). Этого следовало ожидать. поскольку пеге=ача по ссылке открывает вызываемой подпрограмме пути доступа к данным, расширяя -еч самым ее доступ к глобальным переменным. Существует несколько ситуаций, в кото-. кх при передаче параметров по ссылке могут образоваться альтернативные имена. Во-первых, может возникнуть противоречие между фактическими параметрами.
Рас." отрим прототип процедуры-функции на языке С, имеющей два параметра. которые -еэедаотся по ссылке: чоЫ тип(йпв ~Г1гэг, Дае *весопс)) елположим, что при вызове функции 1ип одна и та же переменная передается дваж.ы. как показано ниже: ип(ьсоса1, ьсоса1)г :леловательно ййгвк и весопс) будут альтернативными именами. 3.5. Методы пврвдачи параметров 357 Противоречия межа) элементами массива также могут привести к возникновению альтернативных имен. Допустим.
что функция Гоп вызывается с двумя элементами массива, указанными с помощью переменных индексов, как показано ниже: бои (61 Бс Г1], а113с [3] ) Если окажется. что 1 равно з, то 11гвс и весопс[ снова будут альтернативными именами. Противоречия между параметрами, являющимися элементами массива, и элементами массива, передаваемыми через имя массива, также являются возможной причиной появления альтернативных имен. Рассмотрим случай, когда два формальных параметра подпрограммы являются скалярной величиной и массивом элементов того же типа: топ] (Л1 вг [л], Л11аг.) г Такой вызов может вызвать совмещение имен в функции бцп1, поскольку функция : п1 имеет доступ ко всем элементам массива 11ас через второй параметр и доступ к отдельным элементам этого массива через первый параметр. Кроме того. совместить имена при передаче параметров по ссылке можно с помощью противоречий между формальными параметрами и глобальными переменными, которые являются видимыми в подпрограмме.