Программирование на языке Турбо Паскаль
массивов и других записей. При необходимости хранения информации о
сотрудниках некоторой организации может оказаться полезным массив:
const N = 30;
type tStaff = array [1..N] of tPerson;
Рассмотрим другой пример, где иллюстрируется использование вложенных
записей. Пусть прямоугольник определяется координатами точки, являющейся
его левым верхним углом, шириной, высотой и цветом линий. На Турбо Паскале
эти сведения можно объединить в такую запись:
type tPoint = record
x,y: integer;
end;
tRectangle = record
LeftTop: tPoint;
Width, Height: integer;
Color: integer;
end;
Для такой записи можно применять ещё одну форму оператора with, которая
может «присоединять» несколько имён записей, например:
var rect: tRect;
with rect, LeftTop do begin
x:=100;
y:=150;
Color:=11;
...
end;
Без использования with появились бы выражения вида rect.Color,
rect.LeftTop.x, rect.LeftTop.y и т. п.
Покажем теперь, как можно использовать массивы внутри записей.
Предположим, что требуется хранить информацию уже не о прямоугольнике, а о
произвольном многоугольнике. В этом случае потребуется задать количество
точек в нём и список всех этих точек, то есть массив. Требуется
предусмотреть возможность хранения сведений о многоугольниках с различным
числом вершин, поэтому сделаем массив довольно большим, а реальное число
вершин будем хранить в отдельном поле записи. Всё это будет выглядеть
следующим образом:
const MaxVertex = 200;
type tPolygon = record
size: integer;
V: array [1..MaxVertex] of tPoint;
Color: tColor;
end;
Существует разновидность записей, которая содержит так называемую
вариантную часть. Для лучшего понимания рассмотрим их на примере. Пусть
запись должна хранить полную информацию о геометрической фигуре: цвет,
положение и размеры (для окружности — координаты центра и радиус, для
прямоугольника — координаты левой верхней и правой нижней вершин, для
квадрата — координаты левой верхней вершины и длина стороны). В принципе,
можно было бы включить в запись все перечисленные выше поля, но в таком
случае большинство из них часто оставались бы незанятыми, поэтому удобнее
будет такое решение:
type tFKind = (fCir,fRect,fSqr);
tFigure = record
Color: integer;
case kind: tFKind of
fCir: (Center: tPoint; r: integer);
fRect: (LeftTop,RightBottom: tPoint);
fSqr: (LT: tPoint; size: integer);
end;
В этой записи имеется одно обычное поле (Color), а остальные 6 и
представляют собой вариантную часть. Для окружности в ней имеются поля
Center и r, для прямоугольника — LeftTop и RightBottom, для квадрата — LT и
size. Фраза kind: tFKind не является обязательной, она служит для понимания
того, какие поля к каким фигурам относятся. Можно написать просто case
integer of ... и нумеровать варианты целыми числами. Заметим также, что в
объявлении нашей записи нет слова end, относящегося к case.
Мы можем обращаться к любому полю вариантной части, однако следует
помнить, что при записи данных в поле для одной фигуры поля для других
фигур могут измениться. Чтобы понять, почему так происходит, достаточно
рассмотреть способ хранения переменной типа tFigure:
Из рисунка видно, что вариантная часть хранится в одной части памяти, то
есть поля могут накладываться друг на друга.
Лекция 9. Процедуры и функции
Процедура ( последовательность действий (записанных на Паскале),
названная каким-либо именем. Для того чтобы выполнить эту
последовательность, нужно в соответствующем месте программы указать её имя
(так, например, для очистки экрана при работе с графикой мы указываем
ClearDevice;). Кроме того, что программа становится при использовании
процедур короче и понятнее, процедуры можно вызывать из разных мест
программы (в противном случае пришлось бы повторять в тексте программы
одинаковые последовательности действий несколько раз).
Те действия, которые входят в процедуру, записываются до начала основной
программы в следующем виде:
program ...
const ...
type ...
var ...
procedure MyProc;
begin
{действия}
end;
begin
{основная программа}
end.
Рассмотрим пример нахождения максимума из трёх чисел:
program Max1;
var a,b,c,m: integer;
begin
write('Введите a: '); readln(a);
write('Введите b: '); readln(b);
write('Введите c: '); readln(c);
if a>b then m:=a else m:=b;
if c>m then m:=c;
writeln('Максимум = ',m);
readln;
end.
Перепишем его с использованием процедуры:
program Max2;
var a,b,c,m: integer;
procedure FindMax;
begin
if a>b then m:=a else m:=b;
if c>m then m:=c;
end;
begin
write('Введите a: '); readln(a);
write('Введите b: '); readln(b);
write('Введите c: '); readln(c);
FindMax;
writeln('Максимум = ',m);
readln;
end.
Этот вариант можно улучшить. Пока наша процедура может искать минимум
только среди значений конкретных переменных a, b и c. Заставим её искать
минимум среди любых трёх целых чисел и помещать результат в нужную нам
переменную, а не всегда в m.
Чтобы была видна польза от такой процедуры, рассмотрим пример программы
для поиска максимума среди чисел a+b, b+c и a+c:
program Max3;
var a,b,c,m: integer;
procedure FindMax(n1,n2,n3: integer; var max: integer);
begin
if n1>n2 then max:=n1 else max:=n2;
if n3>max then max:=n3;
end;
begin
write('Введите a: '); readln(a);
write('Введите b: '); readln(b);
write('Введите c: '); readln(c);
FindMax(a+b,b+c,a+c,m);
writeln('Максимум из сумм = ',m);
readln;
end.
В скобках после имени процедуры (в её описании) записаны так называемые
параметры. Эта запись обозначает, что внутри процедуры можно использовать
целые числа, обозначенные n1, n2 и n3, а также заносить значения в
переменную типа integer, которая внутри процедуры называется max (а реально
во время работы программы все действия производятся над переменной m).
Параметры, в которых хранятся числа (n1,n2,n3) называются параметрами-
значениями; а те, которые обозначают переменные (max) ( параметрами-
переменными, перед ними в описании ставится слово var. Параметры, на
которые имеются ссылки внутри процедуры (n1, n2, n3, max), называются
формальными, а те, которые реально используются при вызове (a+b, b+c, a+c,
m) — фактическими.
Процедуры последнего вида оказываются достаточно удобными. Можно один
раз написать такую процедуру, убедиться в её работоспособности и
использовать в других программах. Примерами таких процедур являются
процедуры для работы со строками, встроенные в Турбо-Паскаль.
В нашем примере можно переписать программу и по-другому. Максимум из
трёх чисел определяется по ним однозначно, или, говоря математическим
языком, является функцией этих трёх чисел. Понятие функции есть также и в
Паскале. Рассмотрим такую программу:
program Max4;
var a,b,c,m: integer;
function Max(n1,n2,n3: integer) : integer;
var m: integer;
begin
if n1>n2 then m:=n1 else m:=n2;
if n3>m then m:=n3;
Max:=m;
end;
begin
write('Введите a: '); readln(a);
write('Введите b: '); readln(b);
write('Введите c: '); readln(c);
writeln('Максимум = ',Max(a+b,b+c,a+c));
readln;
end.
Нам уже известно как вызывать функцию из программы (например sqrt, sin и
т. п.). Рассмотрим описание функции. Оно очень похоже на описание процедур,
но есть два отличия:
1. После имени функции и списка параметров (если есть) через двоеточие
записывается тип значения функции (возможны не только числовые типы,
но и логические, строковые, символьные);
2. Среди операторов в теле функции наиболее важными являются операторы
присваивания значения функции (в нашем случае это строчка Max:=m;).
В записанной выше функции используется так называемая локальная
переменная m, то есть переменная, которая «видна» только нашей функции, а
другие процедуры и функции, а также главная программа её «не видят». Кроме
локальных переменных в Турбо-Паскале можно определять локальные константы и
типы.
Приведём другие примеры процедур и функций.
1. Напишем на Паскале функцию [pic].
function Cube(x: real): real;
begin
Cube:=x*x*x;
end;
2. Вычисление площади треугольника через длины сторон. Здесь будет
использована формула Герона: [pic], где p ( полупериметр треугольника,
a, b, c ( длины сторон.
function Square(a,b,c: real): real;
var p: real;
begin
p:=(a+b+c)/2;
Square:=sqrt(p*(p-a)*(p-b)*(p-c));
end;
3. Процедура для решения квадратного уравнения. Будем передавать этой
процедуре коэффициенты уравнения, а результаты своей работы она будет
выдавать в трёх параметрах-переменных. Через первую, логического типа,
процедура сообщит, есть ли вещественные корни, а еще в двух она выдаст
сами эти корни (если корней нет, то на эти две переменные пользователь
нашей процедуры может не обращать внимания).
procedure SqEquation(a,b,c: real; var RootsExist: boolean;
var x1,x2: real);
var d: real;
begin
d:=sqr(b)-4*a*c;
if d>=0 then begin
RootsExist:=true;
x1:=(-b+sqrt(d))/(2*a);
x2:=(-b-sqrt(d))/(2*a);
end
else RootsExist:=false;
end;
Можно вместо процедуры написать и функцию, по логическому значению
которой мы определяем, есть ли корни, а сами корни передаются также как и в
процедуре:
function EqHasRoots(a,b,c: real; var x1,x2: real) : boolean;
var d: real;
begin
d:=sqr(b)-4*a*c;
if d>=0 then begin
EqHasRoots:=true;
x1:=(-b+sqrt(d))/(2*a);
x2:=(-b-sqrt(d))/(2*a);
end
else EqHasRoots:=false;
end;
Использовать такую функцию даже проще чем последнюю процедуру:
if EqHasRoots(1,2,1,r1,r2) then writeln(r1,' ',r2) else writeln('Нет
корней');
Лекция 10. Модуль CRT
Модуль CRT - набор средств для работы с экраном в текстовом режиме,
клавиатурой и для управления звуком. Для того чтобы использовать эти
средства требуется после заголовка программы записать: uses CRT;.
1. Управление экраном
В текстовом режиме экран представляется разбитым на маленькие
прямоугольники одинакового размера, в каждом из которых может находиться
какой-либо символ из набора ASCII. Для символов можно задавать цвет самого
символа и цвет прямоугольника, в котором он рисуется (цвет фона). Строки
экрана нумеруются сверху вниз, а столбцы слева направо, нумерация и строк,
и столбцов начинается с единицы.
Наиболее распространённым в настоящее время является текстовый режим
80x25 при 16 возможных цветах текста и фона. Многие графические адаптеры
позволяют использовать другие режимы, например: 40x25, 80x43, 80x50 и т. д.
В управлении текстовым экраном важную роль играет курсор. Вывод символов
на экран (т.е. write и writeln) осуществляется начиная с позиции курсора,
когда все символы выведены, курсор останавливается в следующей позиции
после последнего символа. Ввод также будет производиться начиная с позиции
курсора.
Ниже приведены основные процедуры и функции для управления экраном в
текстовом режиме.
|Название |Назначение |
|InsLine |Вставить строку в том месте где |
| |находится курсор, все строки ниже |
| |курсора сдвигаются вниз на одну позицию.|
| |Курсор остаётся на том же месте. |
|DelLine |Удалить строку в позиции курсора. Курсор|
| |остаётся на том же месте. |
|GotoXY(x,y: byte) |Переместить курсор в позицию (x,y); x — |
| |номер строки, y — номер столбца. |
|ClrEOL |Очистить строку от курсора и до правого |
| |края экрана. Курсор остаётся на прежнем |
| |месте |
|HighVideo |Устанавливает повышенную яркость для |
| |вывода текста |
|LowVideo |Пониженная яркость |
|NormVideo |Нормальная яркость |
|TextColor(color: byte) |Устанавливает цвет для вывода текста. |
| |Значения цветов — обычно числа от 0 до |
| |15. Вместо этих чисел можно указывать и |
| |существующие константы (black, white, |
| |red, green, blue, magenta, cyan, brown, |
| |lightgray и т. п.). При необходимости |
| |можно заставить текст мерцать прибавляя |
| |к номеру цвета число 128 или константу |
| |Blink. |
|TextBackGround(color: byte) |Устанавливает цвет для фона. |
|ClrScr |Очистить экран и поместить курсор в |
| |левый верхний угол, т.е. в позицию (1,1)|
| |— 1-я строка, 1-й столбец. При очистке |
| |экран заполняется цветом фона (см. |
| |TextBackground) |
|WhereX: byte |Эта функция возвращает номер строки, в |
| |которой находится курсор. |
|WhereY: byte |Номер столбца, в котором находится |
| |курсор |
2. Работа с клавиатурой
При работе с клавиатурой компьютер помещает всю информацию о нажатии
клавиш в очередь до тех пор, пока эта информация не потребуется программе
(например, для вывода на экран, для движения объектов в играх и т.п.). Для
работы с клавиатурой важны 2 функции:
1. KeyPressed: boolean — возвращает true, если очередь клавиатуры не
пуста (то есть была нажата). Простейший пример использования —
повторять какие либо действия, пока не нажата клавиша: repeat ...
until KeyPressed;.
2. ReadKey: char — возвращает символ, соответствующий нажатой клавише (из
очереди клавиатуры). Если пользователь нажал клавишу, для которой
имеется код ASCII, то в очередь будет положен один соответствующий
символ, а если это специальная клавиша (F1, F2, ... F12, клавиши
управления курсором, Ins, Del, Home, End, PgUp, PgDn), то сначала в
очередь будет положен символ с кодом 0, а затем дополнительный символ.
Если очередь клавиатуры пуста, то Readkey будет ждать, пока
пользователь не нажмёт какую-либо клавишу.
Для демонстрации работы ReadKey можно написать такую программу:
uses Crt;
var c: char;
begin
repeat
c:=ReadKey;
writeln(ord(c));
until c=#27 {клавиша Escape};
end.
При нажатии вышеперечисленных специальных клавиш эта программа будет
выводить по два кода сразу.
3. Другие возможности
При необходимости организации задержек в программе можно использовать
процедуру Delay(time: word). Параметр time — время в миллисекундах, на
которое нужно приостановить программу.
Ещё одна возможность модуля CRT — работа с системным динамиком. Для
включения звука нужна процедура Sound(f: word) (f — частота в герцах).
После включения требуется задержка (Delay) на необходимое время звучания,
затем — выключение с помощью NoSound. Если не воспользоваться NoSound, то
звук будет слышен даже после выхода из программы на Паскале.
Лекция 11. Графика в Турбо Паскале
В отличие от уже знакомого текстового режима, экран в графическом режиме
разбит на большое количество точек, каждая из которых может иметь
определённый цвет. Точки считаются одинаковыми и прямоугольными, все они
Страницы: 1, 2, 3, 4, 5, 6
|