Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Тurbo Pascal 7+.doc
Скачиваний:
12
Добавлен:
24.12.2018
Размер:
10.09 Mб
Скачать

12.15. Расположение информации в оперативной памяти. Адреса

Раньше мы рассматривали оперативную память в виде тетрадного листа в клетку, где каждая клетка являлась байтом. Теперь представим оперативную память в виде многоэтажного дома, где каждый этаж – байт.

Как и положено этажам, байты имеют номера. Эти номера называются адресами. Самый "нижний" байт имеет адрес 0, следующий - 1, следующий - 2 и т. д. Если память вашего компьютера имеет объем 1 мегабайт, то вы сами можете вычислить адрес последнего байта, учитывая, что 1 мегабайт = 1024 килобайт, а 1 килобайт = 1024 байтам. Приняты сокращения: мегабайт - М, килобайт - К. Имейте в виду, что во многих книгах адреса записываются не в привычном нам виде, а в так называемой шестнадцатеричной системе счисления.

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

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

Глава 13. Процедуры и функции с параметрами

13.1. Процедуры с параметрами

Поставим и решим задачу, данную вам в качестве задания в разделе 8.2: "Составить программу с процедурами, которая исполнит мелодию (ми — до — ми — до — фа — ми — ре — соль — сольлясидододо)".

Воспользуемся нотами третьей октавы:

USES CRT;

PROCEDURE doo; BEGIN Sound(523); Delay(2000); NoSound END;

PROCEDURE re; BEGIN Sound(587); Delay(2000); NoSound END;

PROCEDURE mi; BEGIN Sound(659); Delay(2000); NoSound END;

PROCEDURE fa; BEGIN Sound(698); Delay(2000); NoSound END;

PROCEDURE sol; BEGIN Sound(784); Delay(2000); NoSound END;

PROCEDURE la; BEGIN Sound(880); Delay(2000); NoSound END;

PROCEDURE si; BEGIN Sound(988); Delay(2000); NoSound END;

BEGIN

mi; doo; mi; doo; fa; mi; re; sol; sol; la; si; doo; doo; doo

END.

Все процедуры в нашей программе всегда делают одно и то же. Например, процедура doo всегда издает звук частотой 523 Гц и продолжительностью 200 мс. Происходит это потому, что в описании процедур мы использовали не переменные величины, а константы.

В реальной музыке ноты принадлежат разным октавам и имеют разную длительность. Чтобы получить ноту четвертой октавы, достаточно умножить частоту одноименной ноты третьей октавы на 2. Например, нота ре четвертой октавы имеет частоту 587 * 2 = 1174 Гц. Естественно, все ноты четвертой октавы звучат выше нот третьей октавы. Пятая октава получается из четвертой так же, как

четвертая из третьей и звучит еще выше. Ноты второй октавы, наоборот, получаются из нот третьей октавы делением частоты на 2.

Поставим задачу - создать более универсальную процедуру Чтобы заставить ноту звучать по-разному, используем переменные величины. Здесь мы применим ту же самую идею, которую мы использовали в процедуре House из главы 10, она рисовала дом в разных местах экрана в зависимости от значений переменных величин, задающих его координаты. Для простоты ограничимся пока одной нотой ре и двумя октавами - третьей и четвертой. Длительность звучания пусть будет любая. Пусть программа должна воспроизвести подряд 3 ноты ре: сначала третья октава - 1 с, затем четвертая октава - 1 с и затем третья октава - 3 с.

USES CRT;

VAR octava :Byte;

dlit :Word;

PROCEDURE re;

BEGIN

if octava = 3 then Sound(587) else Sound(1174);

Delay(dlit);

NoSound

END;

BEGIN

octava:=3; dlit:=1000; re; octava:=4; dlit:=1000; re; octava:=3; dlit:=2000; re

END.

Недостаток программы в том, что раздел операторов выглядит довольно непонятно. Гораздо "прозрачнее" была бы такая запись:

BEGIN

re(3,1000); re(4,1000); re(3,2000)

END.

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

USES CRT;

PROCEDURE re (octava: Byte; dlit: Word);

BEGIN

if octava = 3 then Sound(587) else Sound(1174);

Delay(dlit);

NoSound

END;

BEGIN

re(3,1000);re(4,1000);re(3,2000)

END.

Пояснения. Эта программа похожа на предыдущую, но имеется несколько отличий. Строка

PROCEDURE re (octava: Byte; dlit: Word)

называется заголовком процедуры. Здесь после имени процедуры -re - ставятся скобки и внутри их описываются так называемые формальные параметры процедуры. Здесь их два: octava и dlit. Поскольку они описаны в заголовке, пропадает необходимость в разделе VAR.

В записи re (3,1000) числа 3 и 1000 - так называемые фактические параметры процедуры, их порядок и тип должен соответствовать формальным параметрам.

Если во время выполнения программы Паскаль встречает re (4,1000), он присваивает переменной octava значение 4, переменной dlit - значение 1000 (то есть присваивает формальным параметрам значения фактических параметров) и затем, переходит к выполнению тела процедуры re.

Для усложнения задачи создадим универсальную процедуру nota, параметрами которой будут название ноты, октава и длительность. Учтем, что длительность ноты в музыке задается в так называемых долях. Доли бывают: 1 - целая нота, 1/2 - половинка длительности, 1/4 - четвертушка и т. д. Пусть целая нота звучит 1 с. Вызывать процедуру nota можно было бы так: nota(re,5,8) - это означает, что мы хотим, чтобы прозвучала нота re пятой октавы длительности 1/8.

Вот запись программы:

USES CRT;

TYPE Nota_type = (doo, doo_diez, re, re_diez, mi, fa, fa_diez, sol, sol_diez, la, la_diez, si);

PROCEDURE Nota(Nazvanie:Nota_type; Oktava,Dolya:Byte); {Здесь параметр Dolya - знаменатель доли}

VAR Hz :Word; {Внутри процедуры можно описывать свои переменные (в данном примере это Hz) они называются локальными подробнее о них - в разделе 13.3}

BEGIN

{Объясним Паскалю частоту нужных нам нот третьей октавы}

case Nazvanie of

doo :Hz:=523;

re :Hz:=587;

sol :Hz:=784;

la :Hz:=880;

la_diez :Hz:=932;

end;

{Теперь меняем частоту в зависимости от октавы}

case Oktava of

1 :Hz:=Hz div 4; {Используем целочисленное деление.так как стандартная}

2 :Hz:=Hz div 2; {процедура Sound требует задавать частоту целым}

3 :Hz:=Hz; {числом герц}

4 :Hz:=Hz*2;

5 :Hz:=Hz*4;

6 :Hz:=Hz*8;

else WriteLn('Taкoй октавы не знаю'); ReadLn; Halt

end;

Sound (Hz); {Включаем звук}

Delay(10000 div Dolya); {Задаем продолжительность звука}

NoSound;

Delay (50); {Небольшой промежуток без звука после каждой ноты}

end;

BEGIN

{Вот первые ноты из песни "Широка страна моя родная":}

Nota(re,3,8); Nota(re,3,16); Nota(re,4,4); Nota(re,4,8);

Nota(re,4,8); Nota(doo,4,8); Nota(la_diez,3,8); Nota(la,3,8);

Nota(sol,3,4); Nota(re,3,4)

END.

фактические параметры могут быть любыми выражениями подходящего типа. Например, вместо Nota(re,3,8) можно было бы написать а:=3; Nоtа(re,а,11-а).

Задание 119

В модуле Graph не хватает процедуры, которая рисовала бы треугольник. Создайте такую процедуру. Она должна рисовать примерно равносторонний треугольник вершиной вверх и иметь 3 параметра: положение треугольника на экране и размер.