Читайте данную работу прямо на сайте или скачайте

Скачайте в формате документа WORD


Программирование на языке Турбо Паскаль

Приведём простейший пример программы, единственная цель которой Ц

program Hello;

begin

end.

Первая строка ничего не делает, она просто содержит название программы. Затем, после слова begin

теперь приведём пример, в котором программа же не лглухая, то есть может запрашивать какие-либо данные у пользователя. Пусть требуется спросить у пользователя два числа, после этого вывести на экран их произведение:

program AxB;

var a,b: integer;

begin

end;

В этой программе перед словом begin

О том, что делает первый оператор, нам известно: он выводит на экран строчку 'Введите a и b'. При выполнении второго оператора программа будет ждать, пока пользователь не введет число с клавиатуры и не нажмёт Enter

теперь

Блок объявлений:

program

uses

const

type

var

Блок описания процедур и функций:

procedure

begin

...

end

...

Блок основной программы:

begin

... (операторы

end

Рассмотрим наиболее важные части вышеописанных блоков. Под заголовком программы понимается имя, помогающее определить её назначение. Имя, или идентификатор, строится по следующим правилам: оно может начинаться с большой или малой буквы латинского алфавита или знака л_, далее могут следовать буквы, цифры или знак л_; внутри идентификатора не может стоять пробел. После имени программы следует поставить л;, этот знак служит в Паскале для разделения последовательных инструкций. Заметим, что имя программы может не совпадать с именем соответствующего файла на диске.

После слова const

const

pi = 3.1415926;

my_const = -1.5;

Hello = '

За словом var

Название типа

Возможные значения

Примеры значений

integer

целые: -32768... 32767

12, -1

real

действительные (по модулю): 2,9x10-39... 138

-9

string[n]

строка до n

СabcdeТ

char

одиночный символ

СFТ, С!Т, Т_Т,Т

Объявления переменных записываются в следующей форме: var <

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

Примеры объявления:

var

d,l: real;

Name: string[20];

Line: string;

Key1,Key2: char;

Блок основной программы. Здесь, между словами begin

program

const

a1 = -2;

a0 = 5;

var

begin

write(С

readln(x);

f

writeln(С

end

Первая строка исполняемой (основной) части программы выводит на экран надпись Введите значение х, для этого используется процедура write

writeln('

В арифметических выражениях на Паскале используются следующие знаки для обозначения операций: +, -, *, /

Замечание об именах. Для обозначения переменных запрещается использование ряда слов, называемых зарезервированными, они играют в языке особую роль. Нам же встречался ряд зарезервированных слов: program, begin, end, string, const, var,

Лекция 2. Процедуры ввода-вывода. Некоторые встроенные функции Турбо-Паскаля.

1. Процедуры ввода-

     

     

     

     

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

program

var

begin

end

2.  

Название

Значение

abs

модуль x

cos

косинус

frac

дробная часть x

int

целая часть x

pi

число p

round(x)

x

sin

синус x

sqr

квадрат x

sqrt

квадратный корень из x

trunc(x)

число, полученное из x

Лекция 3.

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

if

Под оператором понимается либо одиночный оператор (например, присваивания, вызова процедуры), либо т.н. составной оператор, состоящий из нескольких простых операторов, помещённых между словами begin

Пример 1: пусть требуется найти число m=max(a,b).

if

Пример 2: (

var

.......

if

Примечание: в примере использована операция нахождения остатка от деления (mod

Пример 3: (с использованием составного оператора). Пусть даны две переменные типа real

var

.........

if

end

Следующий пример использует вложенные операторы if

Пример 4: Поиск корней квадратного равнения.

program

var

begin

end.

Чтобы не запутаться в структуре этой программы, следует помнить такое правило: else

Пример 5:

begin

end

В этом примере пришлось использовать составной оператор (begin... end;

2. Оператор выбора (

Кроме оператора словного выполнения и циклов в Турбо Паскале имеется ещё одна правляющая конструкция, одно из названий которой Ч оператор выбора. На самом деле это сложнённый оператор if

case

end

(Пояснение: квадратные скобки означают то, что часть else

Выражение в простейших случаях может быть целочисленным или символьным. В качестве вариантов можно применять:

1.  

2.  

3.  

Выполняется оператор case

Рассмотрим пример. Пусть пользователь вводит целое число от 1 до 10, программа должна приписать к нему слово лученик с необходимым окончанием (нулевое, ла или лов).

program

var

begin

end

Можно также совершенствовать программу для произвольного натурального n

write(n,' ченик');

Лекция

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

1. Цикл с постусловием (Repeat)

На Паскале записывается следующим образом: repeat

Пример (подсчет суммы натуральных чисел от 1 до 100):

var

begin

end

Важно заметить, что операторы стоящие внутри цикла repeat

2. Цикл с предусловием

Этот цикл записывается так: while

Рассмотрим тот же пример, выполненный с помощью while

var

begin

end

3. Цикл со счетчиком (For)

Записывается так: for

var

begin

При выполнении цикла происходит следующее: переменной i

for

В завершение запишем программу о подсчете суммы чисел от 1 до 100 с помощью for

var

begin

end

Лекция 5. Символьные и строковые переменные

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

1. Символьный тип

Тип данных, переменные которого хранят ровно один символ (букву, цифру, знак препинания и т.п.) называется символьным, в Паскале - char

write(С

if

else

Символьные переменные в памяти компьютера хранятся в виде числовых кодов, иначе говоря, у каждого символа есть порядковый номер. К примеру, код пробела равен 32, код СAТ8=256 различных символов.

Для того чтобы получить в программе код символа нужно использовать функцию chr

var

...

readln(i); writeln('

Если в качестве кода используется конкретное число, не выражение и не переменная, то можно использовать символ л#

program

var

begin

end.

В этой программе в качестве счётчика цикла была использована символьная переменная, это разрешается, поскольку цикл for

С использованием кодов работают ещё две функции, значения которых символьные:

1.  

2.  

Если попытаться в программе получить succ(#255)

...

ch:=#32;

while

end

...

Сравнение символов. Также как и числа, символы можно сравнивать на =, <>

2. Строковый тип

Для хранения строк (то есть последовательностей из символов) в Турбо-Паскале имеется тип string

Для того чтобы положить значение в строковую переменную используются те же приёмы, что и при работе с символами. В случае присваивания

program

var

begin

end

Хранение строк. В памяти компьютера строка хранится в виде последовательности из символьных переменных, у них нет индивидуальных имён, но есть номера, начинающиеся с 1). Переда

Номер байта

0

1

2

3

4

5

6

7

8

9

Содержимое

#6

С

С

С

С

С

С

С

СsТ

С%Т

Для того чтобы в программе получить доступ к n-

Сравнение строк. Строки сравниваются последовательно, по символам. Сравниваются первые символы строк, если они равны - то вторые, и т. д. Если на каком-то этапе появилось различие в символах, то меньшей будет та строка, в которой меньший символ. Если строки не различались, затем одна из них закончилась, то она и считается меньшей. Примеры: '

Склеивание (конкатенация) строк. К строкам можно применять операцию л+

Процедуры и функции для работы со строками. Наиболее часто употребляется функция length(s: string): integer

Другие процедуры и функции приведены в таблице:

Процедура или функция

Назначение

Пример

функция

Copy(s: string; start: integer;
len: integer): string

Возвращает вырезку из строковой переменной s

s:=Т

s1:=Copy(s,4,4);

{

функция

Pos

Ищет подстроку s1

n:=pos(С

n:=pos(СabcТ,

процедура

Insert(s1: string; s:а start: integer)

Вставляет строку s1

S:=С

insert(С

{

процедура

Delete(s: string; start: integer;
len: integer)

Удаляет из строковой переменной s

s:= С

delete(s,4,7);

{

Лекция 6. Перечисляемый и ограниченный типы

Предположим, что нам требуется переменная для хранения дня недели. В этом случае можно воспользоваться целым типом (например byte

type

После этого можно завести переменную этого типа (var

day:=Wed;

...

if

...

if

Как вы же заметили значения перечислимого типа можно сравнивать, при этом меньшим считается то, которое объявлено раньше (левее) в определении типа.

Для переменных перечисляемых типов возможно применение функций succ

Хранение значений перечисляемого типа строено внутри довольно просто: хранятся целые числа от 0 до n

Пример использования перечисляемых типов:

Пусть корабль может двигаться только по четырем направлениям: на север, на запад, на юг и на восток, то есть текущее направление движения определяется переменной типа Directions = (North, West, South, East);

program

type

var

begin

end

2

Этот тип также рассмотрим на примере. Пусть в некоторой переменной нужно хранить текущее число, то есть номер дня в месяце. В Турбо Паскале можно задать тип DaysInMonth = 1..31;

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

type

Нельзя в качестве базового типа потребить какой-

type

Заметим, что функции Ord, Succ

Лекция

Массивы являются представителями структурированных типов данных, то есть таких, переменные которых составлены из более простых элементов согласно определённому порядку. Для массивов характерно то, что они являются совокупностью некоторого числа одинаковых элементов. В простейшем случае эти элементы могут быть занумерованы натуральными числами из некоторого диапазона. Рассмотрим пример такой переменной в Турбо Паскале:

var

Переменная a

Пример 1. Поиск наибольшего числа среди элементов массива.

program

var

begin

end

В качестве типа элементов массива можно использовать все типы, известные нам на данный момент (к ним относятся все числовые, символьный, строковыйа

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

var

В следующем примере показано для чего может понадобиться последний тип.

Пример 2. Подсчет количества различных букв в строке.

program

var

begin

end

2. Многомерные массивы

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

Примеры описаний многомерных массивов:

var

Рассмотрим пример использования двумерного массива.

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

program

type

var

begin

end

3. Сортировка и поиск

В прикладных программах широко распространены два типа операций, связанных с массивами:

1.  

2.  

Рассмотрим простейший вариант сортировки массива (сортировка выбором). Пусть есть массив из n

program

const

var

begin

end

Другой способ - пузырьковая сортировка, он работает чуть быстрее, чем предыдущий. На первом этапе двигаемся от n-

program

...

var

begin

end

Лекция

Тип запись, также как и массив, является структурированным типом данных, то есть таким, переменные которого составлены из нескольких частей. В Турбо-Паскале существует возможность объединить в одну переменную данные разных типов (тогда как в массиве все элементы имеют одинаковый тип). Приведём пример такого типа. Пусть в переменной требуется хранить сведения о некотором человеке: ФИО, пол, адрес, телефон. Тогда для хранения этих данных будет добен такой тип:

type

Объявление переменной типа запись выполняется стандартно, с помощью var

var

...

begin

end

Заметим, что в этом примере постоянно приходится обращаться к полям одной и той же переменной типа запись, и, следовательно, постоянно писать её имя. Есть возможность избавиться от этого неудобства. В Турбо Паскале есть оператор присоединения (with

with

Чаще всего в качестве оператора используется составной оператор.

Пример:

with

end

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

const

type

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

type

Для такой записи можно применять ещё одну форму оператора with

var

with

end

Без использования with

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

const

type

Существует разновидность записей, которая содержит так называемую вариантную часть. Для лучшего понимания рассмотрим их на примере. Пусть запись должна хранить полную информацию о геометрической фигуре: цвет, положение и размеры (для окружности Ч координаты центра и радиус, для прямоугольника - координаты левой верхней и правой нижней вершин, для квадрата - координаты левой верхней вершины и длина стороны). В принципе, можно было бы включить в запись все перечисленные выше поля, но в таком случае большинство из них часто оставались бы незанятыми, поэтому добнее будет такое решение:

type

В этой записи

Байты:

Color

R

RightBottom

LeftTop

size

LT

Center



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

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

Лекция

Процедура Ц

Те действия, которые входят в процедуру, записываются до начала основной программы в следующем виде:

program

const

type

var

procedure

begin

end

begin

end

Рассмотрим пример нахождения максимума из трёх чисел:

program

var

begin

end

Перепишем его с использованием процедуры:

program

var

procedure

begin

end

begin

end

Этот вариант можно лучшить. Пока наша процедура может искать минимум только среди значений конкретных переменных a, b

Чтобы была видна польза от такой процедуры, рассмотрим пример программы для поиска максимума среди чисел a+b, b+c и a+c

program

var

procedure

begin

end

begin

end

В скобках после имени процедуры (в её описании) записаны так называемые параметры. Эта запись обозначает, что внутри процедуры можно использовать целые числа, обозначенные n1, n2

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

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

program

var

function

var

begin

end

begin

end

Нам же известно как вызывать функцию из программы (например sqrt, sin

1.  

2.  

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

Приведём другие примеры процедур и функций.

1.  

function

begin

end

2.  

function

var

begin

end

3.  

procedure

var

begin

end

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

function

var

begin

end

Использовать такую функцию даже проще чем последнюю процедуру:

if

Лекция 10.

Модуль CRT -

1. правление экраном

В текстовом режиме экран представляется разбитым на маленькие прямоугольники одинакового размера, в каждом из которых может находиться какой-либо символ из набора ASCII

В правлении текстовым экраном важную роль играет курсор. Вывод символов на экран (т.е. write

Ниже приведены основные процедуры и функции для правления экраном в текстовом режиме.

Название

Назначение

InsLine

Вставить строку в том месте где находится курсор, все строки ниже курсора сдвигаются вниз на одну позицию. Курсор остаётся на том же месте.

DelLine

Удалить строку в позиции курсора. Курсор остаётся на том же месте.

GotoXY(x,y: byte)

Переместить курсор в позицию (x,y)

ClrEOL

Очистить строку от курсора и до правого края экрана. Курсор остаётся на прежнем месте

HighVideo

Устанавливает повышенную яркость для вывода текста

LowVideo

Пониженная яркость

NormVideo

Нормальная яркость

TextColor(color: byte)

Устанавливает

TextBackGround(color: byte)

Устанавливает цвет для фона.

ClrScr

Очистить экран и поместить курсор в левый верхний гол, т.е. в позицию (1,1) -

WhereX: byte

Эта функция возвращает номер строки, в которой находится курсор.

WhereY: byte

Номер столбца, в котором находится курсор

2. Работа с клавиатурой

При работе с клавиатурой компьютер помещает всю информацию о нажатии клавиш в очередь до тех пор, пока эта информация не потребуется программе (например, для вывода на экран, для движения объектов в играх и т.п.). Для работы с клавиатурой важны 2 функции:

1.  

2.  

Для демонстрации работы ReadKey

uses

var

begin

end

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

3. Другие возможности

При необходимости организации задержек в программе можно использовать процедуру Delay(time: word)

Ещё одна возможность модуля CRT

Лекция 11. Графика в Турбо Паскале

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

Заметим, что существуют разные графические режимы, они отличаются количеством точек по горизонтали и вертикали

Все средства для работы с графикой содержаться в стандартном модуле Graph

1. Включение и выключение графического режима.

Для включения графического режима используется процедура InitGraph(driver,mode,path)

driver

mode

path

Обычно для включения графики мы будем использовать InitGraph

const

var

...

begin

Для завершения работы с графикой и выхода в текстовый режим используется процедура CloseGraph.

2. Построение элементарных изображений

Система координат при работе с графикой имеет начало (точку (0,0)) в левом верхнем глу экрана. Ось x

При построении простейших элементов изображений используются следующие процедуры и функции:

Название

Назначение

PutPixel(x,y: integer; c:

Поставить точку (x,y

SetColor(c: word);

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

SetBkColor(c: word);

Установить текущий цвет для фона (то есть цвет всего экрана).

GetMaxX; GetMaxY;

Эти функции возвращают максимальные допустимые значения координат x

Line(x1,y1,x2,y2: integer);

Рисовать отрезок из (x1,y1

Rectangle(

Рисует текущим цветом прямоугольник, левый гол которого Ц

Circle(x,y: integer; r: word);

Рисует текущим цветом окружность с центром в точке (x,y)

Arc (x,y

Рисует дугу окружности. a1

Ellipse(

Рисует дугу эллипса с полуосями xr

DrawPoly(

Рисует многоугольник, количество сторон в котором Ц

MoveTo(x,y: integer);

Эта процедура опирается на понятие текущей позиции. Она запоминает позицию (x,y)

LineTo(x,y: integer);

Рисует отрезок из текущей позиции в точку (x,y

MoveRel(dx,dy: integer);

Перемещает текущий казатель из прежнего положения (x,y

LineRel(dx,dy: integer);

То же, что и предыдущая процедура, но при перемещении рисует отрезок от (x,y

GetX; GetY;

Возвращают координаты текущего казателя (по отдельности).

ClearDevice;

Очищает экран.

Все приведённые выше процедуры для рисования выполняют только контурные рисунки (не закрашивая прямоугольник, окружность или эллипс внутри). По молчанию рисование происходит с использованием тонкой сплошной линии, однако толщину и вид линии можно менять с помощью процедуры SetLineStyle(style,pattern,width: word)

1.  

2.  

Удобнее всего переводить полученное число в шестнадцатеричный вид, в нашем примере получится $C

3.  

Перейдём теперь к рисованию закрашенных фигур. По молчанию внутренняя область фигуры будет закрашиваться белым цветом, причём закраска будет сплошной. Для правления цветом и видом закраски используется процедура SetFillStyle(style, color: word);

Ниже приводятся процедуры рисования закрашенных фигур.

Название

Назначение

Bar(x1,y1,x2,y2: integer);

Рисует закрашенный прямоугольник.

FillEllipse(x,y: integer; xr,yr: word);

Закрашенный эллипс.

FillPoly(

Закрашенный многоугольник.

PieSlice(

Закрашенный круговой сектор.

Sector (

Закрашивает эллиптический сектор.

FloodFill(x,y: integer; Cborder: word);

Выливает краску в точку (x,y

3. Вывод текстовой информации.

Для вывода текста на экран используются две процедуры:

1.  

2.  

Если требуется вывести какие либо числа, то предварительно требуется преобразовать их в строку, например, с помощью процедуры Str

Пример:

var

....

Str(r,s);

OutTextXY(100,200,Результат=Т+s);

Турбо Паскаль позволяет использовать несколько различных шрифтов для вывода текста.

Font (

DefaultFont Ц

TriplexFont Ц

SmallFont Ц

SansSerifFont Ц

GothicFont Ц

0 Ц

1 Ц

2 Ц

Size Ц

Другая возможность при работе с текстом Ц

для horiz:

LeftText

CenterText

RightText

для vert:

BottomText

CenterText

TopText

Лекция 12. Текстовые файлы

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

Любой текст в файле хранится в виде последовательности символов (char

1. Объявление файловой переменной и привязка к файлу на диске

Для того чтобы программа могла работать с текстовым файлом, нам потребуется переменная специального файлового типа text

var

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

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

assign(TxtFile: text, name: string);

Первый параметр (TxtFile

assign(f,'Z:\SCHOOL\text1.txt');

2. Чтение данных из файла

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

Чтобы открыть для чтения файл, который был казан при вызове assign

reset(TxtFile: text);

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

После открытия файла можно начинать чтение данных. Для этого используются процедуры read

read(TxtFile: text, v1: type1, v2: type2,... vN: typeN);

readln(TxtFile: text, v1: type1, v2: type2,... vN: typeN);

Первая процедура читает последовательно из файла значения и помещает их в переменные v1, v2,... vN

При чтении строковых значений из файла берётся вся последовательность символов от позиции казателя до конца строки. Если после этого попытаться вновь прочитать строку, то результат будет пустой строкой ( '

При чтении чисел read

Пример использования процедуры чтения:

var f: text; s: string; n: integer;

...

readln(f,n,s);

Необходимо помнить, что если файл не был открыт для чтения с помощью reset

Довольно часто в программе бывает необходимо определить, дошёл ли казатель файла до конца строки или до конца файла. В этом случае полезно использовать такие функции:

eoln(TxtFile: text): boolean;

eof(TxtFile: text): boolean;

Первая принимает значение true

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

close(TxtFile: text);

если этого не сделать, то содержимое файла может оказаться испорченным после выполнения нашей программы.

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

program

var

begin

end

3.

теперь перейдём к процедурам записи в файл. Перед тем как что-либо записывать, нужно создать новый (пустой) файл или стереть содержимое существующего. Для этого используется процедура

rewrite(TxtFile: text);

До её вызова файловая должна быть привязана к имени файла на диске с помощью assign

Для записи используются процедуры

write(TxtFile: text, p1: type1, p2: type2,... pN: typeN);

writeln(TxtFile: text, p1: type1, p2: type2,... pN: typeN);

Здесь в качестве параметров p1, p2,... pN

Так же как и в случае с чтением из файла, после того как все данные записаны файл нужно закрыть с помощью close

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

program

var

begin

end

Ещё один способ записи - это открытие для добавления информации в конец файла. Для этого используется процедура

append(TxtFile: text);

Если файл открыт с помощью append

Лекция 1

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

Для всех обсуждаемых ниже файлов можно выполнять те же процедуры открытия, закрытия и привязки, что и для текстовых: Append, Assign, Close, Reset

Двоичные файлы будем делить на типизированные и нетипизированные.

1. Типизированные файлы

Файлы этого вида состоят из элементов одинакового типа, то есть в них нельзя записывать (или читать) значения переменных разных типов, в отличие от текстовых файлов.

Объявляются типизированные файлы так:

var

В качестве типа элемента можно использовать как простые типы, так и структурированные (массивы, записи и т.п.).

2. Нетипизированные файлы

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

var

Для чтения и записи процедуры read

1.  

2.  

Лекция 1

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

При написании модуля сначала описывается то, что он предоставляет для общего пользования (секция интерфейса), затем Ц

unit

interface

implementation

[begin]

end

Рассмотрим части модуля подробнее. Uses

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

При сохранении модуля ему нужно дать такое же имя, как и после unit

Рассмотрим пример. Наш модуль предназначается для операций с трехмерными векторами:

unit

interface

implementation

procedure

begin

end

procedure

begin

end

procedure

begin

end

function

begin

end

end

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

program

uses

var

...

begin

...

...

end

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

Преимущества модулей:

1.  

2.  

3.  

4.  

Лекция 1

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

В Турбо Паскале есть возможность создания динамических переменных (то есть таких, которые можно заводить и ничтожать во время работы программы по мере необходимости). Для этого в программе объявляют не саму переменную нужного нам типа, казатель на эту переменную, например:

var

здесь p

Для всех динамических переменных в памяти отводится пространство, называемое динамической областью, или кучей. Перед тем как пользоваться динамической переменной, требуется выделить для неё место в куче. Это делается с помощью процедуры New

New(p);

В результате такого действия в куче выделено место под переменную типа real

Если потребуется изменить значение казателя, например, заставить его казывать на другую переменную, то старую переменную следует уничтожить, то есть объявить занимаемую старой переменной память свободной. Если этого не сделать, то при изменении казателя сама переменная станет мусором (место в памяти объявлено занятым, получить к нему доступ же невозможно). ничтожение динамической переменной выполняется процедурой Dispose: Dispose(p);

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

1.  

2.  

С динамическими переменными можно выполнять все действия, разрешённые для статических переменных, например:

if

Рассмотрим теперь несколько искусственный пример использования динамических переменных: пусть требуется сложить два числа, не используя статических переменных:

var

begin

end

Кроме описанных казателей существуют ещё так называемые нетипизированные казатели (тип pointer

Динамические структуры данных

.. .

Data

List

Data

Data

Data


Вернёмся теперь к вопросу об экономии памяти при хранении табличных данных. С использованием казателей можно отказаться от массива и использовать динамические структуры. Самой простой из них является список, который схематично изображается так:

Прямоугольники на этой схеме Ц

Для описания списка на Паскале достаточно описать тип указателя на запись и тип самой записи. Выглядит всё это так:

type

В первой строке этого объявления бросается в глаза использование неопределённого типа tItem

Объявить сам список можно как казатель на элемент: var List : tItemPtr

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

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

unit

interface

type

procedure

procedure

function

function

function

procedure

{---------------------------------------------------------------}

implementation

procedure

begin

procedure

var

begin

end

function

var

begin

end

function

var

begin

end

function

var

begin

end

procedure

var

begin

end

end

Лекция 16. Динамические переменные: другие виды списков, стек и очередь.

Кроме рассмотренных списков возможны более сложные варианты, связанные с наличием двух дополнительных свойств:

1.  

2.  

С чётом этих свойств возможны четыре различных типа списков.

Для примера рассмотрим описание и реализацию кольцевого двунаправленного списка:

type

var

........

{

procedure

var

begin

end

{

procedure

var

begin

end

2. Стек и очередь

Стеком называется такой способ хранения данных, при котором элемент, записанный в хранилище

Рассмотрим простейший пример использования стека. Предположим, что имеется строка, состоящая из одних лишь открывающих и закрывающих скобок. Требуется определить, является ли она правильным скобочным выражением (то есть для каждой открывающей скобки должна найтись закрывающая). Заведём массив и переменную для хранения номера последнего значимого элемента в массиве (то есть вершины стека), в который при проходе по строке будем складывать все открывающиеся скобки (с величением номера вершины на 1), при встрече с закрывающей будем далять соответствующую открывающую (попросту уменьшать номер вершины стека). Если окажется, что пришла закрывающая скобка, а стек пуст (то есть номер вершины равен 0), то выражение ошибочно. Это же можно сказать и в случае, когда строка закончилась, стек не пуст.

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

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

Любая реализация стека должна содержать следующие процедуры

procedure InitStack

procedure Push(d: tData)

procedure Pop(var d: tData)

function NotEmpty: boolean

Очередь отличается от стека тем, что последний пришедший в неё элемент будет извлечён последним, а первый Ц

Любая реализация очереди (не обязательно с помощью списков) должна луметь выполнять такие действия:

procedure InitQueue

procedure AddQueue(d: tData)

procedure

function NotEmpty: boolean

Лекция 17. Деревья и поиск в деревьях

...........

.....

Tree

Data

Data

Data

Data

Data

Data

Data


Деревьями называются структуры данных следующего вида:

Элементы дерева называются вершинами. Вершина Tree^

Подробнее мы рассмотрим вариант двоичного дерева, то есть такого, в котором каждая вершина имеет два поддерева (

При описанном построении дерева поиск оказывается довольно простым делом:

Для реализации двоичного дерева сначала рассмотрим его описание на Паскале:

type

Под данными (tMyData)

type

Для того чтобы реализовать действия с двоичным дерево, нам понадобятся так называемые рекурсивные процедуры. Функция или процедура называется рекурсивной, если она вызывает сама себя. Такой вариант рекурсии называется прямым. Кроме того, бывает и косвенная рекурсия, когда одна процедура вызывает другую, та в свою очередь вызывает первую.

В качестве примера рассмотрим функцию для вычисления факториала, в которой мы заменим цикл (или итерацию) рекурсией. Её идея проста: если аргумент равен нулю, то возвращаем значение 1, в противном случае возвращаем значение

function

begin

end

Подобным образом можно применить рекурсию для вычисления n-

function

begin

end

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

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

procedure

begin

end

После того как дерево построено, можно выполнять поиск (также рекурсивный):

function

{

begin

end

Легко заметить, что элементы данных, луложенные в двоичное дерево можно выводить в отсортированном порядке:

procedure

begin

end

Лекция 18. Таблицы и простейшие алгоритмы поиска.

Таблицей будем называть структуру данных, пригодную для хранения набора данных, имеющих одинаковые типы. Простейшим примером такой структуры может служить массив, поскольку тип всех его элементов один и тот же. Чаще всего элемент таблицы состоит из нескольких частей, одна из которых имеет наибольшее значение (называется ключом), остальные содержат информацию, связанную с этим ключом, или собственно данные. Если всё это изобразить графически, то получится то, что называется таблицей в обычном смысле:

Ф. И. О.

дрес

Телефон

Год рождения

Петров Ф. М.

Северная 99-88

29-29-29

1962

Иванов П. С.

Мира -

77-88-99

1976

Козлов Н. В.

Октябрьская 135-246

45-67-89

1970

.................

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

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

type

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

type

Типы tKey

Рассмотрим теперь некоторые способы реализации всей таблицы:

1. Массив

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

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

const

type

var

Предполагается, что в любой момент времени данные таблицы хранятся в первых n

2. Список

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

Как выглядит такая таблица на Паскале нам же известно:

type

var

3. Дерево

Как хранить и искать данные в двоичном дереве, мы же знаем, а таблицу можно задать так:

type

var

2. Алгоритмы

1. Линейный поиск в массиве

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

procedure

var

begin

end

Рассмотрим подробнее части этой процедуры. Параметрами процедуры являются таблица (T

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

procedure

var

begin

end

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

2. Двоичный поиск

Следующий алгоритм также применяется для таблицы, представленной в виде массива, кроме того, массив должен быть отсортированным по значениям ключа (для определённости - по возрастанию). Тогда при поиске можно использовать следующие соображения: возьмём элемент, находящийся в середине массива, если его ключ равен искомому ключу, то мы нашли нужный элемент, если меньше - продолжаем поиск в первой половине массива, если меньше Ч то во второй. Под продолжением понимаем аналогичный процесс: вновь берём средний элемент из выбранной половины массива, сравниваем его ключ с искомым ключом, и т. д. Этот цикл закончится, когда часть массива, в которой производится поиск, не будет содержать ни одного элемента. Так как этот алгоритм многократно разбивает массив на две части, то он называется алгоритмом двоичного поиска. Ниже приведена соответствующая процедура на Паскале.

procedure

var

begin

end

Переменные l,

3. Линейный поиск в списке

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

procedure

var

begin

end

Параметр T

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

Лекция 1

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

Позволим данным располагаться в любых элементах массива, а не только в первых n

const

type

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

Реализованная описанным способом таблица называется перемешанной (или hash

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

function

var

begin

end

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

procedure

var

begin

end

У написанной процедуры есть один существенный недостаток: если элемент, номер которого казала нам хэш-функция был занят, то новые данные будут записаны на место старых, старые бесследно исчезнут. Чтобы решить эту проблему будем пытаться найти какой-либо другой свободный элемент для добавляемых данных. Здесь понадобится ещё одна функция (вторичная хэш-функция), которая по номеру занятого элемента и по значению ключа добавляемых данных кажет номер другой ячейки, если и там будет занято, вызовем вторичную функцию ещё раз, и т. д. до тех пор пока свободная ячейка не найдется.

Наиболее простая хэш-функция будет добавлять к номеру занятой ячейки какое-нибудь постоянное число:

const

function

begin

end

Остаток от деления на nmax

Сейчас можно написать окончательный вариант процедуры добавления элемента данных в таблицу:

procedure

var

begin

end

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

const

procedure

var

begin

end

Процедура выдаёт ответ о результатах поиска через параметр-переменную index