Типы данных



Скачать 251.03 Kb.
Дата26.07.2014
Размер251.03 Kb.
ТипДокументы

Типы данных


Примитивные типы данных Паскаля: типы с плавающей запятой (real), целые (integer), charboolean и перечисления (конструктор нового типа, введённый в Паскале):

var { секция объявления переменных }

r: Real; { переменная вещественного типа }

i: Integer; { переменная целого типа }

c: Char; { переменная-символ }

b: Boolean; { логическая переменная }

e: (apple, pear, banana, orange, lemon); { переменная типа-перечисления }

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

Порядковые типы задаются целым числом(кодом), которое можно получить с помощью функции ord. Все операции, выполняемые над порядковыми типами, выполняются с их кодами.

Диапазоны содержат подмножество значений других порядковых типов:

var

x: 1..10;

y: 'a'..'z';

z: pear..orange;

Для порядковых типов определены операции inc,dec,succ,pred,ord, операции сравнения(=,>,<,=>,<=,<>) , их можно использовать в операторах case,for (как счётчик цикла), как границы массивов, для задания элементов множеств и типов-диапазонов.

В паскале в отличие от си-подобных языков с типами boolean, char арифметические целочисленные операции не определены.

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

var

set1: set of 1..10;

set2: set of 'a'..'z';

set3: set of pear..orange;

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

if i in [5..10] then { проверка на принадлежность элемента множеству }

...


обработается быстрее, чем

if (i>4) and (i<11) then { проверка логическими условиями }

...


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

var { секция объявления переменных }

d:set of char;



begin { начало блока }

d:=['a','b'];

...

В Паскале Йенсен и Вирта строки представлялись как упакованные массивы символов; следовательно, они имели фиксированную длину и обычно дополнялись до этой длины пробелами.


В современном [2] Паскале для работы со строками используется встроенный тип string, поддерживающий операции конкатенации(+) и сравнения (>,<,=,<>,>=,<=). Строки сравниваются в лексикографическом порядке. Например, строки считаются равными если они имеют одинаковую длину и коды всех символов с одинаковыми индексами совпадают. Тип string [n] или просто string в диалектах языка 1970-х — 1990-х гг. определялся в виде массива символов array [0..n] of char (n по умолчанию принимало значение 80 в UCSD Pascal и 255 в Turbo/Borland Pascal), код нулевого символа при таком представлении служит для задания длины строки, соответственно строка могла иметь максимальный размер 255 символов. В Delphi и Free Pascal по умолчанию в качестве String используется тип AnsiString, память под который выделяется и освобождается компилятором динамически и максимальный размер строки в текущих реализациях составляет 2 гигабайта. Кроме того, в Delphi и Free Pascal в качестве string может использоваться тип WideString, где применяется 16-битное представление символов в кодировке UCS2.

Новые типы могут быть определены из существующих:



type { секция объявления типов }

x = Integer;

y = x;

...


Более того, из примитивных типов могут быть сконструированы составные:

type { секция объявления типов }

a = Array [1..10] of Integer; { определение массива }

b = record { определение записи }

x: Integer;

y: Char;

end;

c = File of a; { определение файла }

Файловые типы в Паскале делятся на типизированные, текстовые и файлы без типов. Как показано в вышеприведённом примере, типизированныефайлы в Паскале — это последовательности однотипных элементов. Для каждого файла существует переменная-указатель на буфер, которая обозначается f^. Процедуры get (для чтения) и put (для записи) перемещают указатель к следующему элементу. Чтение реализовано так, что read(f, x)представляет собою то же, что и get(f); x:=f^;. Соответственно, запись реализована так, что write(f, x) представляет собою то же, что и f^ := x; put(f);Текстовые файлы text определены как расширение типа file of char и помимо стандартных операций над типизированными файлами(чтение,запись символа), позволяют осуществлять символьный ввод-вывод в файл всех типов данных аналогично консольному вводу-выводу.

Файлы без типов объявляются как переменные типа file. С ними можно проводить операции побайтового нетипизированного ввода-вывода по несколько блоков байт указанной длины через буфер, для этого служат специальные процедуры blockread и blockwrite.


Указатели


Паскаль поддерживает использование указателей (типизированные ^тип и нетипизированные pointer):

type

a = ^b;


b = record

x: Integer;

y: Char;

z: a;


end;

var

pointer_to_b:a;

Здесь переменная pointer_to_b — указатель на тип данных b,являющийся записью. Тип типизированного указателя может быть задан перед объявлением типа на который он ссылается. Это исключение к правилу, которое гласит, что любая вещь должная быть объявлена перед тем, как используется. Введение этого исключения позволило организовывать рекуррентные определения структур данных, в том числе такие, как линейные спискистеки и очереди, включая указатель на запись в описании этой записи (см. также нулевой указатель (nil)).

Для типизированного указателя определена операция разыменования (её синтаксис: указатель^)

Чтобы создать новую запись и присвоить значение 10 и символ A полям a и b в ней, необходимы следующие операторы:

new(pointer_to_b); { выделение памяти указателю }

pointer_to_b^.x := 10; { разыменовывание указателя и обращение к полю записи }

pointer_to_b^.y := 'A';

pointer_to_b^.z := nil;

...


dispose(pointer_to_b); { освобождение памяти из-под указателя }

Для целей обращения к полям записей и объектов можно также использовать оператор with, как показано в примере:

new(pointer_to_b);

with pointer_to_b^ do



begin

x := 10;


y := 'A';

z := nil



end;

...


dispose(pointer_to_b);

Операторы управления выполнением программы


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

while a <> b do { цикл с предусловием }

writeln('Ожидание');



if a > b then { условный оператор }

writeln('Условие выполнилось')



else { else-секция - может отсутствовать}

writeln('Условие не выполнилось');



for i := 1 to 10 do { итерационный цикл }

writeln('Итерация №', i:1);



repeat { цикл с постусловием }

a := a + 1



until a = 10;

case i of { условный оператор множественного выбора }

0: write('ноль');

1: write('один');

2: write('два')



else write('неизвестное число') { else-секция - может отсутствовать}

end;

В операторах while,for,if,case в качестве выполняемого оператора может использоваться блок. Такая конструкция, представляющая собой обычный оператор или блок, называется сложным оператором.

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

assign(inp,'text.txt');



{$I-} { отключение режима IO checking- генерации кода завершения программы в случае ошибки ввода-вывода }

{ (для случая, если файл не найден)}

reset(inp);



{$I+} { включение режима IO checking }

if IOresult=0 then begin { проверяем значение переменой ioresult(<>0 в случае ошибки ввода-вывода) }

...


close(inp);

end else writeln('file not found')

Существуют директивы, аналогичные директивам препроцессора C/C++ ($ifdef, $define, $include), они обрабатываются компилятором в процессе компиляции.


Процедуры и функции


В Паскале подпрограммы делятся на процедуры и функции:

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



program mine(output);

var i : integer;

procedure print(var j: integer);

function next(k: integer): integer;

begin

next := k + 1



end;

begin

writeln('Всего: ', j);

j := next(j)

end;

begin

i := 1;


while i <= 10 do

print(i)


end.

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

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

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


Модули


До появления модулей в их современном виде некоторые реализации Паскаля поддерживали модульность за счёт механизма включения заголовочных файлов, похожего на механизм #include в языке Си: с помощью специальной директивы, оформляемой в виде псевдокомментария, например, {$INCLUDE "файл"}, содержимое указанного файла прямо включалось в текст программы в исходном, текстовом виде. Таким образом можно было разделить программный код на множество фрагментов, для удобства редактирования, но перед компиляцией они автоматически объединялись в один файл программы, который в итоге и обрабатывался компилятором. Такая реализация модульности примитивна и имеет множество очевидных недостатков, поэтому она была быстро заменена.

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


Структура


Общая структура подключаемого модуля на Паскале выглядит следующим образом:

unit UnitName1;

interface

...


implementation

...


begin {может отсутствовать-используется, если необходимо поместить операторы инициализации}

...


end.

Возможен также ещё один вариант:



unit UnitName2;

interface

...


implementation

...


initialization

...


finalization

...


end.

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

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

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

Тело модуля начинается находящимся на верхнем уровне вложенности ключевым словом BEGIN. Тело содержит программный код, который выполняется один раз при загрузке модуля. Тело может применяться для инициализации, присваивания начальных значений переменным модуля, выделения ресурсов для его работы и так далее. Тело модуля может отсутствовать. В ряде реализаций Паскаля, например, в Delphi, вместо тела модуля могут применяться две секции (также необязательные) — INITIALIZATION и FINALIZATION. Они располагаются в конце модуля, после соответствующего ключевого слова. Первая — секция инициализации, — содержит код, который должен быть выполнен при загрузке модуля, вторая — секция финализации, — код, который будет выполнен при выгрузке модуля. Секция финализации может выполнять действия, обратные инициализации — удалять объекты из памяти, закрывать файлы, освобождать выделенные ресурсы.

Модуль заканчивается ключевым словом END с точкой.


Использование


Чтобы использовать модуль, главная программа или другой модуль должны импортировать данный модуль, то есть содержать объявление о его использовании. Это объявление делается с помощью инструкции подключения модулей, представляющей собой ключевое слово USES, за которым через запятую следуют имена модулей, которые требуется подключить. Инструкция подключения должна следовать непосредственно за заголовком программы, либо после ключевого слова INTERFACE, если подключение производится в модуле.

Модули, подключённые в интерфейсной секции, могут использоваться во всём модуле — и в секции реализации, и в теле. Но секция реализации может иметь собственную инструкцию подключения (она следует за ключевым словом IMPLEMENTATION), содержащую имена подключаемых модулей, которые отсутствуют в интерфейсной секции, но нужны для секции реализации. Одним из поводов использования отдельного списка подключения для раздела реализации является ситуация, когда два или более модуля используют друг друга. Чтобы не возникали циклические ссылки в объявлениях использования таких модулей, по крайней мере один из них должен подключать другой в секции реализации.

Любые объявленные в интерфейсных секциях модулей объекты можно использовать в программе там, где эти модули подключены. Имена импортированных из подключённых модулей объектов остаются теми же самыми, и их можно использовать непосредственно. Если два или более подключённых модуля имеют объекты, называемые одинаково, и компилятор не может их различить, то при попытке использования такого объекта будет выдана ошибка компиляции — неоднозначное задание имени. В этом случае программист должен применять квалификацию имени — указать имя в формате «<имя_модуля>.<имя_объекта>».

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


Компиляция и компоновка


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

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

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

Загрузка и выгрузка модулей


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

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

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

Объектно-ориентированное программирование


В Object Pascal классы задаются с помощью типа object, аналогичного record, который кроме полей данных может содержать заголовки процедур и функций(называются методами). Имена описываемых методов следуют за именем класса через точку. Конструктор и деструктор задаются как обычные процедуры, но вместо идентификатора procedure задаются ключевые слова constructor и destructor. Соответственно, в отличие от С++-подобных языков они имеют имя, отличное от имени класса, деструкторов может быть несколько и они могут иметь параметры (на практике эта возможность используется редко, обычно класс имеет единственный деструктор Destroy, переопределяющий виртуальный деструктор класса-родителя). Все объекты в Object Pascal(fpc, tp) создаются и уничтожаются динамически, конструктор и деструктор всегда должны вызываться явно.

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

В Delphi, FPC реализована перегрузка операций, абстрактные методы, директивы privateprotectedpublicpublished (по умолчанию члены класса являются public):

type

TbasicO=object



procedure writeByte(b:byte); virtual; abstract;

end;

TtextO=object(TbasicO) {наследует TbasicO, реализует остальные операции вывода на основе writeByte}



procedure writeS(s:string);

{..}

end;

TfileO=object(TbasicO) {класс файлового вывода - реализует операцию вывода как вывод байта в файл}



constructor init(n:string);

procedure writeByte(b:byte); virtual;

destructor closefile;

private

f:file of byte;



end;

basicO=^TbasicO; textO=^TtextO; fileO=^TfileO;



constructor TfileO.init(n:string);

begin

assign(f,n);rewrite(f)



end;

destructor TfileO.closefile;

begin

close(f)


end;

procedure TfileO.writeByte(b:byte);

begin

write(f,b)



end;

procedure TtextO.writeS(s:string);

var i:integer;

begin

for i:=1 to length(s) do writeByte(ord(s[i]))

end;

{..}

var f:fileO;

begin

new(f,init('tstobj.txt'));{выделяет пямять под объект и вызывает конструктор}

textO(f)^.writeS('text string');

dispose(f,closefile) {вызывает деструктор и освобождает память объекта}



end.

В диалекте Delphi классы могут также конструироваться с помощью слова class(причем взаимное наследование с object-классами не допускается), и введены интерфейсы(interface)-все методы абстрактные и не могут содержать полей данных. Все классы(созданные с помощью class) являются наследниками TObject, все интерфейсы происходят от IUnknown. Классы(созданные с помощью class) могут реализовывать несколько интерфейсов. В Delphi интерфейсы были введены для поддержки COM технологии фирмы Microsoft.


Классы(Class) в отличии от обычных классов(Object) не нуждаются в явном выделении/освобождении памяти, память под них динамически выделяется конструктором с именем Create, вызываемым с именем класса, и освобождается при вызове деструктора с именем Destroy(могут иметь другие имена). Переменная такого класса в отличии от класса object хранит адрес экземпляра класса в памяти, значение nil используется для указания пустой ссылки, поэтому для освобождения объекта в TObject определен специальный метод free, проверяющий ссылку на nil и вызывающий виртуальный деструктор Destroy. Код с использованием таких классов будет выглядеть следующим образом:

q1:=t1.create(9); { конструируем объект(t1 - имя класса) }

writeln(q1.InstanceSize); { вывод размера экземпляра класса }

q1.Free; { уничтожение объекта }



q1:=nil; { чтобы не происходило повторного вызова деструктора при вызове free }





Похожие:

Типы данных icon«простые типы данных. Символьный тип данных» Простые типы данных делятся на порядковые и ве­щественный типы данных
Под порядковым типом понимают тип данных, областью значений которых является упорядоченное счетное множество. Каждому элементу такого...
Типы данных iconТипы данных на Паскаль. Целочисленные типы данных
В типах данных со знаком старший бит числа используется как признак знака числа. Все целые типы относятся к порядковым, т е для любого...
Типы данных iconВ широком смысле
Табличные базы данных (БД): основные понятия (поле, запись, первичный ключ записи); типы данных. Системы управления базами данных...
Типы данных icon3. 29 Типы баз данных. Реляционные бд. Нормальные формы рбд. Язык sql база Данных
База Данных (БД) — структурированный организованный набор данных, описывающих характеристики какой-либо физической или виртуальной...
Типы данных iconТипы баз данных. Реляционные бд. Нормальные формы рбд. Язык sql
База Данных (БД) — структурированный организованный набор данных, описывающих характеристики какой-либо физической или виртуальной...
Типы данных icon52. Стандартные типы данных
...
Типы данных iconТемы, рекомендуемые для работы с одаренными учащимися в плане подготовки к олимпиаде по информатике (программированию) Раздел Математические основы программирования Раздел Техника программирования
Переменные и простейшие типы данных, размеры типов. Линейные программы. Условные операторы. Циклы. Процедуры и функции. Сложные типы...
Типы данных icon2. Модели и типы данных
Хранимые в базе данные имеют определенную логическую структуру — иными сло­вами, описываются некоторой моделью представления данных...
Типы данных iconТипы моделей данных
Иерархическая и сетевая модели данных стали применяться в системах управления базами данных в начале 60-х годов. В начале 70-х годов...
Типы данных iconТипы данных
Цель урока: сформировать у учащихся целостного представления о типах данных языка Паскаль
Разместите кнопку на своём сайте:
ru.convdocs.org


База данных защищена авторским правом ©ru.convdocs.org 2016
обратиться к администрации
ru.convdocs.org