ПОЛЬЗОВАТЕЛЬСКИЕ ТИПЫ ДАННЫХ




 

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

перечисляемый тип,

тип-диапазон,

массивы,

записи.

 

ПЕРЕЧИСЛЯЕМЫЙ ТИП

 

Перечисляемый тип задается перечислением тех значений, которые он может получать. Каждое значение должно являться идентификатором (смотри главу Алфавит языка) и располагаться в круглых скобках через запятую. Количество элементов в перечислении не более 65536. Вводить и выводить переменные перечисляемого типа запрещено. Перечислимый тип является порядковым (смотри главу Типы данных), поэтому к переменным такого типа можно применять функции Ord, Pred, Succ. Функция Ord возвращает порядковый номер значения начиная с нуля.

ПРИМЕР: Объявление перечисляемых типов.


Type Colors = (Red,Green,Blue);

Numbers = (Zero,One,Two,Three,Four,Five);

var c:Colors; n:Numbers;

begin

c:=Red; write(Ord(c)); {0}

n:=Four; write(Ord(n)); {4}

c:=Succ(c); {c=Green}

for n:=One to Five do write(Ord(n)); {12345}

end.

 

Следует отметить, что стандартные типы byte, word, char и boolean также можно считать вариантами перечислимого типа.

 

ТИП-ДИАПАЗОН

 

Тип-диапазон также называют ограниченным или интервальным типом. Он является подмножеством своего базового типа, в качестве которого может выступать любой порядковый тип кроме типа-диапазона. Тип-диапазон наследует все свойства своего базового типа. Имеются две стандартные функции, работающие с этим типом: High(x)- возвращает максимальное значение типа-диапазона, к которому принадлежит переменная x; Low(x) - возвращает минимальное значение.

ПРИМЕР: Объявление типа-диапазон.

 

type Numbers = (Zero,One,Two,Three,Four,Five);

Num = Two.. Four; {диапазон на базе типа Numbers}

Abc = 'A'.. 'z'; {все английские буквы: диапазон на базе типа Char}

Digits = 0.. 9; {цифры}

var n:Num; c,d:Abc; x:integer;

begin

n:=Four; writeln(Ord(n)); {4 как в базовом типе}

n:=Succ(n); { ОШИБКА (следующее значение вне диапазона)}

read(c,d);

if c=d then write('одинаковые буквы');

writeln(Low(c),'.. ',High(c)); { A.. z }

writeln(Low(x),'.. ',High(x)); { -32768.. 32767 }

end.

 

В тексте программы на Турбо Паскале могут встречаться директивы компилятору, которые также называют опциями. Опции {$R+} и {$R-} позволяют включать и отключать проверку соблюдения границ при работе с диапазонами. Когда проверка включена, при нарушении границ диапазонов происходит аварийное завершение работы программы. В другом случае ответственность за возможные ошибки лежит на программисте.

 

МАССИВЫ

 

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

Имя типа = ARRAY [ диапазоны индексов ] OF тип элемента массива;

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

ПРИМЕР: Три способа описания одного и того же типа массива:

 

type {1} M1 = array [0..5] of integer;

M2 = array [char] of M1;

M3 = array [-2..2] of M2;

{2} M3 = array [-2..2] of array [char] of array [0..5] of integer;

{3} M3 = array [-2..2,char,0..5] of integer;

var A:M3;

{Обращаться к элементам массива можно следующим образом:}

begin

read(A[-1,'a',3]);

read(A[1]['x'][0]);

A[1]['c',1]:=100;

end.

 

Глубина вложенности, т.е. количество индексов, при определении массивов не ограничена. Играет роль только суммарный объем данных в программе. В стандартном режиме работы Турбо Паскаля этот объем ограничен размерами сегмента, т.е. 64 килобайта. Целиком над массивами допускается применение только операции присваивания массивов (подмассивов) одинаковых типов. Остальные операции должны выполняться поэлементно.

ПРИМЕР: Вычисление значения многочлена степени N, коэффициенты которого находятся в массиве A в точке X по схеме Горнера.

 

Pn(x) = A[0]*X^n + A[1]*X^(n-1) +... + A[n-1]*X + A[n] =

= (...((A[0]*X + A[1])*X + A[2])*X +... + A[n-1])*X + A[n].

program Scheme_Gorner;

type Mas = array[0..100] of integer;

var A:Mas; i,j,n:integer; x,p:real;

begin

write('степень многочлена = '); read(n);

writeln('введите целые коэффициенты: ');

for i:=0 to n do read(A[i]);

write('значение X = '); read(x);

p:=0;

for i:=0 to n do p:=p*x+A[i];

writeln('Pn(X) = ',p);

end.

 

ЗАПИСИ

 

Запись - это стpуктуpа данных, котоpая может содеpжать инфоpмацию pазных типов, объединенную под одним названием. Компоненты записи называются полями. Их фиксиpованное число. Описание записей имеет следующую стpуктуpу:

 

Имя типа = RECORD

список полей 1: тип 1;

- -

список полей N: тип N;

CASE поле выбора: тип OF

значение 1: (полей 1: тип 1)

END;

 

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

Список полей может состоять из двух pазделов: постоянной и ваpиантной части. В постоянной части идет пеpечисление полей записи (идентификатоpов) с указанием их типов. Синтаксис такой же, как в pазделе var.

ПРИМЕР: Пример объявления типа запись.


type Men = Record

FIO,Adress: string;

Year: byte;

End;

var A,B: Men;

 

Для обpащения к полям записи указывается имя пеpеменной типа запись, точка, имя поля, напpимеp:

 

begin

A.FIO:='Иванов И.И.';

A.Adress:='пp. Ленина, д. 40, кв. 10';

A.Year:=1981;

end.

 

После описания постоянных полей может следовать ваpиантная часть, котоpая может быть только одна и имеет вид

 

CASE поле выбоpа: тип OF

значение 1: (список полей 1);

- - -

значение N: (список полей N);

 

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

Все ваpианты pасполагаются в одном и том же месте памяти, котоpой выделяется столько, сколько тpебуется для максимального по pазмеpу ваpианта. Это пpиводит к тому, что изменение одного ваpиантного поля оказывает влияние на все остальные. Это увеличивает возможности пpеобpазования типов, ПРИМЕР: Запись с вариантами.

 

var R = Record

rem: string;

Case byte of

3: (n:integer);

5: (x,y,z:char);

'a': (i,j:byte);

end;

begin

R.rem:='запись с ваpиантами';

R.n:=25000;

write(R.i,R.x,R.j,R.y); {168и97a}

{ord('и')=168, ord('a')=97, 168+97*256=25000}

end.

 

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

 

var Rec:Record

x: real;

Sr: Record a: real; x,y: integer; end;

I: byte;

end;

 

Для удобства обpащения к полям записей может использоваться опеpатоp пpисоединения WITH пеpеменная DO опеpатоp;

Здесь пеpеменная - это запись, за котоpой может следовать список вложенных полей, напpимеp следующие тpи опеpатоpа эквивалентны:

 

With Rec,Sr Do a:= x / y;

With Rec.Sr Do a:= x / y;

Rec.Sr.a:= Rec.Sr.x / Rec.Sr.y;

 

РАБОТА СО СТРОКАМИ

 

Тип String (строка) в Турбо Паскале широко используется для обработки текстов. Этот тип является стандартным и во многом похож на одномерный массив символов Array [0..N] of Char. Значение N соответствует количеству символов в строке и может меняться от 0 до 255. Символы, входящие в строку, занимают позиции с 1 до N. Начальный байт строки с индексом 0 содержит информацию о ее длине, т.е. это символ с кодом, равным длине строки.

Можно, также описывать переменные типа String[K], где K - целое число не больше 255. Так определяются строки с длиной не больше K. Этот тип уже не является стандартным. С символами строки можно работать как с элементами массива из символов, но в отличие от массивов, строки можно вводить целиком, сравнивать друг с другом и сцеплять операцией "+".

ПРИМЕР: Работа со строками.

 

var s,x,y,z:string;

begin

x:='turbo';

y:='pascal';

z:=x+' '+y; { z='turbo pascal' }

s:=''; { пустая строка }

for c:='a' to 'z' do s:=s+c; { s='abcd..xyz' }

writeln(s);

end.

 

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

ПРИМЕР: Сравнение строк.

 

'abcd' > 'abcD' { 'd'>'D' }

'abcd' > 'abc' { 'd'>'' }

'abc' < 'axxc' { 'b'<'x' }

'abcd' = 'abcd'

 

Существует ряд стандартных функций и процедур для работы со строками.

Функция Length(s) выдает длину строки s.

Функция Concat(s1,s2,..,sn) возращает строку s1+s2+..+sn.

Функция Copy(s,p,k) возвращает фрагмент строки s, который начинается в позиции p и имеет длину k.

Функция Pos(s1,s) ищет первое вхождение подстроки s1 в строку s и возвращает номер первого символа s1 в строке s или 0 если не нашли.

Процедура Delete(s,p,k) удаляет из строки s фрагмент, который начинается в позиции p и имеет длину k.

Процедура Insert(s,s1,p) вставляет в строку s подстроку s1, начиная с заданной позиции p.

Турбо паскаль позволяет производить преобразования числовых значений в строковые и наоборот. Для этого используются процедуры Str(X:n:d,S) и Val(S,X,e). Первая получает их числа X строку S с изображением этого числа, в которой не менее n символов и из них d знаков после запятой. Параметры n и d необязательные. Вторая процедура получает из строки S число X. При успешном результате e=0.

 

ПРОЦЕДУРЫИ ФУНКЦИИ

 

Турбо Паскаль позволяет выделять фрагменты программы во вспомогательные алгоритмы (ВА). Это позволяет писать хорошо структурированные программы. Языки программирования, в которых предусмотрены ВА, называются процедурно-ориентированными. Структурированные программы обычно проще в понимании и отладке.

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

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

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

 

Procedure Имя (Список формальных параметров);

label

const Описание локальных меток,

type констант, типов и переменных

var

procedure Описание внутренних процедур

function и функций

begin

Операторы

end;

 

Описание функции имеет следующую структуру.

 

Function Имя (Список формальных параметров): Тип результата;

label

const Описание локальных меток,

type констант, типов и переменных

var

procedure Описание внутренних процедур

function и функций

begin

Операторы, среди которых хотя бы один, который

присваивает имени функции значение результата

end.

 


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

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

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

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

По способу передачи параметры в Турбо Паскале делятся на три типа:

параметры-значения,

параметры-переменные,

параметры-константы.

 

Параметры-значения

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

 

Procedure MyProc1(par1,par2: type1; par3,par4: type2);

 

Параметры-переменные

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

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

 

Procedure MyProc2(var par1,par2: type1; var par3,par4: type2);

 

Параметры-константы

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

Использовать параметры-константы рекомендуется при передаче данных большого объема с гарантией сохранения их значений. Заголовок процедуры с параметрами-константами имеет вид:

Procedure MyProc3(const par1,par2: type1; const par3,par4: type2);

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-07-29 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: