Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Spec_Mov_3k_4k_Lect.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
1.46 Mб
Скачать

Формы блоков и связывания переменных

Аналогами блоков в Лиспе являются формы prog:

(prog (u1 u2 …uk) s1 s2 … sr),

где ui (i=1-k) - атомы, обозначающие локальные переменные в форме prog или пары атом и инициализирующее выражение, sj (j=1-r) – произвольные выражения Лиспа, обычно имеющие побочный эффект, влияющий на состояние среды вычислений. Форма возвращает в качестве результата значение nil или вычисленное выражение формы return. В Common Lisp имеются формы prog1, prog2 и progn, которые возвращают значение, соответственно, 1-го, 2-го или последнего выражения из последовательности s1 s2 … sr.

Присваивание значений переменным

В современных версиях Лиспа имеется множество различных форм присваивания значений переменным. Рассмотрим следующие основные формы:

  • (set symb val) – вычисляющее присваивание; вычисляются оба выражения аргументов; первое выражение должно возвращать символьное значение,

  • (set {symb val}…) – невычисляющее присваивание; первый аргумент не вычисляется и должен быть символом, второй аргумент может быть произволным выражением, которое вычисляется до выполнения присваивания; пары symb val могут повторяться произвольное число раз,

  • (setf [place expr]...) обобщенная функция присваивания; place может быть символом, головой или хвостом cons-ячейки и т.п. и тогда вычисленное значение выражения expr присваивается символу, заменяет часть car или часть cdr cons-ячейки и т.д.

Пример

(set ‘f ‘(a b c d e f)) -> (a b c d e f) ;; переменная f получает значение (a b c d e f)

(set (car f) ‘(mind in your head)) ;; переменная a получает значение (mind in

;; your head)

(setq f ‘(a b c d e f)) -> (a b c d e f) ;; переменная f получает значение (a b c d e f)

В данной форме нет необходимости блокировать вычисление символа f.

Пример

(setq lst ‘(a b c d)) -> (a b c d) ;; переменная lst получает значение ‘(a b c d)

(setf (car lst) ‘(e f)) -> (e f)

lst -> ((e f) b c d)

В представленном выше примере выполняется замена части car списка, связанного с переменной (символом) lst.

Любой список в Лиспе представлен cons-ячейками! Первая часть ячейки содержит указатель на голову списка, а вторая часть - на хвост списка.

Пример

(setf (cdr lst) ‘(a b c d)) -> (a b c d) ;; lst та же переменная, что и в предыдущем

;; примере

lst -> ((e f) a b c d)

В этом примере выполняется замена части cdr списка, связанного с переменной (символом) lst.

Прочие процедурные формы в Лиспе

К формам, поддерживающим процедурный стиль программирования относятся:

  • (go s) – безусловный переход к метке, в качестве которой используется символ s, размещаемый в формах prog или block,

  • (return [<expr>]) - выход из обрамляющих форм с значением вычисленного выражения expr или со значением nil, если выражение не указано.

Существует, также, множество других процедурных форм, таких как block, progv, tagbody, return-from, do, do* и др. В формах prog и tagbody можно использовать в качестве меток символьные атомы.

Пример

Перепишем с использованием процедурных форм функцию memb, определяющую принадлежность атома х списку y.

(defun memb (x y)

(prog ()

l (if (null y) (return nil)

(if (eq x (car y)) (return T) nil))

(setq y (cdr y)) (go l)) )

Оператор (return nil) завершает форму prog, а nil в форме if необходим для правильной записи формы if и является как бы эквивалентом пустого выражения.

Пример

Обращение списка и его подсписков.

(defun rev(x) (prog (y u) ;;y и u инициализируются значением nil

a (if (null x) (return y) nil)

(setq u (car x))

(setq x (cdr x))

(if (not (atom u)) (setq u (rev u)) nil)

(setq y (cons u y))

(go a))

)

Для ввода/вывода в каждой Лисп-системе имеется множество фунций как для взаимодействия с файлами, так и со стандартными потоками: open, close, read, write, format, print и др.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]