
- •Для школьников, студентов и начинающих 1999 с,н.Лукин __________________________________________________________ Все права защищены ©
- •Оглавление
- •Часть I. Необходимые сведения о компьютере и программе 8
- •Часть II. Программирование на Паскале – первый уровень 29
- •Часть III. Программирование на Паскале – второй уровень 102
- •Часть IV. Работа в Паскале на компьютере 158
- •От автора
- •Предисловие
- •Кому нужна эта книга?
- •Почему Паскаль?
- •Какой из Паскалей?
- •Краткое содержание с рекомендациями
- •Часть III. Программирование на Паскале – второй уровень. Цели этой части:
- •Часть I. Необходимые сведения о компьютере и программе
- •Первое представление о компьютере и программе
- •Что умеет делать компьютер
- •Что такое компьютер. Первое представление о программе.
- •Как человек общается с компьютером
- •Программа и программирование
- •Список команд. Командный и программный режимы
- •Последовательность работы человека с роботом
- •Что важно знать о программе
- •Понятие о процедуре. Может ли робот поумнеть?
- •Программа для компьютера на машинном языке
- •Языки программирования
- •Пример настоящей программы для компьютера на языке Лого
- •А теперь напишем программу:
- •Последовательность работы программиста на компьютере
- •Основные приемы программирования
- •Устройство и работа компьютера
- •Как устроен и работает компьютер
- •Порядок обмена информацией между устройствами компьютера
- •Устройство и размеры оперативной памяти
- •Взаимодействие программ в памяти
- •Внешние устройства компьютера
- •Устройства ввода
- •Устройства вывода
- •Внешняя память
- •Кодирование информации в компьютере
- •Часть II. Программирование на Паскале – первый уровень
- •Простые (линейные) программы. Операторы ввода-вывода. Переменные величины
- •Процедура вывода Write
- •8 'Котят' 3*3 'щенят'
- •Первая программа на Паскале
- •Точкой с запятой необходимо отделять операторы друг от друга. Служебные слова begin и end от операторов точкой с запятой отделять не нужно.
- •Выполняем первую программу на компьютере
- •Процедура вывода WriteLn. Курсор
- •Переменные величины. Оператор присваивания
- •Описания переменных (var)
- •Что делает оператор присваивания с памятью
- •Оператор присваивания меняет значение переменной величины
- •Имена переменных
- •Математика. Запись арифметических выражений
- •Вещественные числа в Паскале
- •Три совета
- •Порядок составления простой программы Задача:
- •Порядок составления программы:
- •5. Теперь нужно задать компьютеру действия, которые нужно проделать с исходными данными, чтобы получить результат.
- •Операторы ввода данных ReadLn и Read.
- •Интерфейс пользователя
- •Строковые переменные
- •Диалог с компьютером
- •Константы
- •Разветвляющиеся программы
- •Условный оператор if или как компьютер делает выбор
- •Правила записи оператора if
- •Составной оператор
- •Ступенчатая запись программы
- •Вложенные операторы if. Сложное условие в операторе if. Логические операции
- •Символьный тип данных Char
- •Оператор варианта case
- •Циклические программы
- •Оператор перехода goto. Цикл. Метки
- •Выход из цикла с помощью if
- •Оператор цикла repeat
- •Оператор цикла while
- •Отличия операторов repeat и while
- •Оператор цикла for
- •Типичные маленькие программы
- •Вычислительная циклическая программа
- •Роль ошибок
- •Счетчики
- •Сумматоры
- •Вложение циклов в разветвления и наоборот
- •Вложенные циклы
- •Поиск максимального из чисел
- •Процедуры
- •Компьютер звучит
- •Простейшие процедуры
- •Программа 1
- •Программа 2
- •Программа 3
- •Процедуры и операторы
- •Стандартные процедуры Halt и Exit
- •Графика
- •Стандартные модули
- •Стандартный модуль Graph, текстовый и графический режимы
- •Текстовый и графический режимы
- •Переключение между текстовым и графическим режимами
- •Рисуем простейшие фигуры
- •Работа с цветом. Заливка. Стиль линий и заливки
- •Используем в рисовании переменные величины
- •Использование случайных величин при рисовании
- •Движение картинок по экрану
- •Создаем первую большую программу
- •Постановка задачи
- •Программирование по методу “сверху-вниз”
- •Сначала – работа над структурой программы
- •Зачем переменные вместо чисел
- •Записываем программу целиком
- •Порядок описания переменных, процедур и других конструкций Паскаля
- •Управление компьютером с клавиатуры. Функции ReadKey и KeyPressed
- •Буфер клавиатуры
- •Гетерархия. Задание на игру “Торпедная атака”
- •Часть III. Программирование на Паскале – второй уровень
- •Алфавит и ключевые слова Паскаля
- •Алфавит
- •Ключевые слова
- •Использование пробела
- •Работа с разными типами данных Паскаля
- •Список типов
- •Комментарии к списку типов
- •Числовые типы
- •Массивы
- •Переменные с индексами
- •Одномерные массивы
- •Двумерные массивы
- •Какие бывают массивы
- •Определения констант
- •Типизированные константы
- •Придумываем типы данных
- •Логический тип Boolean
- •Перечислимые типы
- •Ограниченный тип (диапазон)
- •Действия над порядковыми типами
- •Символьный тип Char. Работа с символами
- •Строковый тип String. Работа со строками
- •Множества
- •Расположение информации в оперативной памяти. Адреса
- •Процедуры и функции с параметрами
- •Процедуры с параметрами
- •Функции
- •Подпрограммы. Локальные и глобальные переменные
- •Массивы как параметры
- •Параметры-значения и параметры-переменные
- •Индукция. Рекурсия. Стек
- •Сортировка
- •Строгости Паскаля
- •Структура программы
- •Структура процедур и функций
- •Выражения
- •Совместимость типов
- •Форматы вывода данных
- •Переполнение ячеек памяти
- •Дерево типов
- •Синтаксисические диаграммы Паскаля
- •Другие возможности Паскаля
- •Работа с файлами данных
- •Вставка в программу фрагментов из других программных файлов
- •Модули программиста
- •Дополнительные процедуры и функции модуля Graph
- •Копирование и движение областей экрана
- •Вывод текста в графическом режиме
- •Управление цветом в текстовом режиме (модуль crt)
- •Работа с датами и временем (модуль dos)
- •Нерассмотренные возможности Паскаля
- •Миг между прошлым и будущим
- •Часть IV. Работа в Паскале на компьютере
- •Что нужно знать и уметь к моменту выполнения первой программы?
- •Порядок работы в Паскале
- •(1) Запуск Паскаля
- •(2) Начало работы. Ввод программы. Выход из Паскаля
- •(3) Сохранение программы на диске. Загрузка программы с диска
- •(4) Выполнение программы
- •(5) Исправление ошибок. Отладка программы.
- •Пошаговый режим
- •Работа с окнами пользователя и отладчика
- •Отладка больших программ
- •Работа с несколькими окнами.
- •Копирование и перемещение фрагментов текста
- •Обзор популярных команд меню
- •Создание исполнимых файлов (exe)
- •Приложения. Справочный материал п1. Как вводить программу в компьютер или работа с текстом в текстовом редакторе
- •Работа с одной строкой текста
- •Работа с несколькими строками
- •Собственно работа с несколькими строками.
- •П2. Файловая система магнитного диска
- •Имена файлов и каталогов
- •Пример структуры каталогов на диске
- •Логические диски. Путь (дорожка) к файлу
- •П3. Список некоторых операций, процедур и функций Паскаля
- •Математика
- •Модуль crt
- •Модуль Graph
- •П4. Произношение английских слов
- •П5. Решения заданий
- •П6. Список литературы
- •П7. Предметный указатель
-
Зачем переменные вместо чисел
В 0.11 я учил вас использовать в программе не числа, а переменные величины. Однако, впоследствие при написании простеньких программ сам же этому принципу не следовал, чтобы не отвлекать ваше внимание на запоминание имен переменных. Теперь пришла пора показать, почему же все-таки полезно вместо чисел употреблять переменные.
Вот программа для задания 3 из выше для бесконечного движения окружности влево-вправо. В ней этот принцип пока не соблюдается.
USES Graph;
VAR x, Device, Mode :Integer;
BEGIN Device:=0;
InitGraph(Device, Mode, ’<путь к графическим драйверам>’);
ReadLn;
repeat {Внешний цикл для бесконечности отскоков} { Движение направо:}
x:=40; {Начинаем перемещение из левой части экрана}
repeat {Вложенный цикл для движения направо} SetColor(White);
Circle(x,100,10); {Рисуем белую окружность}
SetColor(Black);
Circle(x,100,10); {Рисуем черную окружность}
x:=x+2 {Перемещаемся немного направо}
until x>600; {пока не упремся в правый край экрана} { Движение налево:}
x:=600; {Начинаем перемещение из правой части экрана }
repeat {Вложенный цикл для движения налево} SetColor(White);
Circle(x,100,10); {Рисуем белую окружность}
SetColor(Black);
Circle(x,100,10); {Рисуем черную окружность}
x:=x-2 {Перемещаемся немного налево}
until x<40 {пока не упремся в левый край экрана}
until 8>9 {Невыполнимое условие, чтобы цикл выполнялся бесконечно} END.
Предположим, мы хотим, чтобы шарик летал в три раза быстрее. Для этого нам достаточно в двух местах программы вместо 2 написать 6. Вот то-то и неудобно, что в двух, а не в одном. Слишком много труда. В нашей программе это, конечно, пустяк, а вот в больших и сложных программах одна и та же величина может встречаться десятки раз, и чтобы ее изменить, придется вносить десятки исправлений.
Теперь напишем вариант той же программы, но с использованием переменных величин:
USES Graph;
VAR x, Device, Mode, lev, prav, shag : Integer;
BEGIN Device:=0;
InitGraph(Device, Mode, ’<путь к графическим драйверам>’);
ReadLn;
lev:=40; prav:=600; shag:=2;
repeat x:=lev;
repeat SetColor(White);
Circle(x,100,10);
SetColor(Black);
Circle(x,100,10);
x:=x+shag
until x>prav;
x:=prav;
repeat SetColor(White);
Circle(x,100,10);
SetColor(Black);
Circle(x,100,10);
x:=x-shag
until x<lev until 8>9 END.
Теперь для того, чтобы изменить скорость шарика, достаточно заменить 2 на 6 только в одном месте.
Вторая причина, по которой мы используем переменные, та, что с ними программа становится понятнее, так как имена переменным мы придумываем, исходя из их смысла.
-
Записываем программу целиком
Пока у вас на экране – правильно работающий «скелет» программы. Наша задача – постепенно наполнить этот скелет мышцами.
Ниже вы можете посмотреть готовую программу мультфильма. А сейчас я поясню порядок ее написания, отладки и отдельные трудные места.
При работе на компьютере ни в коем случае не вводите сразу всю программу из сотни строк, чтобы потом, запустив ее, не схватиться за голову! Почему? Потому что профессиональный программист в среднем допускает одну описку или ошибку в 10 строках. Значит, в вашей программе будет порядка 10 опечаток или ошибок. Все 10 сразу вы не найдете и за сутки. Потому что сразу 10 ошибок искать в 100 раз труднее, чем 10 раз по одной. Хорошо, если вам одновременно врет только один человек. А если вам в уши одновременно врут 10 человек, и все по-разному?
Поэтому, следуя не спеша за материалом этого параграфа, действуйте в таком порядке.
Прочтите часть материала, посвященную горизонту (она чуть ниже). Введите в программу строки, необходимые для рисования горизонта: Прежде всего в раздел VAR нужно добавить описание y_goriz. Затем введите строку y_goriz:=240. Затем строку Line (0, y_goriz, 640, y_goriz). Запустите программу. Если горизонт на месте и все в порядке, сверьтесь с текстом программы в учебнике и сотрите репортаж горизонта о своей работе.
Все. С горизонтом разделались. Что дальше должно рисоваться на экране? Синева. Введите пару строк про синеву. Запустите программу. Все в порядке, сверьтесь с текстом. Сотрите репортаж синевы.
И так далее. Вводите за один раз не больше одной-двух строк, после чего запускайте программу и смотрите, как она работает.
Старайтесь не списывать с учебника, а придумывайте программу сами, с учебником только сверяясь.
А теперь приступим к объяснениям в самой программе.
Поскольку у нас первым будет рисоваться горизонт из процедуры Пейзаж, с него и начнем. Я буду исходить из того, что размер вашего экрана - 640480. Если другой, то вам нетрудно будет внести изменения в текст моей программы.
Пусть горизонт делит экран пополам. Тогда подойдет оператор Line(0,240,640,240). Посмотрим, какие числа здесь целесообразно заменить переменными величинами. Числа 0 и 640 нам менять не понадобится, а вот высоту горизонта мы вполне можем захотеть изменить. Придумаем переменную величину y_goriz и поставим ее вместо числа 240. У нас вместо одного оператора получится пара:
y_goriz:=240;
Line (0, y_goriz, 640, y_goriz)
Оператор y_goriz:=240 я помещу в начало раздела операторов, так как значение y_goriz понадобится и части Звезды и процедуре Летающая тарелка и мало ли кому еще может понадобиться.
Части Синева, Луна, Звезды понятны без пояснений. Попробуем теперь сделать процедуру Дерево. Начнем с того дерева, что в левом нижнем углу:
PROCEDURE Tree;
BEGIN
SetColor(White);
{Рисуем крону:}
Ellipse (100,400,0,360,15,30);
SetFillStyle(1,LightGreen);
FloodFill(100,400,White);
{Рисуем ствол:}
Rectangle (97,430,103,460);
SetFillStyle(1,Brown);
FloodFill(100,440,White);
END;
Сделаем переменными все величины, от которых зависит местоположение дерева, а величины, от которых зависят форма и размеры, для простоты трогать не будем. Будем считать “координатами дерева” координаты центра эллипса, образующего крону. Придумаем им имена x_tree и y_tree и от них будем отсчитывать все остальные координаты дерева. Тогда процедура будет выглядеть так:
PROCEDURE Tree;
BEGIN
SetColor(White);
{Рисуем крону:}
Ellipse ( x_tree, y_tree, 0, 360,15,30);
SetFillStyle(1,LightGreen);
FloodFill(x_tree, y_tree, White);
{Рисуем ствол:}
Rectangle (x_tree - 3, y_tree + 30, x_tree + 3, y_tree + 60);
SetFillStyle(1,Brown);
FloodFill (x_tree, y_tree + 40, White);
END;
Теперь для того, чтобы дерево было нарисовано в нужном месте, нужно перед выполнением процедуры Tree присвоить координатам дерева нужные значения: x_tree := 100, y_tree:= 400. В программе процедура выполняется три раза, причем каждый раз перед ее выполнением координатам дерева присваиваются разные значения.
Аналогично составляем процедуру Дом. Сначала напишем ее без переменных:
PROCEDURE House;
BEGIN
SetColor(White);
{Рисуем стену:}
Rectangle (300,400,340,440);
SetFillStyle(1,LightBlue);
FloodFill (301,401,White);
{Рисуем окно:}
Rectangle (315,410,325,420);
SetFillStyle(1,DarkGray);
FloodFill (320,415, White);
{Рисуем крышу:}
Line(295,400,345,400);
Line(295,400,320,370);
Line(345,400,320,370);
SetFillStyle(1,Red);
FloodFill (320,399, White);
END;
Выберем левый верхний угол стены точкой начала отсчета. Ее координаты x_house:=300; y_house:=400. Окончательный вид процедуры House вы можете видеть в программе.
Вот полный текст программы:
USES Graph,CRT;
VAR Device, Mode, i : Integer;
y_goriz, x_tree, y_tree, x_house, y_house,
x_tar, y_tar, shirina_tar, visota_tar : Integer;
PROCEDURE Tree;
BEGIN
SetColor(White);
{Рисуем крону:}
Ellipse ( x_tree, y_tree, 0, 360, 15, 30);
SetFillStyle(1,LightGreen);
FloodFill(x_tree, y_tree, White);
{Рисуем ствол:}
Rectangle (x_tree - 3, y_tree + 30, x_tree + 3, y_tree + 60);
SetFillStyle(1,Brown);
FloodFill (x_tree, y_tree + 40, White);
END;
PROCEDURE House;
BEGIN
SetColor(White);
{Рисуем стену:}
Rectangle (x_house, y_house, x_house+40, y_house+40);
SetFillStyle(1,LightBlue);
FloodFill (x_house+1, y_house+1, White);
{Рисуем окно:}
Rectangle (x_house+15, y_house+10, x_house+25, y_house+20);
SetFillStyle(1,DarkGray);
FloodFill (x_house+20, y_house+15, White);
{Рисуем крышу:}
Line(x_house-5, y_house, x_house+45, y_house);
Line(x_house-5, y_house, x_house+20, y_house-30);
Line(x_house+45, y_house, x_house+20, y_house-30);
SetFillStyle(1,Red);
FloodFill (x_house+20, y_house-1, White);
END;
PROCEDURE Landscape;
BEGIN
{ горизонт: }
Line(0, y_goriz, 640, y_goriz);
{ синева: }
SetFillStyle(1,Blue);
FloodFill(10,10,White);
{ луна: }
SetColor(Yellow);
Circle(500,100,30);
SetFillStyle(1,Yellow);
FloodFill(500,100,Yellow);
{ звезды: }
for i:=1 to 100 do PutPixel (Random(640),Random(y_goriz),Random(16));
{Три дерева: }
x_tree:=100; y_tree:=400; Tree;
x_tree:=300; y_tree:=300; Tree;
x_tree:=550; y_tree:=380; Tree;
{Два дома: }
x_house:=300; y_house:=400; House;
x_house:=470; y_house:=300; House;
{ трава: }
SetFillStyle(1,Green);
FloodFill(10,470,White);
END;
PROCEDURE Music;
BEGIN
Sound(200);Delay(1000);
Sound(500);Delay(1000);
Sound(300);Delay(1000);
NoSound
END;
PROCEDURE Flying_Saucer;
BEGIN
{Задаем начальные координаты летающей тарелки и ее размеры.
Их не обязательно задавать в начале раздела операторов, так как они
больше никакой процедуре не нужны}
x_tar:=100; y_tar:=40; shirina_tar:=30; visota_tar:=15;
repeat {Цикл движения тарелки }
SetColor(White);
Ellipse (x_tar, y_tar, 0, 360, shirina_tar, visota_tar);
Delay(20); {Чтобы замедлить движение }
SetColor(Blue);
Ellipse (x_tar, y_tar, 0, 360, shirina_tar, visota_tar);
y_tar:=y_tar+1
until y_tar > y_goriz;
{Прорисовываем последний раз тарелку на горизонте: }
SetColor(White);
Ellipse (x_tar, y_tar, 0, 360, shirina_tar, visota_tar);
END;
BEGIN
Device:=0;
InitGraph(Device, Mode, '<путь к граф.драйверам>’);
y_goriz:=240;
Landscape; { рисуем пейзаж }
Delay(3000); { пауза три секунды }
Music; { музыка }
Flying_Saucer; { движение тарелки }
Music; { музыка }
SetFillStyle(1,Yellow); { свет в окне }
FloodFill (x_house+20, y_house+15, White); { свет в окне }
ReadLn;
CloseGraph
END.