Опубликован: 21.08.2007 | Доступ: свободный | Студентов: 1622 / 143 | Оценка: 4.23 / 3.74 | Длительность: 15:37:00
Лекция 8:

Стандартное (системное) программирование

< Лекция 7 || Лекция 8: 12 || Лекция 9 >
Аннотация: В данной лекции рассматривается системное программирование. Предлагается анализ ограничений на структуры управления и информационные потоки при обработке данных. Приведено обоснование дисциплины программирования на стандартных императивно-процедурных языках. Отмечена проблема сопряжения программ, подготовленных на разных языках. Обсуждены достоинства структурного программирования, повышающего сходимость процесса отладки программ. Приведены примеры программного кода на языках системного программирования

Рассматривается наиболее известная парадигма программирования. Предлагается анализ ограничений на структуры управления и информационные потоки при обработке данных. Приведено обоснование дисциплины программирования на стандартных императивно-процедурных языках. Отмечена проблема сопряжения программ, подготовленных на разных языках. Методы расширения функциональных построений применены для моделирования привычного операторно-процедурного стиля программирования и техники работы с глобальными определениями. Обсуждены достоинства структурного программирования, повышающего сходимость процесса отладки программ [ [ 11 ] , [ 70 ] ].

Существует большое число чисто теоретических работ, исследовавших соотношения между потенциалом функционального и императивно-процедурного подхода к записи программ, пришедших к заключению о формальной сводимости в обе стороны при непринципиальных ограничениях на средства программирования. На практике переложить функциональные программы в императивные проще, чем наоборот - может не хватать широты понятий.

Любые конструкции стандартных языков программирования могут быть введены как функции, дополняющие исходную систему функционального программирования, что делает их вполне легальными средствами в рамках функционального подхода. Надо лишь четко уяснить цену такого дополнения и его преимущества, обычно связанные с наследованием решений и привлечением пользователей. В первых реализациях Лиспа были сразу предложены специальные формы и структуры данных, служащие мостом между разными стилями программирования, а заодно смягчающие недостатки исходной, слишком идеализированной, схемы интерпретации, выстроенной для учебных и исследовательских целей. Важнейшее такого рода средство, выдержавшее испытание временем - prog-форма, списки свойств атома и деструктивные операции, расширяющие язык программирования так, что становятся возможными оптимизирующие преобразования структур данных, программ и процессов, а главное - раскрутка систем программирования [ [ 75 ] ].

Применение prog-выражений позволяет писать "паскалеподобные" программы, состоящие из операторов, предназначенных для исполнения. (Точнее "алголоподобные", т.к. появились лет за десять до Pascal. Но теперь более известен Pascal.)

Для примера prog-выражения приводится императивное определение функции Length *), сканирующей список и вычисляющей число элементов на верхнем уровне списка. Значение функции Length - целое число. Программу можно примерно описать следующими словами1Примечание. Стилизация примера от МакКарти [ [ 75 ] ]. :

"Это функция одного аргумента L.
 Она реализуется программой с двумя рабочими переменными u и v.
        Записать число 0 в v.
        Записать аргумент L в u.
A: Если u содержит NIL, то программа выполнена и значением является то,
                                                 что сейчас записано в v.
       Записать в u cdr от того, что сейчас в u.
       Записать в v на единицу больше того, что сейчас записано в v.
 Перейти к A"

Эту программу можно записать в виде Паскаль-программы с несколькими подходящими типами данных и функциями. Строкам описанной выше программы в предположении, что существует на Паскале библиотека функций над списками, соответствуют строки определения функции:

function LENGTH (L: list) : integer;
             var U: list; 
                 V: integer;
begin
      V := 0;
      U := l;
A:     if null (U) then LENGTH := V;       
      U := cdr (U);
      V := V+1;
             goto A;
end;

Переписывая на Лисп, получаем программу:

(defun      

LENGTH (lambda (L)
                  (prog (U V)
      (setq V 0)
      (setq U L)
A       (cond  ((null U)(return V)))
      (setq U (cdr U))
      (setq V (+ 1 V))
(go  A)  )))  ))

Prog-форма имеет структуру, подобную определениям функций и процедур в Паскале: (PROG, список рабочих переменных, последовательность операторов и атомов ... ) Атом в списке является меткой, локализующей оператор, расположенный вслед за ним. В приведенном примере метка A локализует оператор, начинающийся с "COND".

Первый список после символа PROG называется списком рабочих переменных. При отсутствии таковых должно быть написано NIL или (). С рабочими переменными обращаются примерно как со связанными переменными, но они не могут быть связаны ни с какими значениями через lambda. Значение каждой рабочей переменной есть NIL, до тех пор, пока ей не будет присвоено что-нибудь другое.

Для присваивания рабочей переменной применяется форма SET. Чтобы присвоить переменной pi значение 3.14 пишется (SET (QUOTE PI)3.14). SETQ подобна SET, но она еще и блокирует вычисление первого аргумента. Поэтому (SETQ PI 3.14) - запись того же присваивания. SETQ обычно удобнее. SET и SETQ могут изменять значения любых переменных из списка параметров более внешних функций. Значением SET и SETQ является значение их второго аргумента.

Обычно операторы выполняются последовательно. Выполнение оператора понимается как его вычисление и отбрасывание его значения. Операторы программы часто выполняются в большей степени ради действия, чем ради значения.

< Лекция 7 || Лекция 8: 12 || Лекция 9 >
Илья Ардов
Илья Ардов

Добрый день!

Я записан на программу. Куда высылать договор и диплом?

Дарья Федотова
Дарья Федотова