- •Средства разработки программ на Паскале
- •Структура Паскаль-программы
- •Комментарии
- •Директивы компилятора
- •Идентификаторы
- •Переменные и типы данных
- •Константы
- •Неименованные константы
- •Нетипизированные константы
- •Типизированные константы
- •Простейшие операторы
- •Метки и безусловный переход
- •Ввод и вывод: консоль
- •Ввод с консоли
- •Вывод на консоль
- •Форматный вывод
- •Пример простейшей программы на языке Pascal
- •Типы данных
- •Порядковые типы данных
- •Стандартные подпрограммы, обрабатывающие порядковые типы данных
- •Типы данных, относящиеся к порядковым
- •Вещественные типы данных
- •Конструируемые типы данных
- •Операции и выражения
- •Совместимость типов данных
- •Приведение типов данных
- •Ветвления, массивы, циклы
- •Массивы
- •Операторы циклов
- •Сортировки массивов
- •Быстрая сортировка
- •Символы и строки
- •Неименованные константы
- •Нетипизированные константы
- •Типизированные константы
- •Операции
- •Стандартные функции
- •Стандартные функции и процедуры обработки строк
- •Операции со строками Сравнения
- •Обращение к компонентам строки
- •Конкатенация
- •Множества
- •Описание множеств
- •Множество-константа Неименованная константа
- •Нетипизированная константа
- •Типизированная константа
- •Операции с множествами
- •Представление множеств массивами
- •Представление множеств линейными массивами
- •Представление множеств битовыми массивами
- •Примеры использования символов, строк и множеств
- •Что такое файл
- •Когда нужно использовать файлы
- •Разновидности файлов
- •Описание файлов
- •Текстовые файлы Назначение файла
- •Открытие файла
- •Закрытие файла
- •Считывание из файла
- •Запись в файл
- •Пробельные символы
- •Пример использования файлов
- •Решение
- •Реализация
- •Изменение реакции на ошибку
- •Описание записей
- •Задание записей константой
- •Доступ к полям
- •Оперирование несколькими полями
- •Вложенные операторы with
- •Запись с вариантной частью
- •Описание записи с вариантной частью
- •Механизм использования записи с вариантной частью
- •Бинарные файлы
- •Типизированные файлы
- •Описание типизированных файлов
- •Назначение типизированного файла
- •Открытие и закрытие типизированного файла
- •Считывание из типизированного файла
- •Поиск в типизированном файле
- •Запись в типизированный файл
- •Поиск в нетипизированном файле
- •Запись и чтение
- •Подпрограммы обработки директорий
- •Применимость подпрограмм обработки файлов
- •Процедуры и функции Подпрограммы
- •Список параметров
- •Возвращаемые значения
- •Вызов подпрограмм
- •Способы подстановки аргументов
- •Параметр-значение Описание
- •Механизм передачи значения
- •Параметр-переменная Описание
- •Механизм передачи значения
- •Параметр-константа Описание
- •Механизм передачи значения
- •Области действия имен Разграничение контекстов
- •Побочный эффект
- •Совпадение имен
- •Нетипизированные параметры
- •Явное преобразование типа
- •Совмещение в памяти
- •Открытые параметры
- •Открытые массивы
- •Рекурсивные подпрограммы Динамические структуры данных
- •Операции
- •Очередь
- •Операции
- •Рекурсия
- •Рекурсивные подпрограммы
- •Пример рекурсивного алгоритма
- •Алгоритм решения
- •Стековая организация рекурсии
- •Ограничение глубины рекурсии
- •Замена рекурсивных алгоритмов итеративными
- •Пример сравнения рекурсивного и нерекурсивного алгоритма
- •Рекурсивный алгоритм
- •Реализация рекурсивного алгоритма
- •Полный перебор с отсечением
- •Нерекурсивный алгоритм
- •Реализация нерекурсивного алгоритма
- •Иллюстрация
- •Эффективность
- •Быстрая сортировка2
- •Алгоритм Быстр
- •Реализация алгоритма Быстр
- •Эффективность алгоритма Быстр
- •Адреса и указатели. Списочные структуры данных Статически выделяемая память
- •Разыменование
- •Присваивания
- •Сравнения
- •Динамически распределяемая память
- •Динамическое выделение памяти Типизированные указатели
- •Нетипизированные указатели
- •Динамическое освобождение памяти Типизированные указатели
- •Нетипизированные указатели
- •Списочные структуры
- •Структура списков
- •Описание списков
- •Оперирование элементами списка Хранение списка
- •Обращение к элементам списка
- •Создание списков
- •Просмотр элементов списка
- •Удаление элементов списка
- •Перестройка списков
- •Примеры перестройки линейных списков
- •Реализация
- •Создание дружественного интерфейса
- •Заставка
- •Ввод информации
- •Приглашения
- •Вывод информации
- •Технология программирования и отладка Советы по технологии написания быстро отлаживаемых программ
- •Имена, имена, имена...
- •Кусочки, куски и кусищи...
- •Спасение утопающих - дело рук самих утопающих
- •Отладка и тестирование
- •Поиск и исправление ошибок
- •Правила составления тестов
- •Оптимизация программ
- •Учебники к курсу
Перестройка списков
Разницу между структурой статической (массив) и структурой динамической (список) очень доступно проиллюстрировал Никлаус Вирт в своей книге "Алгоритмы и структуры данных". Мы позволим себе позаимствовать оттуда, хотя и не дословно, красивый пример.
Представим обычную очередь у прилавка в магазине. Первый покупатель - это тот, кто в данную минуту стоит непосредственно возле прилавка; следующий за ним - второй, за вторым - третий и т.д. Покупатели занумерованы строго в порядке следования, и вновь пришедшие встают в хвост. В принципе, взглянув на очередь, всегда можно сказать, кто за кем стоит. А что происходит, если один из покупателей желает покинуть очередь? Хвост тут же сдвигается: каждый человек делает шаг вперед, чтобы очередь не утратила целостности. Если же, наоборот, некто желает встроиться в середину очереди (невзирая на крики "А вас тут не стояло!"), то задним приходится пятиться, чтобы освободить ему место. Точно так же ведут себя элементы линейного массива.
Теперь возьмем другую очередь: в приемной у зубного врача. Во-первых, посетители уже не привязаны так жестко к линии прилавка: они сидят в креслах, расположенных там и сям, где только нашлось удобное место. Во-вторых, каждому вновь пришедшему нет необходимости знать, кто в этой очереди первый, а кто второй: достаточно лишь выяснить, кто последний. И вовсе не обязательно садиться рядом с последним пациентом: вновь пришедший может занять любое свободное кресло в приемной. А если у кого-то вдруг перестали болеть зубы и он радостно уходит из очереди, то "стоявшему" за ним достаточно спросить: - "А вы за кем занимали?" При этом физического перемещения пациентов в пространстве не происходит. Аналогично, если вдруг появляется пациент с талончиком на более раннее время, "задние" пропускают его вперед, не сдвигаясь со своих кресел. Именно так ведут себя и элементы динамических списков1).
Примеры перестройки линейных списков
На рис. 10.5 приведены четыре примера перестройки односвязных списков. Пунктирами изображены указатели, получающие новые значения в процессе работы программ.
Удаление всех нулей из списка.
Вставка в список, хранящий все нечетные числа от 1 до 11, трех новых элементов - 0, 8 и 12 - с сохранением его упорядоченности.
Обмен второго и третьего элементов списка.
Обращение порядка всех четных элементов списка.
Реализация
Приведем фрагменты программ, решающих первую и третью задачи:
{- голову списка обрабатываем отдельно -}
while (head<>nil)and(head^.znach =0)do
begin p:= head;
head:= head^.next;
dispose(p);
end;
{- середина и конец списка обрабатываются вместе -}
p:= head;
while p^.next <> nil do
if p^.next^.znach = 0
then begin q:= p^.next;
p^.next:= p^.next^.next;
dispose(q);
end
else
p:= p^.next;
p:= head^.next;
head^.next:= p^.next;
p^.next:= p^.next^.next;
head^.next^.next:= p;
Рис. 10.5. Примеры перестройки односвязных списков
Создание дружественного интерфейса
Напомним, что пользовательский интерфейс - это обеспечение взаимодействия программы и человека1).
Хорошим считается дружественный (или дружелюбный) интерфейс - тот, который удобен не программисту, а пользователю. Несколько раз на протяжении нашего курса лекций мы подчеркивали это. Теперь, когда у нас уже есть все инструменты, позволяющие создавать хорошие интерфейсы к программам, пришло время поговорить о них подробнее.