|
||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[75] 0Э параметры: balance тело: (lambda (amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Недостаточно денег на счете")) Рис. 3.6: Результат определения make-withdraw в глобальном окружении. параметры: amount тело: (if (>= balance amount) (begin (set! balance (-balance amount)) balance) "Недостаточно денег на счете")) Рис. 3.7: Результат вычисления (define W1 (make-withdraw 100)). глобальное make-withdraw:... - окружение W1:-, параметры: balance глобальное окружение E1 balance: 100 00- Баланс, который будет изменен операцией set!.. amount: 50 параметры: amount (if (>= balance amount) (begin (set! (balance (- balance amount)) balance "Недостаточно денег на счете")) Рис. 3.8: Окружения, создаваемые при применении процедурного объекта W1. (W1 50) 50 Для начала мы конструируем кадр, в котором amount, формальный параметр W1, связывается со значением 50. Здесь крайне важно заметить, что у этого кадра в качестве объемлющего окружения выступает не глобальное окружение, а E1, поскольку именно на него указывает процедурный объект W1. В этом новом окружении мы вычисляем тело процедуры: (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Недостаточно денег на счете") Получается структура окружений, изображенная на рисунке 3.8. Вычисляемое выражение обращается к переменным amount и balance. Amount находится в первом кадре окружения, а balance мы найдем, проследовав по указателю на объемлющее окружение E1. Когда выполняется set!, связывание переменной balance в E1 изменяется. После завершения вызова W1 значение balance равно 50, а W1 по-прежнему указывает на кадр, который содержит переменную balance. Кадр, содержащий amount (тот, в котором мы выполняли код, изменяющий balance), больше не нужен, поскольку создавший его вызов процедуры закончен, и никаких указателей на этот кадр из других частей окружения нет. В следующий раз, когда мы позовем W1, создастся новый кадр, в котором будет связана переменная amount, и для которого объемлющим окружением снова будет E1. Мы видим, что E1 служит «местом», в котором хранится локальная переменная окружения для процедурного объекта W1. На рисунке 3.9 изображена ситуация после вызова W1. глобальное окружение параметры: amount тело: Рис. 3.9: Окружения после вызова W1. Рассмотрим, что произойдет, когда мы создадим другой объект для «снятия денег», вызвав make-withdraw второй раз: (define W2 (make-withdraw 100)) При этом получается структура окружений, изображенная на рисунке 3.10. Мы видим, что W2 - процедурный объект, то есть пара, содержащая код и окружение. Окружение E2 для W2 было создано во время вызова make-withdraw. Оно содержит кадр со своим собственным связыванием переменной balance. С другой стороны, код у W1 и W2 один и тот же: это код, определяемый lambda-выражением в теле make-withdraw.15 Отсюда мы видим, почему W1 и W2 ведут себя как независимые объекты. Вызовы W1 работают с переменной состояния balance, которая хранится в E1, а вызовы W2 с переменной balance, хранящейся в E2. Таким образом, изменения внутреннего состояния одного объекта не действуют на другой. Упражнение 3.10. В процедуре make-withdraw локальная переменная balance создается в виде параметра make-withdraw. Можно было бы создать локальную переменную и явно, используя let, а именно: (define (make-withdraw initial-amount) (let ((balance initial-amount)) (lambda (amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Недостаточно денег на счете")))) Напомним, что в разделе 1.3.2 говорится, что let всего лишь синтаксический сахар для вызова процедуры: 15Разделяют ли W1 и W2 общий физический код, хранимый в компьютере, или каждый из них хранит собственную копию кода - это деталь реализации. В интерпретаторе, который мы создадим в главе 4, код будет общим. |
Среды: Smalltalk80 MicroCap Local bus Bios Pci 12С ML Микроконтроллеры: Atmel Intel Holtek AVR MSP430 Microchip Книги: Емкостный датчик 500 схем для радиолюбителей часть 2 (4) Структура компьютерных программ Автоматическая коммутация Кондиционирование и вентиляция Ошибки при монтаже Схемы звуковоспроизведения Дроссели для питания Блоки питания Детекторы перемещения Теория электропривода Адаптивное управление Измерение параметров Печатная плата pcad pcb Физика цвета Управлении софтверными проектами Математический аппарат Битовые строки Микроконтроллер nios Команды управления выполнением программы Перехода от ahdl к vhdl Холодный спай Усилители hi-fi Электронные часы Сердечники из распылённого железа Анализ алгоритмов 8-разрядные КМОП Классификация МПК История Устройства автоматики Системы и сети Частотность Справочник микросхем Вторичного электропитания Типы видеомониторов Радиобиблиотека Электронные системы Бесконтекстный язык Управление техническими системами Монтаж печатных плат Работа с коммуникациями Создание библиотечного компонента Нейрокомпьютерная техника Parser Пи-регулятор ч.1 ПИ-регулятор ч.2 Обработка списков Интегральные схемы Шина ISAВ Шина PCI Прикладная криптография Нетематическое: Взрывной автогидролиз Нечеткая логика Бытовые установки (укр) Автоматизация проектирования Сбор и защита Дискретная математика Kb радиостанция Энергетика Ретро: Прием в автомобиле Управление шаговым двигателем Магнитная запись Ремонт микроволновки Дискретные системы часть 2 | ||