Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
PAGE 44
Алгоритмический язык PASCAL Краткий курс лекций
Краткий курс лекций
по основам структурного программирования
на языке Pascal
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
[10]
[11]
[12]
[13] [13.0.1] Текстовые файлы
[13.0.2]
[14] [15] Список литературы |
Программа на языке Pascal имеет следующую структуру:
Program <имя>; <блок описаний>; begin <оператор 1>; <оператор 2>; … <оператор N> end. |
{заголовок программы } { описание данных (модулей, констант, типов, переменных, процедур и функций) } { начало исполняемой части программы } { исполняемая часть тело программы } { конец программы } |
В фигурные скобки заключаются комментарии к программе это поясняющий текст произвольного содержания. Комментарии не обрабатываются транслятором.
Имя программы является идентификатором. Идентификатор может состоять из латинских букв, цифр и символа _ (подчеркивание) и начинаться не с цифры.
В блоке описаний описываются:
Uses <имя модуля>;
Const <имя>=<значение>;
Type <имя типа>=<описание>;
Var <имя переменной>:<тип>;
Тип может быть стандартным, а также сконструированным и описанным в разделе описания типов.
Базовые стандартные типы:
Procedure <описание процедуры>;
Function <описание функции>;
Исполняемая часть программы представляет собой составной оператор несколько операторов языка, заключенных в операторные скобки Begin и End.
Все операторы языка можно условно разделить на команды и конструкции.
Команда (оператор) присваивания:
<имя переменной> := <выражение>;
Сначала будет вычислено значение выражения, которое затем будет записано в переменную с указанным именем. В записи выражения могут быть использованы константы, переменные, знаки операций, стандартные (и определенные программистом) функции, а также скобки.
Например: X:=10; - в переменную Х будет записано число 10;
Y:=X+6; - в переменную Y будет записано число 16;
Y:=Y+1; - в переменную Y будет записано число 17 (число 16 будет стерто из памяти).
Для обработки вещественных чисел в языке Turbo Pascal предусмотрены следующие операции: + (сложение), (вычитание), * (умножение), / (деление). Для обработки целых чисел: + (сложение), (вычитание), * (умножение), div (целочисленное деление), mod (остаток от деления нацело).
Наиболее часто используемые стандартные функции перечислены в Таблице 1. Аргумент функции (константа, переменная или выражение) при ее вызове заключается в круглые скобки.
Таблица 1
Некоторые стандартные функции языка Turbo Pascal
Имя функции |
Описание функции |
Abs (x) |
Модуль (абсолютная величина) числа x |
Sqrt (x) |
Извлечение квадратного корня из числа x |
Sqr (x) |
Возведение числа x в квадрат (во вторую степень) |
Exp (x) |
Экспонента числа x (т.е. ex) |
Sin (x) |
Синус угла x (значение угла должно быть представлено в радианах) |
Cos (x) |
Косинус угла x (значение угла должно быть представлено в радианах) |
Arctan (x) |
Арктангенс числа x |
Ln (x) |
Натуральный логарифм числа x |
Random (x) |
Датчик случайных чисел возвращает случайное число из интервала от 0 до x-1. Инициализация датчика случайных чисел выполняется командой Randomize (стандартная процедура). |
Round (x) |
Округление вещественного числа x до целого |
Trunc (x) |
Целая часть вещественного числа x |
Frac (x) |
Дробная часть вещественного числа x |
Команда (оператор) вывода:
Write (<список вывода>);
Выводит информацию на экран. Элементами списка вывода могут быть константы и выражения (на экран будут выведены их значения). Элементы списка вывода разделяются запятыми.
Writeln (<список вывода>);
Выводит информацию на экран, после чего переводит курсор в начало следующей строки (т.е. выводит специальный символ «конец строки»).
Команда (оператор) ввода:
Readln (<имя переменной>);
Приостанавливает работу программы и ожидает ввода данных с клавиатуры. После набора данных и нажатия клавиши <Enter> производится проверка соответствия типов введенных данных и указанной переменной. Если их типы совпадают, данные записываются в переменную с указанным именем.
Если необходимо ввести значения нескольких переменных, их имена можно перечислить через запятую.
Линейной называется программа, в которой все команды выполняются последовательно, одна за другой, причем каждая команда выполнится ровно один раз.
Для организации ветвления в программе на языке Pascal используются условный оператор (конструкция ветвления в полной и сокращенной форме) и оператор варианта.
Ветвление в полной форме:
If <условие> Then <оператор 1> Else <оператор 2>;
где <условие > - логическое выражение, которое может принять одно из двух значений истина или ложь; условия могут быть простыми (с использованием операций отношения >, <, =, <>, <=, >=) или сложными (с использованием логических операций Not, And, Or, Xor);
<Оператор1> и <Оператор2> - простые или составные операторы. <Оператор1> будет исполнен в случае, когда условие истинно. <Оператор2> - если условие ложно. Одновременно <Оператор1> и <Оператор2> выполнены быть не могут. Ветвление в полной форме может быть представлено в виде блок-схемы на рис.1.
Ветвление в сокращенной форме:
If <условие> Then <оператор>;
Ветвление в сокращенной форме может быть представлено в виде блок-схемы на рис.2.
Оператор варианта:
Позволят осуществить множественный выбор. Имеет вид:
Case <переключатель> Of
<константа 1> : <оператор 1>;
<константа 2> : <оператор 2>;
…
<константа n> : <оператор n>
Else <оператор>
End;
где: <переключатель> - переменная (выражение) перечисляемог типа (из стандартных к перечисляемым относятся: Integer, Char, Boolean);
<константа i> - возможные значения переключателя;
<оператор i> - простой или составной оператор, который будет исполнен в случае, если значение переключателя будет равным соответствующей константе;
<оператор> - простой или составной оператор, который будет исполнен в случае, если значение переключателя не совпадет ни с одной из констант.
Циклом называется многократное повторение некоторого набора действий. Эти повторяющиеся действия называются телом цикла. Программа, содержащая цикл, называется циклической.
В языке Pascal существует три оператора для организации циклов трех разных видов.
Цикл с предусловием:
While <условие> Do
<тело цикла>;
где: <условие> - логическое выражение,
<тело цикла> - простой или составной оператор.
Компьютер сначала проверяет условие (поэтому цикл называется циклом с ПРЕДусловием). Если оно истинно, будет выполнено тело цикла, и произойдет переход снова на проверку условия. То есть, пока условие истинно, будет выполняться тело цикла. Таким образом, условие является в данном операторе условием выполнения цикла. Цикл с предусловием может быть представлен блок-схемой на рис.3.
Тело цикла может выполняться бесконечно (условие всегда истинно), может не выполниться ни разу (условие сразу ложно).
Цикл с постусловием:
Repeat
<тело цикла>
Until <условие>;
где <условие> - логическое выражение,
<тело цикла> - группа операторов.
Компьютер сначала выполняет тело цикла, затем проверяет условие (поэтому цикл называется циклом с ПОСТусловием). Если оно ложно, будет вновь выполнено тело цикла, и так до тех пор, пока условие не станет истинным. Таким образом, условие в данном операторе является условием окончания цикла. Цикл с постусловием может быть представлен блок-схемой на рис.4.
Тело цикла всегда выполнится хотя бы один раз, может выполняться бесконечно (если условие всегда ложно).
Цикл со счетчиком (с параметром):
For k:=A To B Do
<тело цикла>;
где: k счетчик (переменная перечислимого типа, в ней хранится количество сделанных повторов тела цикла),
А начальное значение счетчика,
В конечное значение счетчика,
<тело цикла> - простой или составной оператор,
шаг изменения счетчика +1.
При А>В тело цикла не будет выполнено ни разу.
Если необходимо использовать цикл со счетчиком, меняющимся с шагом -1, оператор приобретает вид:
For k:=A Downto B Do
<тело цикла>;
где А>В.
Если алгоритм требует другого шага изменения счетчика (отличного от +1 и -1), необходимо использовать другие операторы цикла (While или Repeat).
Символьный тип Char. Значением является один символ. Все символы упорядочены. Порядковый номер символа его код. К данным символьного типа применимы операции отношения (сравниваются коды символов). Отображаемыми (на экране) являются символы с кодами от 32 до 255. Символы с кодами от 0 до 31 управляющие. Русские и латинские буквы упорядочены по алфавиту.
Функции преобразования:
Порядковые функции:
Строковый тип String. Строка произвольная последовательность символов. Длина строки количество символов в ней. Пустая строка не содержит ни одного символа. Ее длина равна нулю. Pascal допускает использование строк длиной до 255 символов.
Строковая константа заключается в апострофы: Мама мыла раму.
Описание строковой переменной:
Var <имя переменной> : String [N];
где N максимальная длина строки. Если она не указана, максимальной длиной строки считается число 255.
Например:
Var Family : String [20];
Name : String [10];
P : String;
Номер символа в строке называется еще индексом. Для обращения к отдельному символу строки его индекс указывается после имени строки в квадратных скобках. Например, P[3] 3-й символ строки P; Name[K] K-й символ строки Name.
К данным строкового типа применима операция конкатенации (обозначается символом «+»). Например, после выполнения последовательности команд:
A:= тепло;
B:= ход;
C:= A+B;
в переменной С будет записана строка теплоход.
К данным строкового типа применимы операции отношения, причем строки сравниваются посимвольно, с учетом порядковых номеров символов в алфавите. Например, мама < папа, машина>мама.
Стандартные функции:
A := крокодил;
B := код;
K := Pos (B, A);
N := Pos (о, A);
M := Pos (a, A);
переменные К, N, M примут следующие значения: K=4, N=3, M=0.
A := крокодил;
B := Copy (A, 2, 3);
значением переменной В будет слово рок.
Стандартные процедуры:
A := корзина;
Delete (A, 4, 3);
значением переменной A будет слово кора.
A := кот;
Insert (р, A, 2);
значением переменной A будет слово крот.
Данные, обрабатываемые программой, записанной на языке TurboPascal, принадлежат к одному из следующих типов, классификация которых представлена на рис.5:
Перечисляемый тип задается перечислением тех значений, которые он может получать. Определяется как упорядоченный набор идентификаторов, заданных путем их перечисления.
Например:
Type Colors = ( red, green, blue );
Var Col : Colors;
Переменная Col может принять одно из трех значений: red, green, blue.
Таким образом, каждое значение именуется некоторым идентификатором и располагается в списке, ограниченном круглыми скобками. Идентификаторы перечисляются через запятую.
Значения перечисляемого типа упорядочены: первое имеет порядковый номер 0, второе 1 и т.д.
Можно использовать следующие стандартные функции:
Ord (x) возвращает порядковый номер элемента x;
Succ (x) возвращает значение, следующее за х;
Pred (x) возвращает значение, предшествующее х.
В приведенном выше примере:
a := ord (red); { Значение переменной a = 0 }
col := succ (green); { col = blue }
col := pred (col); { col = green }
Значения перечисляемого типа можно сравнивать: сравниваются их порядковые номера.
К данным этого типа нельзя применять стандартные команды ввода (Readln) и вывода (Write).
Назначение перечисляемого типа сделать текст программы более наглядным (читабельным).
Тип-диапазон называют также ограниченным и интервальным типом.
Тип-диапазон есть подмножество своего базового типа, в качестве которого может выступать любой порядковый тип, кроме самого типа-диапазона (т.е. типы Integer, Boolean, Char, перечисляемый тип).
Диапазон задается границами своих значений внутри базового типа:
<минимальное значение> .. <максимальное значение>
Причем минимальное значение должно быть больше либо равно максимальному.
Например:
Type Digit = 0..9; { тип-диапазон, ограничение наложено на Char }
Year = 1900..2006; { тип-диапазон, ограничение на Integer }
Week = {mon, tues, wed, thur, fri, sat, sun); { перечисляемый тип (дни недели)}
Var d : Digit;
y : Year;
m : 1..12; { переменная m относится к ограниченному типу}
work : mon .. fri; { тип-диапазон, ограничение наложено на Week }
Тип-диапазон наследует все свойства своего базового типа.
Назначение типа-диапазона:
Множество это неупорядоченный набор однотипных элементов.
Количество элементов в множестве от 0 до 256.
Пустое множество это множество, которое не содержит ни одного элемента.
Два множества эквивалентны, если все их элементы одинаковы (порядок перечисления значения не имеет).
Первое множество включено во второе, если все элементы первого множества являются также элементами второго.
Пустое множество включено в любое другое.
Описание множественного типа:
Type <имя типа> = Set Of <базовый тип>;
В качестве базового типа может использоваться любой порядковый тип, мощность которого не больше 256. Из стандартных это Char, Boolean. Integer напрямую в качестве базового типа для множества использовать нельзя. Сначала нужно описать тип-диапазон (не более 256 чисел).
Например:
Type digit = Set Of 0..9;
setchar = Set Of Char;
Var d1, d2 : digit;
c : setchar;
Для задания множества (т.е. присваивания ему некоторых значений) используется конструктор множества это список элементов множества, разделенных запятыми. Список ограничен квадратными скобками.
В качестве элементов могут быть:
Например:
d1 := [ 0..3 , 6 ];
d2 := [ ];
c := [a .. z , A .. Z ];
Операции над множествами:
* |
пересечение множеств: результат содержит элементы, общие для двух множеств |
+ |
объединение множеств: результат содержит элементы 1-го множества, дополненные недостающими элементами из 2-го множества |
- |
разность множеств: результат содержит элементы из 1-го множества, которых нет во 2-м множестве |
= |
проверка эквивалентности |
<> |
проверка неэквивалентности |
<= >= |
проверка вхождения во множество: (содержит) (содержится) |
in |
проверка принадлежности элемента множеству (элемент задается как выражение соответствующего типа) |
Стандартные процедуры:
Include ( S , i ); включает элемент i в множество S;
Exclude ( S , i ); исключает элемент i из множества S.
Процедуры исполняются быстрее, чем операции <+> и < -> .
Массив это упорядоченная (пронумерованная) последовательность однотипных элементов. Массив имеет общее для всех элементов имя. Номер элемента массива называют еще его индексом. В качестве индексов можно использовать значения любого порядкового типа. Например:
А массив из пяти целых чисел. Индексы элементов целые числа от 1 до 5. |
|
В - массив из 5 вещественных чисел. Индексы элементов целые числа от 2001 до 2005. |
|
C - массив из 5 целых чисел. Индексы элементов символы от a до e. |
|
W массив из пяти строк. Индексы элементов целые числа от 1 до 5. |
Доступ к элементам массива осуществляется по индексу, который указывается после имени массива в квадратных скобках. Например, в приведенных выше примерах: A[2]=12, B[2005]=5.9, C[d]=234, W[1+2]=раму.
Массивы реализованы практически во всех структурных и объектно-ориентированных языках программирования.
Обработка массивов в языке TurboPascal:
Type <имя типа>=Array [<min индекс>..<max индекс>] Of <тип элементов массива>;
Var <имя переменной> : <имя описанного выше типа>;
Например:
Type List = Array [1..30] Of String;
MasNum = Array[1..15] Of Real;
Var Fam, Name : List; { Переменные Fam и Name массивы строк }
Year, a, b : MasNum; { Переменные Year,
a и b массивы вещественных чисел }
Для обработки массивов наиболее часто используется оператор цикла со счетчиком For.
Фрагмент программы, позволяющий осуществить ввод значений элементов массива A из N элементов, может быть записан следующим образом:
…
For i := 1 to n do
begin
Write (введите , i , -ый элемент );
Readln ( A[i] )
end;
…
…
Randomize; { инициализация датчика случайных чисел }
For i := 1 to n do
A[ i ] := random(100); { в этом случае значения элементов будут лежать в интервале от 0 до 99 }
…
…
For i := 1 to n do
Writeln( A[i] );
…
Алгоритм сортировки по убыванию состоит в следующем:
…
For i := 1 to n-1 do
For j := i+1 to n do
If A[ j ] > A[ i ] then
begin { меняем местами i-ый и j-ый элементы массива А }
p := A[ i ]; { для этого используем Ъ
A[ i ] := A[ j ]; { промежуточную переменную p, тип которой }
A[ j ] := p { должен совпадать с типом элементов массива }
end;
…
При сортировке по убывания нужно в тексте программы изменить лишь знак «>» на знак «<».
Размер массива это количество элементов в нем.
Размерность массива это количество индексов, которые нужно указать для доступа к элементу массива. Выше были рассмотрены одномерные массивы. Массивы могут быть также двумерными (матрицы, таблицы), трехмерными, и любой другой размерности, необходимой для решения поставленной задачи. Рассмотрим более подробно двумерные массивы.
Двумерный массив можно представить в виде совокупности пронумерованных строк и столбцов:
1 |
2 |
3 |
4 |
5 |
6 |
|
1 |
24 |
-57 |
0 |
12 |
1 |
13 |
2 |
103 |
6 |
-134 |
2 |
15 |
-8 |
3 |
5 |
9 |
24 |
-11 |
-67 |
91 |
4 |
-7 |
10 |
8 |
421 |
36 |
-22 |
5 |
11 |
47 |
-3 |
14 |
59 |
32 |
А
Двумерный числовой массив А состоит из 5 строк и 6 столбцов. Для того чтобы обратиться к отдельному элементу этого массива, нужно указать после его имени индексы в квадратных скобках через запятую сначала номер строки, затем номер столбца. Например: А[1,3]=0, А[4,1]= -7, А[4,6]= -22, А[2,5]=15.
Использование двумерных массивов в программах на языке TurboPascal:
Type <имя типа> = Array [ <min номер строки>..<max номер строки> , <min номер столбца>..<max номер столбца> ] Of <тип элементов массива>;
Var <имя переменной> : <имя описанного выше типа>;
Например:
Type Mas2 = Array [1..5, 1..6] Of Integer;
Var a : Mas2;
{Переменная a двумерный массив целых чисел, в котором 5 строк и 6 столбцов}
Для обработки двумерных массивов наиболее часто используется вложенные циклы (цикл по строкам и цикл по столбцам, или элементам строки).
Фрагмент программы, позволяющий осуществить ввод значений элементов массива A из N строк и М столбцов, может быть записан следующим образом:
…
For i := 1 to n do
For j := 1 to m do
begin
Write ( A [ , i , j , ] = );
Readln ( A[i , j] )
end;
…
…
For i := 1 to n do
begin
For j:=1 to m do
Write ( A[i , j] : 3 ); {выводим все элементы i-ой строки массива в одну
строку на экране}
Writeln { переводим на экране курсор на следующую строку}
end;
…
Для работы в графическом режиме в языке Turbo Pascal реализованы следующие возможности:
Uses Graph;
g1 := detect; {автоопределение типа графического адаптера }
InitGraph (g1, g2, C:\tp70\BGI); {инициализация графики}
Устанавливается графический режим с разрешением 640x480 точек.
Графика растровая (точечная). Точка - пиксел.
Переменные g1 и g2 имеют тип Integer.
CloseGraph;
PutPixel (x, y, c):
SetBkColor (c);
SetColor (c);
Line (x1, yl, x2, y2);
(xl, y1) и (х2, у2) - координаты концов отрезка.
Circle (x, y, r);
Rectangle (x1, у1, х2, у2);
(xl, y1) и (х2, у2) координаты любой из диагоналей.
А) установка типа S и цвета С штриховки:
SetFillStyle (s, c);
где 0<=S<= 11 (0 - штриховка цветом фона, т.н. «пустая», 1 - сплошная заливка, прочие значения различные типы штриховки).
Б) закрашивание области с границей цвета b:
FloodFill (x, y, b);
b - цвет границы (до этого цвета будет "разливаться" краска (штриховка)).
SetFillStyle (s, c);
Ваг(х1, у1, х2, у2);
(xl, yl) и (х2, у2) - координаты любой из диагоналей.
SetFillStyle (s, c);
Bar3D (xl, yl, x2, y2, d, Top);
(xl, yl) и (х2, у2) - координаты любой диагонали передней грани, d-глубина, Тор - логический параметр, указывающий, рисовать ли верхнюю грань параллелепипеда: True рисовать, False - нет.
13. Рисование эллипса или его дуги:
Ellipse (x, y, a1, a2, xr, yr);
(х, у) - координаты центра,
a1 - начальный угол (в градусах),
а2 - конечный угол (в градусах),
хr - радиус по оси X,
уr - радиус по оси Y.
SetFillStyle (s, c);
Sector (х, у, а1, a2, xr, yr);
(х, у) - координаты центра,
a1 - начальный угол (в градусах),
а2 - конечный угол (в градусах),
хr - радиус по оси X,
уr - радиус по оси Y.
A) установка шрифта: SetTextStyle (f, d, s);
f - номер шрифта (0 - матричный шрифт 8x8),
d - направление вывода символов (0 - горизонтально,1 - слева направо),
s - размер символов.
Б) вывод текста: OutTextXY (x, y, s);
(х, у) - координаты левого верхнего угла выводимой строки,
s выводимая текстовая строка.
Подпрограмма это часть программы (составной оператор), имеющая собственное имя и вызываемая по этому имени из основной (головной) программы или других подпрограмм. В языке Паскаль реализованы подпрограммы двух видов: процедуры и функции. Действует правило описание должно предшествовать вызову (т.е. подпрограмма должна быть сначала описана, а только после этого может быть вызвана).
Процедуры в языке TurboPascal
Procedure <имя> (<список параметров>); { заголовок процедуры }
<блок описаний>
Begin { начало исполняемой части процедуры}
<тело процедуры (исполняемая часть)>
End; { конец процедуры }
Структура процедуры почти полностью совпадает со структурой программы. Исключения:
I. Заголовок: начинается с зарезервированного слова Procedure (а не Program), кроме того содержит список параметров. Параметры это «средство связи» процедуры с программой и с другими процедурами, механизм обмена данными. Параметры процедуры бывают двух видов:
- параметры-значения, или входные параметры это исходные (входные) данные, передаваемые в процедуру. Их значения после окончания работы процедуры остаются неизменившимися. Описание параметров-значений: <имя> : <тип> .
- параметры-переменные, или выходные параметры это результаты работы процедуры, передаваемые обратно в программу или другую процедуру. Их значения после окончания работы процедуры изменяются. Описание параметров-переменных: Var <имя> : <тип> .
Например, процедура может иметь такой заголовок:
Procedure Calculate ( x, y : integer; var z : integer; var f : real );
Имя этой процедуры Calculate. Она имеет 4 параметра: два входных (или параметра значения) это параметры x и y целого типа; два выходных (или параметра-переменных) z целого типа и f вещественного типа. Так как типы у них различны, перед описанием каждого указано зарезервированное слово Var.
Параметры, указанные при описании процедуры (т.е. в ее заголовке) называются формальными, т.к. процедура это по сути формальное правило получения некоторых результатов из некоторых исходных данных. Конкретным смыслом формальные параметры наполняются при вызове процедуры (см. ниже).
Можно использовать процедуры и без параметров.
II. Блок описаний может содержать те же разделы, что и блок описаний программы (Const, Type, Var, Procedure, Function), за исключением описания подключения модулей библиотек Uses (модули подключаются только в блоке описаний в основной программе!).
Данные, описанные в блоке описаний процедуры, называются локальными и могут быть использованы только в этой процедуре.
Данные, описанные в блоке описаний программы, называются глобальными и могут использоваться как в самой программе, так и во всех ее процедурах.
III. Тело процедуры также представляет собой составной оператор, но заканчивается End; (ставится точка с запятой, а не точка, как в конце программы).
может осуществляться из основной программы или процедуры, описанной после вызываемой. При вызове указывается имя процедуры и список фактических параметров, т.е. тех, которые будут «подставлены» на место формальных. Количество, порядок и типы фактических параметров должны совпадать с количеством, порядком и типами формальных параметров. Например, процедуру Calculate, заголовок которой был описан выше, можно вызвать следующим образом:
Calculate( a, b, c, d ); - при условии, что a, b, c имеют тип Integer, d Real.
Calculate( 23, р+14, q, w ); - если p и q имеют тип Integer, а w Real.
Исходя из всего вышесказанного следует, что команды языка (например, Write, Readln) это тоже процедуры, которые описаны в некоторых библиотеках и которые мы вызываем при написании наших программ.
Функции в языке TurboPascal
Практически все сказанное о процедурах верно и для функций. Отличие функции от процедуры состоит в том, что функция не имеет выходных параметров, она возвращает единственное значение это значение функции. Входные параметры называются еще аргументами функции.
Function <имя> (<список аргументов>): <тип значения функции>;
{заголовок }
<блок описания локальных данных>
Begin { начало исполняемой части функции }
<тело функции (исполняемая часть)>
End; { конец описания функции }
В теле функции обязательно должна быть команда присваивания вида:
<имя функции> := <вычисленное значение>;
которая и позволит функции возвратить вычисленное значение.
Например, опишем функцию вычисления среднего арифметического двух целых чисел:
Function middle (a, b : integer) : real;
Begin
Middle := ( a + b ) / 2
End;
В данном примере тело функции единственный оператор присваивания, который присваивает имени функции нужное значение.
Тип данных запись позволяет объединять разнотипные данные.
Запись это совокупность компонентов разного типа. Компонент записи называется ее полем. Каждое поле имеет уникальное имя.
Обработка записей в языке TurboPascal:
Описание нового типа данных - запись:
Type <имя типа> = Record
<имя поля 1> : <тип поля 1>;
…
<имя поля N> : <тип поля N>
End;
Если несколько полей имеют одинаковый тип, их имена можно перечислить через запятую.
Var <имя переменной> : <имя описанного выше типа>;
Например:
Type Book = Record { тип данных книга состоит из трех полей }
Name, Author : String [ 30 ]; { название и автор }
Year : Integer { год издания }
End;
Var Bk : Book; { Переменная Bk запись с тремя полями }
Обращение к полям записи:
Для обращения к отдельному полю записи следует сначала указать имя переменной типа запись, затем через точку имя поля. Например: Bk.Name.
Для ввода значений полей описанной выше записи Bk может быть записан следующий фрагмент программы:
Write (Введите название книги ); Readln (Bk.Name);
Write (Введите фамилию автора ); Readln (Bk.Author);
Write (Введите год издания книги ); Readln (Bk.Year);
При многочисленных обращениях к полям одной и той же записи можно использовать оператор присоединения With.
With <имя переменной-записи> Do
<составной оператор>;
Оператор With позволяет «вынести за скобки» имя переменной-записи. Приведенный выше фрагмент программы можно переписать с использованием оператора присоединения:
With Bk Do
Begin
Write (Введите название книги ); Readln (Name);
Write (Введите фамилию автора ); Readln (Author);
Write (Введите год издания книги ); Readln (Year)
End;
Все программы, составленные до настоящего момента, обрабатывали данные (переменные, константы), хранящиеся в оперативной памяти компьютера. Часто это крайне неудобно, например, если каждый раз при запуске программы требуется вводит большой объем исходных данных, или одни и те же данные должны обрабатываться несколькими программами.
В языке Pascal, как и во многих других развитых языках программирования, существует возможность хранить данные независимо от программы. Для этого эти данные должны быть представлены в виде файла.
Файл это поименованное место на внешнем носителе, представляющее собой совокупность отдельных записей. Файл данных позволяет:
По способу представления данных файлы делятся на
По способу доступа к данным файлы делятся на:
В обобщенном виде алгоритм работы с файлами следующий:
Записи текстового файла это строки различной длины, поэтому текстовые файлы являются файлами последовательного доступа. Структура текстового файла представлена на рис.6.
Eoln |
||||||
Eoln |
||||||
Eoln |
||||||
Eoln |
||||||
Eof |
||||||
Рис.6. Структура текстового файла |
Таким образом, текстовый файл представляет собой совокупность строк разной длины. Именно поэтому к записям файла возможен только последовательный доступ. Каждая строка заканчивается специальным неотображаемым символом Eoln («End of line» - конец строки). В конце файла записан специальный неотображаемый символ Eof («End of file» - конец файла).
В текстовом файле может храниться не только текст, но и данные других типов (например, числа) в текстовом представлении (т.е. по сути дела все равно текст).
Для работы с текстовыми файлами в языке Pascal используются следующие команды, описания и функции:
Var f : text;
где f имя файловой переменной, text еще один стандартный тип данных текстовый файл.
Файловая переменная это переменная-указатель, посредством которой идет взаимодействие программы (чтение/запись данных) с внешним файлом.
Assign ( f, <имя файла> );
где f имя файловой переменной, <имя файла> - строковая константа или переменная. Например, выполнение команды
Assign ( f, c:\tp70\example.txt );
свяжет файловую переменную f с файлом «example.txt», который расположен на диске C: в папке с именем «tp70». После записи такой команды в тексте программы нигде далее не будет указываться имя файла, с которым работает программа.
Rewrite (f);
Файл создается заново. Если для записи открыт уже существующий файл, то все данные из него будут потеряны.
Reset (f);
Для чтения можно открыть только существующий файл. Указатель устанавливается на первую запись (т.е. на первый символ первой строки) файла.
Append (f);
Для дополнения можно открыть только существующий файл. Указатель устанавливается после последней записи (строки).
Write ( f, <список вывода> );
По сути, используется та же команда, что и для вывода данных на экран. Имя файловой переменной f указывает на то, что вывод будет осуществляться в файл.
Команда Writeln ( f, <список вывода> ); записывает в текстовый файл данные и символ Eoln.
Read ( f, <список переменных> );
Команда Readln ( f, <список переменных> ); позволяет прочитать данные, а также символ Eoln.
Close ( f );
Записи типизированного (структурированного) файла имеют одинаковый тип (а значит, имеют одинаковый размер именно поэтому к ним и возможен прямой доступ). Структуру типизированного файла представлена на рис.7.
Запись 0 |
Запись 1 |
Запись 2 |
Запись 3 |
Eof |
Рис.7. Структура типизированного файла |
Записи файла пронумерованы. Нумерация начинается с нуля. В конце файла записан специальный неотображаемый символ Eof («End of file» - конец файла).
Для работы с типизированными файлами в языке Pascal используются следующие команды, описания и функции:
Var f : File Of <тип записи файла>;
где f имя файловой переменной.
Файловая переменная это переменная-указатель, посредством которой идет взаимодействие программы (чтение/запись данных) с внешним файлом.
Записи файла могут иметь любой из рассмотренных выше типов (как стандартный, так и сконструированный в блоке Type).
Например:
Type Stud = Record
Name : String;
Group : Integer;
Rating : Real
End;
Var f1 : File of Stud; { записями файла f1 являются записи (Record) из трех полей }
f2 : File Of Integer; { записи файла f2 целые числа }
Assign ( f, <имя файла> );
где f имя файловой переменной, <имя файла> - строковая константа или переменная. Например, выполнение команды Assign ( f, c:\tp70\data ) свяжет файловую переменную f с файлом «data», который расположен на диске C: в папке с именем «tp70». После записи такой команды в тексте программы нигде далее не будет указываться имя файла, с которым работает программа.
Rewrite (f);
Файл создается заново. Если для записи открыт уже существующий файл, то все данные из него будут потеряны.
Reset (f);
Для чтения можно открыть только существующий файл. Указатель устанавливается на первую запись (т.е. на первый символ первой строки) файла.
Write ( f, <имя переменной> );
Тип переменной должен совпадать с типом записей файла.
Read ( f, <имя переменной> );
Close ( f );
Статические и динамические переменные
Переменные в тексте программы описываются в разделе описания переменных. Например:
Var a, b : integer;
s : string;
m : array [1..100] of real;
Такие «обычные» статические переменные располагаются в части оперативной памяти компьютера, называемой стеком (stack). Объем стека не превышает 64 Кбайтов. Перед исполнением программы в стеке резервируются участки памяти, размер которых соответствует типу переменных, описанных в разделе описания переменных (VAR).
Кроме того, программист имеет возможность использовать в своей программе динамические переменные, память для которых резервируется уже в процессе исполнения программы и затем, если в них больше нет необходимости, может быть освобождена. Такие переменные располагаются в другой части оперативной памяти компьютера. Такая динамически распределяемая память называется кучей (Heap-областью).
Необходимость в использовании динамических переменных возникает в следующих случаях:
При работе с динамическими переменными возникает необходимость работы с данными ссылочного типа, или указателями.
Указатели
Указатель это переменная целого типа, которая интерпретируется как адрес какого-либо элемента данных (переменной, константы, адреса другого элемента данных). Т.е. указатель это адрес. Кроме этого, употребляют термин ссылка. Это синонимы.
В языке Pascal существует возможность получить значение адреса любой переменной, как статической, так и динамической. Это можно сделать посредством функции Addr.
Например, после исполнения команды присваивания
p := Addr (a);
в переменную p будет записан адрес1 переменной a. Вместо функции Addr можно использовать оператор @. То есть, вместо записанной выше команды можно написать:
p := @a;
В языке Turbo Pascal указатели бывают двух видов типизированные и нетипизированные.
Типизированные указатели
Типизированным называется указатель, который указывает (ссылается) на данные определенного типа. Для его объявления используется символ ^, который размещается перед соответствующим типом данных. Например:
Type mas = array[1..100] of real;
Var p1 : ^integer;
p2 : ^mas;
В этом случае p1 это ссылка (указатель) на целое число, p2 ссылка на массив из 100 вещественных чисел. Для того, чтобы обратиться к данным по этим адресам, необходимо указать: p1^, p2^. То есть, p1 это адрес, а p1^ - то, что по этому адресу находится.
Для выделения участка динамически распределяемой памяти (кучи) в целях размещения там необходимых данных используется стандартная процедура
New (p); , где p указатель.
После выполнения такой команды будет выделен блок памяти необходимого размера (для размещения тех данных, на которые ссылается указатель p), а сам указатель p приобретет значение адреса этого выделенного участка памяти. Например, после выполнения команд:
New (p1);
New (p2);
будет выделено два непрерывных участка кучи, первый размером 2 байта (т.к. целое число занимает 2 байта оперативной памяти), второй 400 байтов (100 * 4 байта для каждого из 100 вещественный чисел).
После выполнения этих команд указатели p1 и p2 приобрели конкретные значения. Поэтому по адресам, на которые они указывают, можно размещать конкретные значения соответствующего типа. Например,
p1^ := 52;
p2^[1] := 8;
Если в момент выполнения процедуры New в куче не окажется непрерывного участка памяти требуемого размера, то программа аварийно завершится с сообщением «Out of Memory». Для контроля размера доступного участка в динамически распределяемой памяти (куче) можно использовать функцию MaxAvail, которая возвращает размер максимального непрерывного участка кучи в текущий момент времени.
Для освобождения динамической памяти используется процедура
Dispose (p), где p указатель.
Например:
Dispose (p1); Dispose (p2);
После выполнения такой команды память, ранее связанная с указателем, возвращается в кучу (и может быть вновь использована уже для хранения других данных). Однако значение самого указателя не меняется, т.е. в нем остается адрес «несуществующего» (уже отданного обратно в кучу) блока памяти. Поэтому обращение к указателю после выполнения команды Dispose может привести к ошибке.
В паскале существует константа Nil пустой указатель. Значение Nil может быть присвоено любому указателю, например:
p2 := nil;
Однако выполнение такого присваивания до вызова процедуры
Dispose (p2) к тому, что указатель p2 не будет ссылаться ни на какой участок динамической памяти, а данные в памяти останутся, т.е. этот участок не будет возвращен в кучу. Это плохо по той причине, что при выполнении серии таких команд значительная часть динамической памяти будет считаться занятой, но использоваться не будет.
Константа Nil необходима при работе с динамическими структурами данных, что будет рассмотрено ниже.
Нетипизированные указатели
Нетипизированным называется указатель, не связанный с каким-то конкретным типом данных. Для его описания используется стандартный тип Pointer. Например,
Var p : pointer;
Нетипизированные указатели используются для динамического размещения данных, структура и тип которых могут меняться в ходе выполнения программы.
Для выделения памяти используется стандартная процедура
GetMem ( p, size );
где p указатель, переменная типа Pointer; size размер выделяемого участка памяти, выражение типа Word (целочисленный тип). За одно обращение к процедуре GetMem возможно выделение не более 65521 байта памяти (максимальное значение типа Word).
Для освобождения памяти и возвращения ее в кучу используется стандартная процедура
FreeMem ( p, size );
где p указатель, переменная типа Pointer; size размер освобождаемого участка памяти, выражение типа Word.
Константу Nil можно использовать и при работе с нетипизированными указателями.
Динамические структуры данных
Динамическими называют структуры данных, динамически создаваемые в ходе выполнения программы. Они размещаются в динамической памяти. К ним относятся списки: однонаправленные (стек, очередь), двунаправленные; графы (и прежде всего дерево как ориентированный граф).
Стек
Стеком называется структура данных, организованная по правилу LIFO: last input first output, т.е последним вошел первым вышел.
Глубина стека количество элементов в нем.
Вершина стека «верхний», т.е. доступный элемент.
Стек как структуру данных, размещенную в динамической памяти, можно представить как «цепочку» записей (Record), одно из полей которых есть указатель на предыдущий элемент. Стек из четырех элементов «выглядит» в памяти так, как изображено на рис.8:
1 Память в персональном компьютере адресуется двумя шестнадцатеричными словами (BA:BS), где BA - сегментный адрес, BS - смещение. Сегмент участок памяти длиной 64 Кбайта, который начинается с физического адреса, значение которого кратно числу 16. Смещение определяет номер байта в сегменте.
PAGE 1
Объекты
Процедурные
Указатели
Файлы
Множества
Записи
Строки
Массивы
Структурированные
Тип-диапазон
Перечисляемый
Символьный
огический
Вещественные
Целые
Порядковые
Простые
Типы
-8
12
0
234
3
5
4
3
2
1
А
3.5
7.8
0.8
-0.1
5.9
2005
2004
2003
2002
2001
В
-8
12
0
234
3
e
d
c
b
a
С
Мама
мыла
раму
и
Машу
5
4
3
2
1
W
4-й эл-т
ссылка
3-й эл-т
ссылка
2-й эл-т
ссылка
1-й эл-т
ссылка
Nil
указатель на вершину стека
Тело цикла
Условие
да
нет
…
Рис.3. Блок-схема цикла с предусловием
Тело цикла
Условие
нет
да
Рис.4. Блок-схема цикла с постусловием
Условие
Оператор 1
Оператор 2
Рис.1. Блок-схема ветвления в полной форме
Рис.2. Блок-схема ветвления в сокращенной форме
да
Оператор
Условие
нет
да
нет
Рис.5. Типы данных языка Паскаль
Рис.8. Стек из четырех элементов