Турбо-Паскаль 7.0

Необходимые сведения о компьютере и программе. Командный и программный режимы программы "Турбо-Паскаль 7.0". Простые, линейные программы. Операторы ввода-вывода. Запись арифметических выражений. Стандартный модуль Graph, текстовый и графический режимы.

Рубрика Программирование, компьютеры и кибернетика
Вид учебное пособие
Язык русский
Дата добавления 13.10.2012
Размер файла 1,5 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Оператор

а

с

Печать

c:=0

?

0

ReadLn(a)

8

0

if a>0 then c:=c+1

8

1

WriteLn('Из них положительных - ' ,c)

8

1

Из них положительных 1

goto m

8

1

ReadLn(a)

-2

1

if a>0 then c:=c+1

-2

1

WriteLn('Из них положительных - ' ,c)

-2

1

Из них положительных 1

goto m

-2

1

ReadLn(a)

10

1

if a>0 then c:=c+1

10

2

WriteLn('Из них положительных - ' ,c)

10

2

Из них положительных 2

goto m

10

2

Не забывайте обнулять счетчик перед входом в цикл, а не то он начнет считать вам не с нуля, а бог знает с чего. Как бы вам понравилось, если бы таксист в начале поездки не обнулил счетчик?

В нашем фрагменте значения счетчика печатаются при каждом выполнении цикла. Изменим задачу.

Задача 2: В компьютер вводится ровно 200 чисел. Компьютер должен подсчитать и один раз напечатать, сколько среди них положительных.

Программа:

VAR c,i :Integer;

a :Real;

BEGIN

c:=0; {Обнуляем счетчик}

for i:=1 to 200 do begin

ReadLn(a);

if a>0 then c:=c+1

end {for};

WriteLn('Из них положительных - ' ,c)

END.

Пояснения: Путь рассуждений здесь тот же, что и в первой задаче. В результате применения оператора for фрагмент ReadLn(a);if a>0 then c:=c+1 выполняется ровно 200 раз, благодаря чему счетчик с накапливает нужное значение. Оператор WriteLn выполняется только один раз и печатает это значение.

Совет: Если вы запускаете эту программу в компьютере, то с числом 200 возиться крайне долго. Поменяйте его на 3 или 4. Смысл программы от этого не изменится.

Задание 46: Что будет, если

Вместо c:=0 написать c:=10.

Вместо c:=c+1 написать c:=c+2.

Строки end {for} и WriteLn поменять местами.

Строки c:=0 и for поменять местами.

Строки for и ReadLn поменять местами.

Задача 3: В компьютер один за другим вводятся произвольные символы. Ввод заканчивается символом "/". Подсчитать, какой процент от общего числа введенных символов составляют символ "W" и символ ":" по отдельности.

Здесь мы организуем три счетчика одновременно: сW и сDv - для подсчета букв W и двоеточий соответственно, а также i - счетчик циклов, то есть общего числа введенных символов.

Программа:

VAR i,cW,cDv, procent_W, procent_Dv : Integer;

simvol :Char;

begin

i:=0; cW:=0; cDv:=0; {Обнуляем все три счетчика}

repeat {Повторяй цикл}

ReadLn (simvol); {Введи символ}

i:=i+1; {«Посчитай» его}

case simvol of

'W' :cW:=cW+1; {Если это W, увеличь счетчик символов W}

':' :cDv:=cDv+1 {Если это :, увеличь счетчик символов :}

end

until simvol = '/'; {пока не наткнешься на символ /}

procent_W :=Round(100*cW/i); {Вычисляй процент символов W}

procent_Dv :=Round(100*cDv/i); {Вычисляй процент символов :}

WriteLn(procent_W,' ',procent_Dv)

end.

Задание 47: В компьютер вводится N чисел. Подсчитать по отдельности количество отрицательных, положительных и тех, что превышают число 10.

Задание 48: В компьютер вводятся пары целых чисел. Подсчитать, сколько среди них пар, дающих в сумме число 13. Подсчет закончить после ввода пары нулей.

Напомню, что пару чисел можно ввести оператором ReadLn(a,b).

2.4.4 Сумматоры

Если вы поняли идею счетчика, то понять идею сумматора вам будет нетрудно. Посмотрим, как будет работать следующий фрагмент:

s:=0; {Обнуляем сумматор. Это не менее важно, чем обнулить счетчик}

m: ReadLn(a);

s:=s+a; {Увеличиваем сумматор}

WriteLn(`Сумма=', s);

goto m;

Пусть мы вводим числа 8, 4, 10 . . . В этом случае порядок выполнения операторов будет такой:

Оператор

а

s

Печать

s:=0

?

0

ReadLn(a)

8

0

s:=s+a

8

8

WriteLn(`Сумма=' ,s)

8

8

Сумма=8

goto m

8

8

ReadLn(a)

4

8

s:=s+a

4

12

WriteLn(`Сумма=' ,s)

4

12

Сумма=12

goto m

4

12

ReadLn(a)

10

12

s:=s+a

10

22

WriteLn(`Сумма=' ,s)

10

22

Сумма=22

goto m

10

22

……….

Как видите, в ячейке s накапливается сумма вводимых чисел a, поэтому назовем эту ячейку сумматором. Отличие сумматора от счетчика в том, что счетчик увеличивается на 1 оператором c:=c+1, а сумматор - на суммируемое число оператором s:=s+a.

Задача: В компьютер вводится N чисел. Вычислить и один раз напечатать их сумму.

Программа:

VAR i,N :Integer;

a,s :Real;

BEGIN

ReadLn(N);

s:=0;

for i:=1 to N do begin

ReadLn(a);

s:=s+a

end {for};

WriteLn(`Сумма равна ' ,s:20:10)

END.

Задание 49: Пусть N=2, a=5 и 3. Тогда по этой программе Паскаль напечатает 8. Что он напечатает, если:

Вместо s:=0 написать s:=10.

Вместо s:=s+a написать s:=s+a+1.

Строки end {for} и WriteLn поменять местами.

Строки s:=0 и for поменять местами.

Строки for и ReadLn поменять местами.

Строки s:=s+a и end {for} поменять местами.

Вместо for i:=1 to N написать for i:=2 to N.

Задания 50-52: Написать программы для следующих задач:

Во дворце 40 залов. Известны длина и ширина каждого зала. Вычислить площадь пола всего дворца.

Вычислить средний балл учеников вашего класса по физике.

Вычислить произведение N произвольных чисел.

2.4.5 Вложение циклов в разветвления и наоборот

Реальная программа на Паскале представляет собой сложную мозаику из циклических и разветвляющихся частей, вложенных друг в друга. Мы уже видели в 5.7, как в оператор case был вложен оператор for. В свою очередь в оператор цикла могут быть вложены другие операторы, как в 7.3, и так до бесконечности.

Для тренировки определите, что напечатает следующий фрагмент:

for i:=1 to 5 do begin

a:=9;

if i*i = a then for k:=5 to 8 do Write(k)

else WriteLn(1997);

end {for}

Ответ:

1997

1997

56781997

1997

2.4.6 Вложенные циклы

Поставим себе задачу - напечатать таблицу умножения. В следующем виде:

1*1=

1

1*2=

2

1*3=

3

1*4=

4

1*5=

5

1*6=

6

1*7=

7

1*8=

8

1*9=

9

2*1=

2

2*2=

4

2*3=

6

2*4=

8

2*5=

10

2*6=

12

2*7=

14

2*8=

16

2*9=

18

3*1=

3

3*2=

6

3*3=

9

3*4=

12

3*5=

15

3*6=

18

3*7=

21

3*8=

24

3*9=

27

4*1=

4

4*2=

8

4*3=

12

4*4=

16

4*5=

20

4*6=

24

4*7=

28

4*8=

32

4*9=

36

5*1=

5

5*2=

10

5*3=

15

5*4=

20

5*5=

25

5*6=

30

5*7=

35

5*8=

40

5*9=

45

6*1=

6

6*2=

12

6*3=

18

6*4=

24

6*5=

30

6*6=

36

6*7=

42

6*8=

48

6*9=

54

7*1=

7

7*2=

14

7*3=

21

7*4=

28

7*5=

35

7*6=

42

7*7=

49

7*8=

56

7*9=

63

8*1=

8

8*2=

16

8*3=

24

8*4=

32

8*5=

40

8*6=

48

8*7=

56

8*8=

64

8*9=

72

9*1=

9

9*2=

18

9*3=

27

9*4=

36

9*5=

45

9*6=

54

9*7=

63

9*8=

72

9*9=

81

Начнем с малого - пусть нужно напечатать

1*1=1

Вот фрагмент программы:

Фрагмент 1

a:=1;

b:=1;

proizv:=a*b;

Write(a, '*' ,b, '=' ,proizv)

Здесь в операторе Write 5 элементов:

сомножитель a,

символ знака умножения '*',

сомножитель b,

символ '=',

значение произведения proizv

Усложним задачу. Попробуем заставить компьютер напечатать первую строку таблицы:

1*1= 1 1*2= 2 1*3= 3 1*4= 4 1*5= 5 1*6= 6 1*7= 7 1*8= 8 1*9= 9

Замечаем, что здесь нам нужно решить 9 элементарных задач на вычисление произведения, первую из которых решает фрагмент 1. Все они очень похожи и различаются лишь значением второго сомножителя. Таким образом, для решения каждой из 9 задач подошел бы наш фрагмент 1, если бы в нем в операторе b:=1 вместо единицы стояла нужная цифра. В данном случае идеально подходит оператор for:

Фрагмент 2

a:=1;

for b:=1 to 9 do begin

proizv:=a*b;

Write(a, '*' ,b, '=' ,proizv, ' ' )

end {for}

Для того, чтобы печать была аккуратной, оператор Write мы дополнили символом пробела ' '. Он нужен для того, чтобы отдельные столбцы таблицы не сливались.

Следующая ступень усложнения - последняя - напечатать не одну строку таблицы, а девять. Для этого фрагмент 2 должен быть выполнен 9 раз, каждый раз - с новым значением a. Чтобы этого достичь, “обнимем” фрагмент 2 оператором for точно так же, как мы это сделали с фрагментом 1.

Фрагмент 3

for a:=1 to 9 do

for b:=1 to 9 do begin

proizv:=a*b;

Write(a, '*' ,b, '=' ,proizv, ' ' )

end {for b}

end {for a}

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

VAR a,b,proizv: Integer; {1}

BEGIN {2}

for a:=1 to 9 do begin {3}

WriteLn; {4}

for b:=1 to 9 do begin {5}

proizv:=a*b; {6}

Write(a, '*' ,b, '=' ,proizv:3, ' ' ) {7}

end {for b} {8}

end {for a} {9}

END. {10}

WriteLn нужен для того, чтобы каждая новая строка таблицы начиналась с новой строки экрана.

Формат :3 означает, что на изображение произведения на экране отведено три позиции. Формат в нашем примере нужен для того, чтобы разные по количеству цифр произведения (например, 4 и 25) занимали на экране одинаковое по размеру место, а то не получится у нас аккуратных столбиков в таблице.

В целом программа иллюстрирует идею вложенных циклов, когда один, внутренний, цикл вложен внутрь другого, внешнего. У нас тело внешнего цикла (строки 4 и 5) выполняется 9 раз, а тело внутреннего (строки 6, 7 и 8) - 81 раз, так как на каждое выполнение строки 5 оно выполняется 9 раз.

Задания 53-56:

Распечатать все возможные сочетания из двух цифр - первая цифра может быть любой от 3 до 8, вторая - любой от 0 до 7. Например, 36, 44, 80.

Распечатать все возможные сочетания из четырех цифр, каждая из которых может принимать значения 1,2,3. Например, 2123, 3312, 1111.

Подсчитать количество таких сочетаний.

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

2.4.7 Поиск максимального из чисел

Задача программисту: Найти максимальное из вводимых в компьютер чисел.

Задача рыбаку: Принести домой самую большую из выловленных рыб.

Решение рыбака: Рыбак приготовил для самой большой рыбы пустое ведро. Первую пойманную рыбу рыбак не глядя бросает в это ведро. Каждую следующую рыбу он сравнивает с той, что в ведре. Если она больше, то он бросает ее в ведро, а ту, что была там раньше, выпускает в реку.

Решение программиста: Программист приготовил для самого большого числа ячейку и придумал ей название, скажем, max. Первое число программист не глядя вводит в эту ячейку. Каждое следующее число (назовем его chislo) он сравнивает с max. Если оно больше, то он присваивает переменной max значение этого числа.

Напишем программу для определения максимального из 10 вводимых чисел:

VAR i, chislo, max :Integer;

BEGIN

ReadLn(max); {первую рыбу - в ведро}

for i:=2 to 10 do begin {ловим остальных рыб:}

ReadLn(chislo); {поймали очередную рыбу}

if chislo>max then max:=chislo {и если она больше той, что в ведре, бросаем ее в ведро }

end {for};

WriteLn(max) {несем самую большую рыбу домой}

END.

Задание 57: Найти из N чисел минимальное. Каким по порядку было введено минимальное число? Указание: для номера минимального числа тоже нужно отвести специальную ячейку.

Задание 58: У вас есть данные о росте ваших одноклассников. Правда ли, что рост самого высокого отличается от роста самого низкого больше, чем на 40 см.?

2.5 Процедуры

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

Я мог бы объяснить вам процедуры, не вводя новых операторов, однако мне кажется, что лучше всего их объяснять на музыкальном примере, поэтому я предварительно расскажу вам, как заставить компьютер звучать и исполнять мелодии.

2.5.1 Компьютер звучит

Если даже в вашем компьютере нет звуковой карты, все равно он может звучать. Посмотрим, что заставляет его сделать такая программа:

USES CRT;

BEGIN

Sound(300)

END.

Пояснения:

Если мы хотим, чтобы наш компьютер настроился на работу со звуком, мы должны первой строкой программы написать Uses CRT. Подробно о том, что это значит, я расскажу в 9.1, а сейчас не будем отвлекаться.

Единственный оператор программы Sound (300) приказывает компьютеру включить ровный однообразный звук частотой 300 колебаний в секунду (герц). Слово Sound звучит “`саунд”, переводится “звук”. Для тех, кто не знает, поясню, что частота определяет высоту звука. Sound(300) - это звук средней высоты . Sound(6000) - это звук высокий, тонкий, как комариный писк. Sound(40) - звук низкий, толстый.

Итак, все действие нашей программы заключается в том, что включается звук. А что дальше? Когда он выключается? А никогда! Программа, выполнившись мгновенно, прекращает свою работу, и мы остаемся один на один со звуком. Через две-три минуты он начинает нам надоедать. Пытаясь его прекратить, мы выходим из среды Паскаля - не помогает. В общем, звук продолжается все то время, пока компьютер включен. В остальном он никак не мешает компьютеру правильно работать. Мы можем запустить другую программу - звук будет сопровождать нас. Самый простой способ избавиться от звука - перезапустить компьютер. Другой способ - выполнить программу, в которой есть оператор NoSound:

USES CRT;

BEGIN

NoSound

END.

Оператор NoSound (звучит “ноу `саунд”, переводится “нет звука”), выключает звук. Совет: Работая с любой звуковой программой, откройте еще одно окно и введите туда эту программу с NoSound. Не пожалеете!

Теперь рассмотрим такую программу:

USES CRT;

BEGIN

Sound (300); Delay (2000); NoSound

END.

Здесь мы видим новый для нас оператор Delay (2000). Он читается “ди'лэй”, переводится “отсрочка” или “пауза”. Его действие в том, что он приостанавливает работу программы на 2000 миллисекунд или, что то же самое, на 2 секунды. Delay (1000) приостанавливает работу программы на 1 секунду, Delay (500) - на полсекунды и т.д. (Должен сказать, что на самом деле продолжительность паузы сильно зависит от быстродействия компьютера).

Итак, оператор Sound (300) включает звук. Сразу после этого оператор Delay (2000) приостанавливает работу программы на 2 сек. Но звук этот оператор не может выключить, компьютер продолжает звучать. Через 2 сек программа снова оживает и выполняется оператор NoSound. Звук выключается. Таким образом, результатом выполнения этих трех операторов будет звук частотой 300 гц продолжительностью 2 сек.

Рассмотрим работу программы:

USES CRT;

BEGIN

Sound(900);Delay(1000);Sound(200);Delay(3000);NoSound

END.

Начинается она со звука частотой 900 гц и продолжительностью 1 с, а затем оператор Sound(200) включает вместо звука в 900 гц звук частотой 200 гц, который длится 3 с.

В операторах Sound и Delay вместо чисел можно записывать целочисленные переменные величины и выражения. Вот программа, производящая серию постепенно повышающихся звуков:

USES CRT;

VAR hz: Integer;

BEGIN

hz:=60;

while hz<800 do begin

Sound(hz);

Delay(1000);

hz:=hz+40

end;

NoSound

END.

Если вас интересуют музыкальные ноты, то вот вам операторы Sound, задающие все ноты третьей октавы:

Нота до

Sound(523)

Нота до диез

Sound(554)

Нота ре

Sound(587)

Нота ре диез

Sound(622)

Нота ми

Sound(659)

Нота фа

Sound(698)

Нота фа диез

Sound(740)

Нота соль

Sound(784)

Нота соль диез

Sound(831)

Нота ля

Sound(880)

Нота ля диез

Sound(932)

Нота си

Sound(988)

Задания 59-63:

59) Уменьшив как следует числа в операторах Delay(1000) и hz:=hz+40 можно добиться впечатления одного непрерывного постепенно повышающегося звука (сирена). Попробуйте сделать это.

60) Если вам это удалось, попробуйте смоделировать сирену милицейской машины: звук вверх - звук вниз - звук вверх - звук вниз - … и так несколько раз.

61) Быстро чередуя короткие звуки двух разных частот и короткие паузы, можно добиться разных звуковых эффектов и шумов, например звука телефонного звонка или моторчика авиамодели.

62) Сделайте “датчик чувствительности уха к высоким частотам”. Извстно, что человеческое ухо не может слышать звуки, частота которых превышает 10000-20000 гц. У разных людей порог чувствительности разный. Напишите программу, которая выдает звуки все более высокой частоты и печатает на экране значения этой частоты, так что человек успевает увидеть, при какой частоте он перестает слышать звук. Вы сможете определить, у кого порог чувствительности выше - у вас или у вашего друга. Удобно внутри цикла использовать команду ReadLn.

63) Если у вас есть некоторое музыкальное образование, вы можете попробовать заставить компьютер исполнить простенькую мелодию из нескольких нот.

2.5.2 Простейшие процедуры

Задача: Все вы слышали про азбуку Морзе, широко использовавшуюся раньше для радиосвязи с кораблями и не только с ними. Включив радиоприемник и покрутив ручку настройки, можно было услышать частую тоненькую дробь однотонных сигналов разной длительности: точки (очень короткие сигналы) и тире (сигналы подлиннее). Каждая буква алфавита кодируется в азбуке Морзе последовательностью точек и тире.

Вот таблица кодирования русских и латинских букв (латинские буквы показаны строчными, а русские - заглавными):

Аa

.-

Бb

-…

Вw

.--

Гg

--.

Дd

-..

Еe

.

Жv

…-

Зz

--..

Иi

..

Йj

.---

Кk

-.-

Лl

.-..

Мm

--

Нn

-.

Оo

---

Пp

.--.

Рr

.-.

Сs

Тt

-

Уu

..-

Фf

..-.

Хh

….

Цc

-.-.

Ч

---.

Ш

----

Щq

--.-

Ъ,Ьx

-..-

Ыy

-.--

Э

..-..

Ю

..--

Я

.-.-

Закодируем азбукой Морзе текст PIPING и заставим компьютер воспроизвести соответствующий набор звуков. Пусть продолжительность точки - 100 миллисекунд, тире - 200, пауза молчания после точки или тире - 80, пауза после буквы - 300. Частота звуков не играет роли, выберем наугад 900 гц.

Вот как будет выглядеть фрагмент, воспроизводящий точку:

Sound(900);Delay(100); NoSound; Delay(80)

А вот фрагмент, воспроизводящий тире:

Sound(900);Delay(200); NoSound; Delay(80)

Вот вся программа:

Программа 1

USES CRT;
BEGIN

{буква P:}

Sound(900); Delay(100); NoSound; Delay(80); {точка}

Sound(900); Delay(200); NoSound; Delay(80); {тире}

Sound(900); Delay(200); NoSound; Delay(80); {тире}

Sound(900); Delay(100); NoSound; Delay(80); {точка}

Delay(300); {пауза}

{буква I:}

Sound(900); Delay(100); NoSound; Delay(80); {точка}

Sound(900); Delay(100); NoSound; Delay(80); {точка}

Delay(300); {пауза}

{буква P:}

Sound(900); Delay(100); NoSound; Delay(80); {точка}

Sound(900); Delay(200); NoSound; Delay(80); {тире}

Sound(900); Delay(200); NoSound; Delay(80); {тире}

Sound(900); Delay(100); NoSound; Delay(80); {точка}

Delay(300); {пауза}

{буква I:}

Sound(900); Delay(100); NoSound; Delay(80); {точка}

Sound(900); Delay(100); NoSound; Delay(80); {точка}

Delay(300); {пауза}

{буква N:}

Sound(900); Delay(200); NoSound; Delay(80); {тире}

Sound(900); Delay(100); NoSound; Delay(80); {точка}

Delay(300); {пауза}

{буква G:}

Sound(900); Delay(200); NoSound; Delay(80); {тире}

Sound(900); Delay(200); NoSound; Delay(80); {тире}

Sound(900); Delay(100); NoSound; Delay(80); {точка}

Delay(300); {пауза}

END.

Недостатки программы:

Довольно большой объем, что обидно, так как в программе много одинаковых фрагментов.

Если бы не комментарии, было бы совершенно непонятно, о чем эта программа.

А теперь я напишу ту же программу, но с использованием процедур:

Программа 2

USES CRT;

PROCEDURE tochka;

BEGIN Sound(900); Delay(100); NoSound; Delay(80) END;

PROCEDURE tire;

BEGIN Sound(900); Delay(200); NoSound; Delay(80) END;

BEGIN

{буква P:} tochka; tire; tire; tochka; Delay(300);

{буква I:} tochka; tochka; Delay(300);

{буква P:} tochka; tire; tire; tochka; Delay(300);

{буква I:} tochka; tochka; Delay(300);

{буква N:} tire; tochka; Delay(300);

{буква G:} tire; tire; tochka; Delay(300);

END.

Программа 2 гораздо короче и даже без комментариев понятнее программы 1. Поясним, как мы получили ее из предыдущей.

Сначала мы обнаружили в программе 1 часто повторяющиеся фрагменты. Их было два:

Sound(900); Delay(100); NoSound; Delay(80); {точка}

Sound(900); Delay(200); NoSound; Delay(80); {тире}

Затем мы придумали имена каждому фрагменту: tochka и tire. После этого можно было писать программу 2. Каждый фрагмент мы записали один раз в начале программы выше главного BEGIN, оформив его в виде так называемого описания процедуры:

PROCEDURE tochka;

BEGIN Sound(900); Delay(100); NoSound; Delay(80) END;

PROCEDURE tire;

BEGIN Sound(900); Delay(200); NoSound; Delay(80) END;

В результате программа “узнала”, что такое tochka и tire. С этого момента имена процедур tochka и tire можно употреблять, как обыкновенные операторы, ниже главного BEGIN. Паскаль выполняет программу, начиная с главного BEGIN, и когда он натыкается на имя процедуры, он подставляет вместо него соответствующий фрагмент, взятый из описания процедуры. Это событие называется вызовом процедуры или обращением к процедуре.

Синтаксис описания простейшей процедуры таков:

PROCEDURE имя ; BEGIN оператор ; оператор ; ... END

Слово PROCEDURE читается “про'сидже”, переводится “процедура”. Имя процедуры создается по тем же правилам, что и имя переменной. Все, что идет после имени, будем называть телом процедуры.

Задание 64: Составьте программу с процедурами, которая исполнит мелодию “Чижик-пыжик” (ми-до-ми-до-фа-ми-ре-соль-соль-ля-си-до-до-до).

А теперь попробуем еще больше упростить нашу программу. Замечаем, что и в программе 2 тоже имеются одинаковые фрагменты:

{буква P:} tochka; tire; tire; tochka; Delay(300);

{буква I:} tochka; tochka; Delay(300);

Для экономии места их тоже выгодно оформить в виде процедур:

PROCEDURE P;

BEGIN tochka; tire; tire; tochka; Delay(300) END;

PROCEDURE I;

BEGIN tochka; tochka; Delay(300) END;

Остальные буквы тоже выгодно оформить в виде процедур, но уже не для экономии места, а для удобочитаемости программы. Вот окончательный вариант программы:

Программа 3

USES CRT;

PROCEDURE tochka;

BEGIN Sound(900); Delay(100); NoSound; Delay(80) END;

PROCEDURE tire;

BEGIN Sound(900); Delay(200); NoSound; Delay(80) END;

PROCEDURE P;

BEGIN tochka; tire; tire; tochka; Delay(300) END;

PROCEDURE I;

BEGIN tochka; tochka; Delay(300) END;

PROCEDURE N;

BEGIN tire; tochka; Delay(300) END;

PROCEDURE G;

BEGIN tire; tire; tochka; Delay(300) END;

BEGIN

P;I;P;I;N;G

END.

Эта программа понятна и без комментариев. От предыдущей она отличается тем, что процедуры вызываются не только из тела программы, но и из тел других процедур. Действительно, посмотрим на самое начало выполнения программы. Первое, на что натыкается Паскаль ниже главного BEGIN, это P. Заглянув выше главного BEGIN, Паскаль обнаруживает, что P - это имя процедуры, и начинает ее выполнять (вызывает на выполнение). При этом, первое, на что он натыкается, это tochka. Заглянув выше, Паскаль обнаруживает, что tochka - это имя процедуры, и тоже начинает ее выполнять (вызывает на выполнение). Обратите внимание, что вызываемая процедура должна быть описана выше вызывающей.

Такая уж особенность у Паскаля. О том, что делать, если это требование выполнить невозможно, написано в 10.6. Закончив выполнять процедуру tochka, Паскаль возвращается в процедуру P (возвращает управление процедуре P). Там он идет к следующему оператору. Это оказывается tire. И т.д.

Задание 65: Компьютер печатает текст Песня «Чижик-пыжик». 1 куплет. После этого исполняется мелодия чижика-пыжика (см. выше). Затем компьютер печатает текст 2 куплет и мелодия чижика-пыжика исполняется еще раз.

2.5.3 Процедуры и операторы

Разберемся немного с терминологией. Прежде всего уточним структуру программы на Паскале. Любая программа на Паскале состоит из двух разделов:

{Раздел описаний}

BEGIN

{Раздел операторов}

END.

Раздел описаний может и отсутствовать, если же он присутствует, то может содержать разделы VAR, LABEL, USES, PROCEDURE и другие, нами еще не изученные.

Раздел операторов состоит из операторов, разделенных точками с запятой.

В самом начале части II я упомянул, что многие операторы на Паскале являются обращениями к процедурам. Для простоты мы договорились не различать поначалу обращения к процедурам и другие операторы. Сейчас нам пора этому научиться. Кроме процедур, написанных нами (таких как tochka, tire и др.), существуют еще так называемые стандартные процедуры Паскаля. Мы уже изучили следующие стандартные процедуры: Write, WriteLn, Read, ReadLn, Sound, Delay, NoSound. Они называются стандартными, потому что определены “внутри Паскаля” точнее, внутри стандартных модулей Паскаля, о которых вы узнаете позже и ими можно пользоваться, не описывая их, как мы описывали созданные нами “пользовательские” процедуры. Природа пользовательских и стандартных процедур едина, поэтому мы будем называть и те и другие просто процедурами. Операторами же мы будем продолжать называть операторы goto, if, case, for, while, repeat, оператор присваивания, составной оператор и еще незнакомые нам оператор with и пустой оператор.

2.5.4 Стандартные процедуры Halt и Exit

Halt читается “хальт”, переводится с немецкого “стой”.

Exit читается “ `экзит”, переводится с английского “выход”.

До сих пор мы составляли программы, которые заканчивали свою работу на END с точкой, не раньше. Процедура Halt заставляет Паскаль завершить работу программы, не доходя до конечного END с точкой. Пример: программа

BEGIN Write(1); Write(2); Halt; Write(3) END.

напечатает 12, а программа

PROCEDURE a; BEGIN Write(6); Halt; Write(7); END;

BEGIN Write(2); a; Write(3); Halt; Write(4) END.

напечатает 26.

Обращение к процедура Exit, если оно встречается в процедуре, заставляет Паскаль вернуться в процедуру, ее вызвавшую. Пример: заменим в предыдущей программе первый из двух Halt на Exit и посмотрим, что будет. А будет то, что программа

PROCEDURE a; BEGIN Write(6); Exit; Write(7); END;

BEGIN Write(2); a; Write(3); Halt; Write(4) END.

напечатает 263.

Если Exit встречается в разделе операторов программы, то он, подобно Halt, вызывает выход из программы.

Задание 66:

Вот вам программа с процедурами. Вам нужно, не запуская ее, записать на бумажке весь разговор, который ведут герои “Трех мушкетеров”.

PROCEDURE ATOS;

begin WriteLn ('Я - Атос') end;

PROCEDURE ARAMIS;

begin WriteLn ('Это так же верно,как то,что я -Арамис!') end;

PROCEDURE PORTOS;

begin WriteLn ('А я Портос! Я правильно говорю, Арамис?');

Aramis;

WriteLn ('Он не врет, ваше величество! Я Портос, а он Арамис.') end;

PROCEDURE DARTANIAN;

begin WriteLn ('А я все думаю, ваше величество - куда девались подвески королевы?');

Exit;

WriteLn ('Интересно, что ответит король?');

Portos end;

BEGIN

WriteLn ('Я, король Франции, спрашиваю вас - кто вы такие? Вот ты - кто такой?');

Atos;

WriteLn ('А ты, толстяк, кто такой?');

Portos;

WriteLn ('А ты что отмалчиваешься, усатый?');

dArtanian;

WriteLn ('Анна! Иди-ка сюда!!!');

Halt;

WriteLn ('Аудиенция закончена, прощайте!');

END.

Выполнив задание, скопируйте программу в редактор Паскаля и запустите ее. Если ответ не сходится, запустите ее в отладочном пошаговом режиме.

Теперь вы достаточно знаете о процедурах, чтобы они стали для вас удобными кирпичиками для постройки программ. Более мощным средством являются процедуры с параметрами, о которых вы узнаете в Глава 13.

2.6 Графика

Если в предыдущих главах на экране изображались только буквы, цифры и прочие символы, то эта глава научит вас рисовать.

2.6.1 Стандартные модули

В 2.5 я говорил, что при работе с языком программирования мы реально работаем с комплексом программ, позволяющим программисту создавать собственные программы, пользуясь при этом значительным количеством готовых процедур (а сейчас мы уточним - стандартных процедур и функций, и других элементов). На данный момент мы знаем следующие стандартные процедуры языка Паскаль: Write, WriteLn, Read, ReadLn, Sound, Delay, NoSound, Exit, Halt. Вспомним теперь, что для того, чтобы вообще быть выполненной, программа должна находиться в оперативной памяти компьютера. Паскаль - это программа. Значит, для того, чтобы мы могли работать с Паскалем, все стандартные процедуры Паскаля тоже должны находиться в памяти? Однако, память - вещь дефицитная и ее нужно экономить. Хорошо бы в память загружались не все процедуры, а только те, которые нужны данному программисту. Действительно, во многих приведенных в этой книге программах мы не использовали звук, зачем же нам было иметь в памяти процедуры Sound и NoSound?

Реально так и сделано. В Паскале определен целый ряд необязательных его кусков, которые называются стандартными модулями. Упрощенно говоря, стандартный модуль является сборником процедур и других элементов, которые загружаются с диска в память только тогда, когда программист специально попросит. Один из этих модулей называется CRT и кроме всего прочего занимается звуком. Другой называется Graph и дает возможность программисту работать с изображениями на экране. С некоторыми другими стандартными модулями мы познакомимся позже.

Если программист специально не попросил, то в памяти оказывается только минимальная часть Паскаля, которая нужна более-менее всем.

А как же попросить? Очень просто. Если вам нужно работать со звуком, вы пишете первой строкой своей программы - USES CRT, а если вы собираетесь работать с изображениями, то - USES Graph. USES читается “'юзез”, переводится “использует”. Значит, строка USES CRT является приказом компьютеру “использовать стандартный модуль CRT”, для чего загрузить в память те его процедуры и другие элементы, которые требует программа.

Вот так, довольно грубо я обрисовал идею использования стандартных модулей. Если же программист видит, что их возможностей ему не хватает, он может написать несколько процедур и создать из них свой собственный модуль, придумать ему имя и пользоваться затем точно так же, как стандартными. Об этом написано в 15.3.

2.6.2 Стандартный модуль Graph, текстовый и графический режимы

Graph читается “граф”, это сокращение слова “графика”. Если мы напишем первой строкой своей программы USES Graph, то Паскаль предоставит в наше распоряжение целый ряд процедур и других средств, позволяющих нам рисовать на экране разноцветные точки, отрезки прямых, дуги, закрашенные и незакрашенные окружности, прямоугольники, а также выполнять ряд других действий. Пользуясь этими возможностями, мы очень скоро напишем программы, рисующие причудливые картинки и заставляющие изображения двигаться по экрану. С помощью модуля CRT мы научимся управлять этим движением с клавиатуры, а значит сможем создавать свои собственные компьютерные игры. В 10.9 я объясню создание игры “Торпедная атака”.

А в этой главе я опишу работу самых популярных с моей точки зрения процедур модуля Graph.

2.6.2.1 Текстовый и графический режимы

Существуют два режима (способа) работы компьютера с монитором - текстовый и графический. В любом месте программы вы можете приказать компьютеру переключиться из одного режима в другой.

Текстовый режим используется для вывода на экран текстовой и числовой информации. Работая в текстовом режиме, компьютер считает экран разбитым на 25 строк и 80 столбцов, иногда на другое количество. В каждой из получившихся клеточек умещается ровно одна буква или цифра или знак препинания или любой другой символ. Какой именно символ будет находиться в клеточке, диктуете вы в вашей программе. Рисовать и показывать картинки компьютер в текстовом режиме не может.

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

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

Во всех написанных ранее программах мы ничего не говорили об этих режимах, мы молчали о них. Если мы в программе специально не просим, то Паскаль всегда выбирает текстовый режим. Говорят, что текстовый режим в Паскале используется по умолчанию.

2.6.2.2 Переключение между текстовым и графическим режимами

Итак, если вы собираетесь работать с изображениями, то должны переключиться в графический режим и для этого пишете первой строкой программы USES Graph. Но сама по себе эта строка не является указанием компьютеру переключиться в графический режим, хотя бы потому, что находится в разделе описаний, а не в разделе операторов. Для переключения в графический режим (или, как говорят, для инициализации графического режима) служит стандартная процедура InitGraph. Для того, чтобы закрыть графический режим и снова переключиться в текстовый, служит стандартная процедура CloseGraph.

(Начиная с этого момента я не буду приводить переводы и произношение английских слов. Многие из них приведены в приложении П3 и П4.)

Вот пример программы, которая сначала в текстовом режиме пишет на экране текст “Это текстовый режим”, затем переключается в графический режим, рисует окружность, а затем снова переключается в текстовый режим и пишет “Это снова текстовый режим”:

USES Graph;

VAR Device, Mode : Integer;

BEGIN

WriteLn(`Это текстовый режим');

{Инициализируем графический режим:}

ReadLn;

Device:=0;

InitGraph(Device, Mode, '<путь к графическим драйверам>');

Circle(100,80,50); {Обращение к процедуре рисования окружности. Пока без пояснений}

ReadLn;

{Закрываем графический режим, что рекомендую:}

CloseGraph;

WriteLn(`Это снова текстовый режим');

ReadLn

END.

Пояснения: Перед использованием процедуры InitGraph необходимо создать две переменные величины типа Integer с произвольными именами (я использовал имена Device и Mode). Обе эти переменные при обращении к процедуре InitGraph должны быть записаны внутри круглых скобок. Вам на первых порах совершенно не обязательно это знать, но поясню, что Device означает тип вашего видеоадаптера (CGA, EGA, VGA или другой), а Mode означает номер графического режима. Если вы ничего не знаете ни о том, ни о другом, смело пишите Device := 0 и Паскаль сам определит тип вашего видеоадаптера и установит самый мощный из допустимых графический режим.

Третий элемент - не что иное, как путь к графическим драйверам Паскаля. Я использовал угловые скобки <>, чтобы подчеркнуть, что в вашей программе нужно писать не те четыре русских слова, что внутри угловых скобок, а то, на что они указывают. Почти наверняка для вас графический драйвер представлен файлом egavga.bgi, расположенном в каталоге BGI. Если сам Паскаль расположен в каталоге TP диска c, то строка вашей программы будет выглядеть так:

InitGraph(Device, Mode, `c:\TP\BGI')

Если вы ее записали верно, то можете попытаться запустить программу, и при правильной настройке Паскаля у вас все получится. Тех, кто не знает, что такое каталоги и файлы, отсылаю к приложению.

Если Паскаль при запуске графического режима жалуется (File not found (GRAPH.TPU)), то прочтите «Обзор популярных команд меню» из части IV. Там сказано, что делать.

Учтите, что при переключении режимов все содержимое экрана стирается.

2.6.3 Рисуем простейшие фигуры

Начиная с этого момента я буду для определенности считать, что графический режим вашего монитора считает экран разделенным на 640 пикселов в ширину и 480 в высоту и исходя из этого буду писать программы. Если у вас режим другой, то вы легко сможете сделать поправки в программах.

Попробуем нарисовать точку и прямоугольник. Пусть мы хотим их видеть в следующем месте экрана:

Для этого мы пишем обращения к двум процедурам:

Для точки - PutPixel (14,6, Yellow)

Для прямоугольника - Rectangle (4,2,16,10)

Как видим, при обращении к процедуре PutPixel в скобках нужно указывать три элемента, у Rectangle - четыре. Будем называть элементы, разделенные запятыми внутри скобок, параметрами процедур.

Смысл параметров процедур PutPixel и Rectangle ясен из рисунка. В PutPixel первый параметр - горизонтальная координата точки, второй - вертикальная, третий - цвет точки (желтый). В Rectangle первая пара параметров - координаты любого из углов прямоугольника, вторая пара - координаты противоположного ему угла (только не соседнего). В каждой паре первой идет горизонтальная координата, второй - вертикальная. Цвет прямоугольника задается в другой процедуре, о которой разговор позже.

Модуль Graph позволяет удобно использовать всего лишь 16 цветов. Вот они:

0

Black

Черный

1

Blue

Синий

2

Green

Зеленый

3

Cyan

Голубой

4

Red

Красный

5

Magenta

Фиолетовый

6

Brown

Коричневый

7

LightGray

Светлосерый

8

DarkGray

Темносерый

9

LightBlue

Ярко-синий

10

LightGreen

Ярко-зеленый

11

LightCyan

Ярко-голубой

12

LightRed

Розовый

13

LightMagenta

Малиновый

14

Yellow

Желтый

15

White

Белый

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

В обращениях к процедурам, имеющим дело с цветом, вместо английского названия цвета можно писать соответствующее число. Например, вместо PutPixel(14,6, Yellow) можно написать PutPixel(14,6, 14).

В школе вы привыкли к такой системе координат:

В компьютере же применяется такая:

Как видите, ось у направлена вниз. Это не очень привычно. Если вас это раздражает, то в 13.2 вам будет предложено исправить ситуацию.

Напишем программу, которая рисует точку, прямоугольник, окружность и отрезок прямой так, как это показано на рисунке:

USES Graph;

VAR Device, Mode: Integer;

BEGIN

Device:=0;

InitGraph(Device, Mode, '<путь к графическим драйверам>');

PutPixel(50,100,White);

Rectangle(150,150,50,200); {правый верхний и левый нижний углы}

Circle(200,100,50); {окружность}

Line(100,50,250,150); {отрезок прямой}

ReadLn;

CloseGraph

END.

Пояснения: Отрезок прямой рисуется процедурой Line. Мы знаем, что отрезок прямой можно построить, если известно положение его двух крайних точек. Они-то и задаются в обращении к процедуре. Первая пара параметров - координаты одной точки (любой из двух), вторая пара - другой.

Окружность можно построить, если известно положение центра и радиус. Окружность рисуется процедурой Circle, первые два параметра которой - координаты центра, третий - радиус.

Попробуем теперь нарисовать эллипс с центром в точке х=200, у=150, вот такой:

Это выполнит процедура Ellipse. Вот ее вызов - Ellipse (200,150,0,360,100,40).Если вы хотите нарисовать не полный эллипс, а только часть его, вместо 0 укажите начальный угол дуги эллипса, скажем 90, а вместо 360 - конечный угол, скажем 180.

Процедура ClearDevice стирает все с экрана в графическом режиме.

Задание 67: Нарисуйте снеговика:

2.6.4 Работа с цветом. Заливка. Стиль линий и заливки

Сначала поговорим о стиле линий. Если вы хотите, чтобы линии, которыми чертятся фигуры, были потолще, используйте процедуру SetLineStyle. Вот ее вызов - SetLineStyle (0, 0, ThickWidth). Это приказ отныне рисовать линии толстыми. Если вы хотите вернуться к тонким линиям, напишите SetLineStyle(0, 0, NormWidth).

Первый параметр процедуры SetLineStyle управляет стилем прямых отрезков (штриховые, пунктирные и др.). Попробуйте вместо 0 написать 1, 2 или 3 и посмотрите, что получится.

Второго параметра касаться не будем.

А теперь поговорим о цвете. Если цвет точки задается непосредственно в вызове процедуры, которая рисует точку (PutPixel), то цвета многих других фигур задаются по-иному. Делает это специальная процедура SetColor. Пример: SetColor(Yellow) приказывает компьютеру отныне рисовать фигуры желтым цветом.

Вот поясняющий фрагмент:

Circle(100,100,20); {окружность белая и тонкая, так как по умолчанию

{Паскаль все рисует белым цветом тонкими линиями}

SetColor(Yellow);

Circle(150,100,20); {желтая тонкая окружность }

SetLineStyle(0, 0, ThickWidth);

Circle(200,100,20); {желтая толстая окружность}

SetColor(Blue);

SetLineStyle(0, 0, NormWidth);

Circle(250,100,20); {синяя тонкая окружность}

Работая в Паскале, вы можете покрасить любым цветом (залить краской) любую область экрана внутри замкнутого контура. Пусть вы нарисовали такую картинку:

После этого вы можете ее покрасить, например, вот так:

Как красить? Начнем с процедуры SetFillStyle. Подобно тому, как процедура SetColor сама ничего не рисует, а только устанавливает цвет линий на будущее, процедура SetFillStyle сама ничего не заливает, а устанавливает цвет и стиль заливки на будущее. Например, SetFillStyle(1, Green) устанавливает заливку зеленым цветом. На единичку пока не обращаем внимания.

Сам процесс заливки вызывает процедура FloodFill. Например, FloodFill(200, 150, Blue) вызывает следующие действия Паскаля:

В точке экрана с координатами х=200 и у=150 встает “маляр с ведром краски”, цвет которой был указан в обращении к процедуре SetFillStyle (в нашем примере - зеленый), и начинает эту краску разливать вокруг себя. Краска свободно растекается по экрану и преградой для нее становится только линия, имеющая цвет, указанный в обращении к процедуре FloodFill, то есть синий. Очевидно, если синий контур не будет замкнут вокруг “маляра”, то краска прольется на весь экран.

Пример: Следующий фрагмент нарисует желтый квадрат и зальет его красным цветом:

SetColor(Yellow);

SetFillStyle(1, Red);

Rectangle(200,50,300,150);

FloodFill(250, 100, Yellow)

А теперь попробуем поставить “маляра” вне квадрата, записав в нашем фрагменте вместо FloodFill(250, 100, Yellow) например, FloodFill(250, 200, Yellow). Теперь красной будет вся поверхность экрана, кроме области внутри квадрата.

Распространенная ошибка новичков - на вопрос о том, каким цветом будет красить оператор FloodFill(250, 100, Yellow), они отвечают “Желтым”, хотя нужно отвечать “Не знаю, надо посмотреть в SetFillStyle”.

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

Для этого поместим “маляра” внутрь этого прямоугольника и используем операторы SetFillStyle(1, Yellow) и FloodFill( , ,Blue ). Мы получим следующую картину:

Очевидно, при помощи FloodFill нужный прямоугольник закрасить невозможно, так как он ограничен линиями разного цвета.

Заливку можно делать не только сплошной, но и по-разному заштрихованной. Для этого вместо единички в обращении к процедуре SetFillStyle попробуйте другие целые числа - 2, 3 и др.

Задание 68: Усовершенствуйте снеговика из 9.3. Он должен стать таким - с красным носом, красными губами, желтой шапкой и толстым синим посохом. При помощи оператора WriteLn сделайте надпись “Это снеговик”.

2.6.5 Используем в рисовании переменные величины

Если вы нарисовали снеговика, то наверное согласитесь, что для этого вам пришлось основательно потрудиться, хотя сам рисунок не слишком богат, в нем всего порядка десяти элементов.

Как заставить Паскаль короткой программой рисовать множество элементов? Ответ: применять циклы, используя в обращениях к графическим процедурам вместо чисел переменные величины и арифметические выражения.

Задача: Нарисовать горизонтальный ряд окружностей радиусом 10 на расстоянии 100 от верхнего края экрана и с такими горизонтальными координатами 50, 80, 110, 140, , 290.

Как видим, центры соседних окружностей отстоят друг от друга на 30. Вот примитивный фрагмент, решающий эту задачу:

Circle( 50,100,10);

Circle( 80,100,10);

Circle(110,100,10);

Circle(140,100,10);

Circle(170,100,10);

Circle(200,100,10);

Circle(230,100,10);

Circle(260,100,10);

Circle(290,100,10);

При вводе этой программы вас будет раздражать необходимость вводить много раз почти одно и то же. Воспользуйтесь копированием, которое объяснено в параграфе «Копирование и перемещение фрагментов текста» из части IV.

Мы видим, что здесь Паскаль 9 раз выполнит одну и ту же процедуру, причем при каждом следующем обращении первый параметр вырастает на 30.

А теперь решим эту же задачу при помощи цикла.

Придумаем для первого параметра переменную величину, например, х. Чтобы х изменялся, организуем цикл repeat. Вот программа решения задачи:

USES Graph;

VAR x, Device, Mode :Integer;

BEGIN

Device:=0;

InitGraph(Device, Mode, '<путь к графическим драйверам>');

x:=50;

repeat

Circle(x,100,10);

x:=x+30;

until x>290;

ReadLn;

CloseGraph

END.

Задание 69:. Попробуйте уменьшить расстояние между центрами окружностей, не изменяя их радиуса, нарисовав их плотнее, чтобы они пересекались, еще плотнее, пока они не образуют “трубу”.

Задание 70:. Удлините трубу налево и направо до краев экрана.

Задание 71:. Увеличьте толщину трубы.

Заставим окружности вести себя посложнее. Например, расположим их не по горизонтали, а по диагонали экрана в направлении от левого верхнего угла в правый нижний. Для этого организуем еще одну переменную - вертикальную координату у - и заставим ее тоже изменяться одновременно с x.

USES Graph;

VAR x, y, Device, Mode : Integer;

BEGIN
Device:=0;

InitGraph(Device, Mode, '<путь к графическим драйверам>');

x:=50;

y:=20;

repeat

Circle(x,y,10);

x:=x+30;

y:=y+20;

until x>290;

ReadLn;

CloseGraph

END.

Если мы захотим менять радиус, то организуем переменную R, тоже типа Integer.

Задание 72:. Нарисуйте ряд точек по направлению из левого нижнего угла в правый верхний.

Задание 73:. “Круги на воде”. Нарисуйте пару десятков концентрических окружностей, то есть окружностей разного радиуса, но имеющих общий центр.

Задание 74:. “Компакт-диск”. Если радиус самого маленького “круга на воде” будет порядка 50, а самого большого - во весь экран, и если радиусы соседних окружностей будут различаться на 2-3 пиксела, то на экране вы увидете привлекательный “компакт-диск”. Сделайте его золотым (Yellow).

Задание 75:. Не трогая x, а меняя только y и R, вы получите коническую башню.

Задание 76:. Меняя все три параметра, вы получите трубу, уходящую в бесконечность.

Задание 77:. Разлинуйте экран в линейку.

Задание 78:. А теперь в клетку.

Задание 79:. А теперь в косую линейку.

Задание 80:. Начертите ряд квадратов.

Чтобы получить богатые рисунки, нужно использовать богатые возможности Паскаля: вложенные циклы, ветвление внутри цикла и т.д., например:

Задание 81:. Нарисуйте шахматную доску.

Задание 82:. “Ковер”. В задании 69 вы рисовали горизонтальный ряд пересекающихся окружностей. Теперь нарисуйте один под другим много таких рядов.

Указания: Здесь вам понадобятся вложенные циклы. Если центры соседних окружностей отстоят друг от друга на одинаковое расстояние что по горизонтали, что по вертикали, и если удачно подобраны остальные числа, то у вас получится красивый ковер во весь экран с аккуратными краями.

Задание 83:. Пусть у этого ковра будет вырезан левый нижний угол.

Задание 84:. и вдобавок вырезан квадрат посередине.

2.6.6 Использование случайных величин при рисовании

Как получить случайное число? Давайте сначала напечатаем его. Для этого подойдет функция Random из 4.9. WriteLn(Random(100)) напечатает целое неотрицательное число, какое - мы заранее не знаем, знаем только, что меньше 100. Легко догадаться, что WriteLn (500 + Random(100)) напечатает случайное число из диапазона от 500 до 599.

Попробуем нарисовать “звездное небо”. Для этого достаточно в случайных местах экрана нарисовать некоторое количество разноцветных точек (скажем, 1000). Точка ставится процедурой PutPixel. Как сделать координаты и цвет точки случайными? Тот же Random. Если ваш экран имеет размер 640480 пикселов, то обращение к процедуре рисования одной точки случайного цвета будет выглядеть так:

PutPixel (Random(640), Random(480), Random(16))

Число 16 взято по той причине, что все цвета в Паскале имеют номера от 0 до 15.

Для того, чтобы таких точек было 1000, используем цикл for:

for i:=1 to 1000 do PutPixel (Random(640), Random(480), Random(16))

Имейте в виду, что сколько бы раз вы не запускали программу с указанным фрагментом, картина созвездий на экране будет абсолютно одинакова. Если вам нужно, чтобы от запуска к запуску набор значений случайной величины менялся (а значит и созвездия), употребите разик до использования функции Random процедуру Randomize. Вот так:

Randomize;

for i:=1 to 1000 do PutPixel (Random(640), Random(480), Random(16))

Задание 85:. “Дождь в луже”. Заполните экран окружностями радиуса 20 в случайных местах.

Задание 86:. “Цирк”. То же самое случайных радиусов и цветов.

Задание 87:. “Звезды в окне”. Звездное небо в пределах прямоугольника.

2.6.7 Движение картинок по экрану

Идею создания иллюзии движения картинок по экрану я объяснил в 2.8. Попробуем заставить двигаться по экрану слева направо окружность. Для этого мы должны сначала нарисовать слева окружность и тут же стереть ее, для чего нарисовать ее на том же месте, но черным цветом. Несмотря на то, что мы окружность тут же стерли, она успеет мелькнуть на экране, и глаз это заметит. Затем нужно нарисовать и стереть такую же окружность чуть правее, затем еще правее и т.д. Вот программа:

USES Graph;

VAR x, Device, Mode : Integer;

BEGIN

Device:=0;

InitGraph(Device, Mode, '<путь к графическим драйверам>');

ReadLn; {Переключение в графический режим иногда занимает одну-две секунды, поэтому, если вы хотите увидеть движение с самого начала, щелкните по клавише ввода через пару секунд}

x:=40;

repeat

SetColor(White);

Circle(x,100,10); {Рисуем белую окружность}

SetColor(Black);

Circle(x,100,10); {Рисуем черную окружность}

x:=x+1 {Перемещаемся немного направо}

until x>600;

CloseGraph

END.

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

Задание 88:. Измените скорость движения. Если окружность движется небыстро, увеличьте скорость (x:=x+2), если слишком быстро - уменьшите процедурой Delay.

Задание 89:. Пусть одновременно движутся две окружности.

Задание 90:. Одна вниз, другая направо.

Задание 91:. Заставьте окружность отскочить от правого края экрана.

Задание 92:. Заставьте окружность бесконечно двигаться, отскакивая от правого и левого краев экрана.

Если вы будете рисовать окружности толстой линией, то увидите, что движение сильно замедлилось, так как толстая линия рисуется гораздо дольше тонкой. То же относится и к закрашенной окружности.

Задание 93:. “Биллиардный шар”. Нарисуйте «биллиардный стол» - большой прямоугольник. Окружность под углом летает по столу, отскакивая от его краев по закону отражения. Попав “в лузу” (любой из четырех углов стола), останавливается.

Задание 94: Изобразите полет камня, брошенного с башни, для задания из 6.3. Напоминаю условие задания. Камень бросили горизонтально со 100-метровой башни со скоростью v=20м/с. Его расстояние от башни по горизонтали (s) выражается формулой s=v*t, где t - время полета камня в секундах. Высота над землей h выражается формулой h=100 - 9.81*t2/2. Нарисуйте башню, землю, камень (маленькая окружность). Затем камень летит. Добейтесь, чтобы время полета камня на экране примерно соответствовало реальному времени, полученному в 6.3. Нарисуйте траекторию полета камня. Для этого достаточно, чтобы камень оставлял за собой следы в виде точек.

Указание: В задаче говорится о метрах, а на экране расстояние измеряется в пикселах. Поэтому вам придется задать масштаб, то есть вообразить, что один пиксел равен, скажем, одному метру. Тогда высота башни будет равна 100 пикселам, а скорость камня - 20 пикселов в секунду Правда, картинка на экране в этом случае может показаться вам маловатой. Тогда можете задать другой масштаб - один метр, скажем, - четыре пиксела. Тогда высота башни будет равна 400 пикселам, скорость камня - 80 пикселов в секунду, а формула изменится - h=4*(100 - 9.81*t2/2).


Подобные документы

  • Развертывание системы на жестком диске, диалоговая система программирования Турбо Паскаль, запуск программы и выполнение задания. Функциональные клавиши и их назначение. Текстовый редактор, средства создания и редактирования текстов программ, курсор.

    реферат [18,6 K], добавлен 01.04.2010

  • Основные сведения о системе программирования Турбо Паскаль. Структура программы на Паскале и ее компоненты. Особенности и элементы языка Турбо Паскаль. Порядок выполнения операций в арифметическом выражении, стандартные функции и оператор присваивания.

    лекция [55,7 K], добавлен 21.05.2009

  • Особенности использования графического режима в среде Турбо Паскаль. Типы драйверов. Инициализация графики. Построение изображения на экране. Графические примитивы и работа с текстом. Разработка и реализация программ в среде Турбо Паскаль "Графика".

    курсовая работа [1,2 M], добавлен 26.09.2014

  • Особенности программирования на языке Паскаль в среде Турбо Паскаль. Линейные алгоритмы, процедуры и функции. Структура данных: массивы, строки, записи. Модульное программирование, прямая и косвенная рекурсия. Бинарный поиск, организация списков.

    отчет по практике [913,8 K], добавлен 21.07.2012

  • Язык программирования Турбо Паскаль. Запись алгоритма на языке программирования и отладка программы. Правила записи арифметических выражений. Стандартное расширение имени файла, созданного системным редактором. Составной оператор и вложенные условия.

    курсовая работа [75,0 K], добавлен 21.03.2013

  • Использование графических возможностей Турбо Паскаля, подключение графического модуля Graph. Графические функции и процедуры. Общая структура графической программы. Построение фигур, определение цветов и стилей, работа с текстом, сообщения об ошибках.

    реферат [109,3 K], добавлен 28.04.2010

  • Правила описания множественных типов данных, приемов использования множеств и операций над множествами в Паскаль-программах. Разработка в Турбо Паскале программы вывода всех согласных букв, которые входят хотя бы в одно слово заданного предложения.

    контрольная работа [30,8 K], добавлен 25.12.2010

  • Освоение технологии структурного программирования и применения стандартных методов работы с одномерными массивами при разработке и создании программы на языке Турбо Паскаль. Разработка программы методом пошаговой детализации с помощью псевдокода.

    реферат [276,9 K], добавлен 27.02.2008

  • Разработка программы, создающей и управляющей базой данных, ее реализация на языке Turbo Pascal. Организация алгоритма программы. Вывод информации и возможность добавления информации в базу данных. Поиск информации в базе данных по заданному значению.

    курсовая работа [26,7 K], добавлен 19.06.2010

  • Расчет на устойчивость в системе программирования Турбо Паскаль. Определение критического напряжения стержня по формуле Ясинского, предельной гибкости в зависимости от материала. Программирование алгоритма расчета. Порядок ввода исходных данных.

    курсовая работа [1,0 M], добавлен 27.04.2013

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.