Общая характеристика языка
Основные синтаксические правила записи программ на языке Object Pascal. Использование блоков при определении области видимости константы, переменной или функции. Примеры константных выражений и инициализации переменных. Классификация типов данных.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | контрольная работа |
Язык | русский |
Дата добавления | 06.11.2011 |
Размер файла | 125,4 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Общая характеристика языка
Синтаксис языка
Основные синтаксические правила записи программ на языке Object Pascal сводятся к следующему:
· Все используемые типы, константы, переменные, функции, процедуры должны быть объявлены или описаны до их первого использования
· Прописные и строчные буквы идентичны.
· При записи идентификаторов могут использоваться латинские буквы, цифры, символ подчеркивания "_". Идентификатор не может начинаться с цифры и не может содержать пробелов. Длина идентификатора не ограничена, но воспринимается не более 255 первых символов идентификатора.
· При ссылках на идентичные идентификаторы, описанные в разных местах, например, в разных модулях или в разных объектах, используется нотация с точкой, в которой сначала перечисляются идентификаторы объектов, разделенные символами точки. Например, Unit2.A, или, Form2.Label1.Caption.
· Каждое предложение языка кончается символом точка с запятой (;). Точку с запятой можно не ставить перед ключевым словом end.
· В строке может размещаться несколько операторов. Надо выделять объединенные смыслом операторы в группы, широко используя для этого отступы и комментарии.
· Комментарии в тексте заключаются в фигурные скобки: {текст комментария}. Вместо фигурных скобок можно использовать символы круглых скобок с символами звездочки "*": (* текст комментария *). Комментарии, заключенные в фигурные скобки или в круглые скобки со звездочками, могут вводится в любом месте текста, в частности, внутри операторов, и занимать любое количество строк. Текст комментария в фигурных скобках не может начинаться с символа доллара, поскольку сочетание символов {$ воспринимается как начало директивы компилятора. Еще один способ введения комментария - размещение его после двух символов "слеш" ("//"). Этот комментарий должен занимать конец строки, в котором он введен, и не может переходить на следующую строку. Любой текст в строке, помещенный после символов "//" воспринимается как комментарий.
· Операторные скобки begin…end выделяют составной оператор. Все операторы, помещенные между ключевыми словами begin и end воспринимаются синтаксически как один оператор.
· Программа или отдельный модуль завершаются оператором "end." (ключевое слово end с символом точки).
Области видимости
Такие элементы программы, как константы, переменные, функции и процедуры, могут использоваться только в области их видимости, которая зависит от того места, в котором определен элемент. При определении области видимости используется понятие блок. Блок состоит из разделов объявлений и следующего за ними составного оператора:
объявления
begin
операторы
end;
Область видимости константы, переменной, функции и других элементов, объявленных в головном файле программы, в функции или процедуре, ограничивается тем блоком, в котором элемент объявлен. Такие элементы называются локальными.
Элементы, объявленные в разделе interface модуля, видимы во всех модулях, которые используют данный модуль. Такие элементы называются глобальными.
Таблица, определяющая область видимости элемента:
Если элемент объявлен… |
Его область видимости простирается… |
|
в головном файле программы, в функции или процедуре |
от точки объявления до конца текущего блока, включая все вложенные в него блоки |
|
в разделе interface модуля |
от точки объявления до конца данного модуля, а также во всех модулях, которые с помощью предложения uses используют данный модуль |
|
в разделе implementation модуля, но не в блоке какой-то функции или процедуры |
от точки объявления до конца раздела implementation, включая все расположенные в этом разделе функции и процедуры |
|
в определении записи, т.е. является именем поля записи |
от точки объявления до конца определений типов полей |
|
в определении класса, т.е. является свойством или методом |
от точки объявления до конца определения класса, а также в классах - наследниках и в блоках всех методов данного класса и его наследников |
Константы и константные выражения
Константы и константные выражения могут использоваться непосредственно в тексте программы в любых операторах и выражениях. Константы (именованные константы) могут объявляться с помощью ключевого слова const. Это слово начинает раздел объявления констант. После него может следовать ряд объявлений констант в форме:
<идентификатор константы> = <константное выражение>;
Имеются также определенные константы: true - истина, false - ложь, nil - нулевой указатель.
Константное выражение в общем случае может использовать константы, ранее объявленные именованные константы, арифметические операции, значения перечислимых типов, конструкторы множеств, а так же следующие встроенные функции:
Abs Addr ArcTan Chr Cos Exp |
Frac Hi High Int Length Ln |
Lo Low Odd Ord Pi Pred |
Round Sin SizeOf Sqr Sqrt Succ |
Swap Trunc |
Примеры константных выражений:
100
'A'
Sin(35*180/Pi)
'Мой файл'+' '+'Mf.txt'
Chr(32)
Ord('Z')-Ord('A')+1
Примеры объявления именованных констант:
Const NMax=55;
Pi2=2*Pi; {удвоенное число Пи}
Kd=Pi/180; {коэффециент пересчета градусов в радианы}
Name='Алексей';
Константы, являющиеся целыми числами, обычно записываются в десятичной форме Например, 7, 22,-5. Могут использоваться также константы в шестнадцатеричной форме. В этом случае константа начинается с символа "$", после которого записывается до 8 шестнадцатеричных цифр. Диапазон значений шестнадцатеричных констант от $00000000 до $FFFFFFFF.
Константы, являющиеся действительными числами, могут записываться в десятичном виде с точкой, отделяющей целую часть от дробной, или с указанием порядка, после символа "е". Например, 6.2 (6,2), 7е5 (7*105), -3.1е-4 (-3,1*10-4).
Значения строковых констант заключается в одинарные кавычки и могут содержать последовательность любых символов. Если в текст строки надо включить символ одинарной кавычки, то он повторяется дважды. Например
Const MyFile='Имя моего файла ''Mf.txt'' ' {Имя моего файла 'Mf.txt'}
Еще один вид констант - строки ресурсов. Они включаются в проект с помощью ключевого слова resourcestring вместо const. Например:
resourcestring
LineTooLong='Строка слишком длинная';
Переменные
Переменная является идентификатором, обозначающим некоторую область в памяти, в которой хранится значение переменной. Это значение может изменяться во время выполнения приложения.
Объявление переменной имеет вид:
var <список идентификаторов переменных> : <тип>;
Примеры объявления переменных:
var I: integer;
X, Y, Z: Double;
Digit: 0..9;
Okay: Boolean;
Переменные можно разделить на локальные и глобальные. Переменные, объявляемые в процедурах и функциях, являются локальными. Они существуют только во время выполнения соответствующей процедуры или функции. Т.е. память для них выделяется только при вызове соответствующей процедуры или функции и освобождается при возврате в вызвавшую процедуру. Переменные, объявленные вне процедур или функций, являются глобальными.
Глобальные переменные можно инициализировать в их объявлениях, т.е. задавать им начальные значения:
<идентификатор переменной>:<тип>=<константное выражение>;
Пример инициализации переменных:
var I:integer=7;
Deg:double=35*180/Pi;
При низкоуровневом программировании можно в объявлении переменной указывать с помощью ключевого слова absolute абсолютный адрес переменной. Например:
Var CrtMode: Byte absolute $0040
Можно создавать динамические переменные, выделяя для них место в динамически распределяемой области памяти heap (куча) процедурами GetMem и New и освобождая память соответственно процедурами FreeMem и Dispose. Можно так же использовать для динамических переменных функции ReallocMem, Initialize, StrAlloc и StrDispose.
В приложениях с несколькими параллельно выполняемыми потеплений могут быть определены переменные, локализуемые в потоках (thread-local или thread). Они подобны глобальным переменным, но каждый поток или нить (thread) получает свою копию такой переменной, не доступную другим нитям. Объявление переменной, локализуемой в потоке, осуществляется с помощью ключевого слова threadvar. Например:
threadvar X: Integer;
Можно создавать динамические переменные, выделяя для них место в динамически распределяемой области памяти heap (куча) процедурами GetMem и New и освобождая память соответственно процедурами FreeMem и Dispose. Можно так же использовать для динамических переменных функции ReallocMem, Initialize, StrAlloc и StrDispose.
В приложениях с несколькими параллельно выполняемыми потеплений могут быть определены переменные, локализуемые в потоках (thread-local или thread). Они подобны глобальным переменным, но каждый поток или нить (thread) получает свою копию такой переменной, не доступную другим нитям. Объявление переменной, локализуемой в потоке, осуществляется с помощью ключевого слова threadvar. Например:
threadvar X: Integer;
Подобные переменные не могут объявляться в процедурах и функциях, не могут инициализироваться, не могут задаваться динамическими или с абсолютным адресом.
Типизированные константы
Типизированные константы объявляются в разделе констант const. В действительности являются не константами, а переменными, инициализируемыми при их объявлении, т.е. получающими начальное значение. Типизированные константы могут использоваться для задания начальных значений локальным переменным, а при желании - и глобальным переменным.
Типизированная константа объявляется выражением:
Const <идентификатор>:<тип>=<константное выражение>;
Например:
Const In: integer=7;Angl:double=35*Pi/180
В дальнейшем тексте программы с типизированными константами можно обращаться как с обычными переменными, изменяя, когда требуется, их значения.
Типы данных
Классификация типов данных, объявление типов
Типы данных можно разделить на предопределенные в языке (встроенные) типы и типы, определяемые пользователем. К предопределенным относятся типы целые, действительные, символы, строки, указатели, булевы, variant.
Определяемые пользователем типы могут быть использованы или непосредственно в объявлении переменной, или должны быть объявлены с помощью ключевого слова type. Это слово начинает раздел объявления типов. После него может следовать ряд объявлений типов в форме:
синтаксический программа язык константа
<идентификатор типа>=<описание типа>;
Пример. Объявление
var Mode : (mRead,mEdit,mWrite);
объявляет переменную Mode, задавая для нее вводимый пользователем перечислимый тип. А объявления
type TMode : (mRead, mEdit,mWrite);
var Mode1,Mode2 : TMode;
задают имя нового типа - TMode и определяют две переменные введенного пользователем типа - Mode1 и Mode2.
Объявление типа можно использовать и для создания псевдонима встроенного типа. Например, объявление
Type TMyString = string;
Создает тип TMyString, являющийся псевдонимом встроенного типа строк string.
Приведение типов
В выражениях и в операторах присваивания могут фигурировать переменные и константы разных типов. В этом случае осуществляется приведение типов, что означает преобразование одного типа в другой. Приведение типов может быть неявным и явным. Неявное приведение совместимых типов автоматически осуществляет компилятор. При этом всегда более младший тип, занимающий меньший объем памяти, приводится к типу, занимающему больший объем. Например, если I -- целая переменная, а А -- действительная, то допустимы операторы
A:=I;
A:A+I;
Но недопустим оператор
I:A+I;
который требует приведения действительного значения к целому.
Явное приведение типов осуществляется программистом с помощью следующей конструкции:
<идентификатор типа>(<выражение>)
Если выражение представляет собой просто переменную, то говорят о приведении типа переменной. В противном случае говорят о приведении типа значения.
Явное приведение типа переменной можно проводить для любых типов, имеющих одинаковый размер. При этом не допускается взаимное преобразование целых и действительных чисел. Для преобразования действительных чисел в целые надо использовать функции Int и Trunc . А целые переменные преобразуются в действительные неявно.
Явное приведение типа переменной может использоваться и в правой, и в левой частях оператора присваивания. Например, могут быть записаны такие операторы (предполагается, что переменная Ch имеет тип Char, а I -- Integer):
Ch :=Char(I)
Shortint(Ch) :=I;
Эти два оператора дают один и тот же результат. Например, если I = 122 (код символа "z"), то значение переменной Ch в результате выполнения любого из этих операторов станет равно символу "z".
Явное приведение типа значения некоторого выражения осуществляется после его вычисления. Например, в операторе
Ch :=Char(I-1);
cначала вычисляется выражение в скобках, а потом производится приведение результата к типу Char.
Порядковые типы данных
Порядковыми (ordinal) типами называются те, в которых значения упорядочены и для каждого из них можно указать предшествующее и последующее значения. Для порядковых типов предопределен ряд функций:
Функция |
Параметр |
Возвращаемое значение |
Замечания |
|
Ord |
Выражение порядкового типа |
Порядковый номер значения данного выражения |
Не воспринимает аргумент типа Int64 |
|
Pred |
Выражение порядкового типа |
Величина, предшествующая значению данного выражения |
Нельзя использовать в свойствах, имеющих процедуру Write |
|
Succ |
Выражение порядкового типа |
Величина, следующая для значения данного выражения |
Нельзя использовать в свойствах, имеющих процедуру Write |
|
High |
Идентификатор порядкового типа или переменная порядкового типа |
Максимально возможное значение |
Используется также для типов коротких строк и массивов '' |
|
Low |
Идентификатор порядкового типа или переменная порядкового типа |
Минимально возможное значение |
Используется также для типов коротких строк и массивов |
Для порядковых типов определены также процедуры инкремента Inc и декремента Dec. Эти процедуры соответственно увеличивают или уменьшают на единицу порядковый номер своего аргумента. Таким образом, оператор
Inc(I)
эквивалентен оператору
I :=Succ(I);
а оператор
Dec(I);
эквивалентен оператору
I :=Pred(I);
Если I -- целая переменная, то приведенные операторы эквивалентны соответственно
I :=I+1;
и
I :=I-1;
Целые типы данных
Целые типы данных используются для представления целых чисел. Они относятся к целым порядковым типам.
Тип |
Диапазон значений |
Требования к памяти в байтах |
Знаковый (может ли хранить отрицательные числа) |
|
Byte |
0255 |
1 |
нет |
|
Word |
065535 |
2 |
нет |
|
Longword |
04294967295 |
4 |
нет |
|
ShortInt |
-128127 |
1 |
да |
|
SmallInt |
-3276832767 |
2 |
да |
|
Cardinal |
04294967295 |
4 |
нет |
|
Integer |
-2147483648 2147483647 |
4 |
да |
|
LongInt |
-2147483648 2147483647 |
4 |
да |
|
Int64 |
-263 263 -1 |
8 |
да |
Арифметические операции над целыми числами возвращают тип Integer. Только если оба операнда имеют тип Int64, результат тоже имеет тип Int64.
Большинство стандартных процедур и функций, работающих с целыми аргументами, усекают аргументы типа Int64 до 4 байтов. Исключение составляют функции High, Low, Succ, Pred, Inc, Dec, IntToHex, полностью поддерживающие аргументы типа Int64. Функции Round, Trunc, StrToInt64, StrToInt64Def также возвращают результат типа Int64. Функция Ord к Int64 применяться не может.
Действительные типы данных
Действительные типы данных предназначены для хранения чисел, имеющих дробную часть.
Тип |
Диапазон значений |
Число значащих разрядов |
Требования к памяти в байтах |
|
Real48 |
11-12 |
6 |
||
Real |
15-16 |
8 |
||
Single |
7-8 |
4 |
||
Double |
15-16 |
8 |
||
Extended |
19-20 |
10 |
||
Comp |
19-20 |
8 |
||
Currency |
19-20 |
8 |
Родовым (т.е. обеспечивающим максимальную производительность) является тип Real.
Наименьшую производительность обеспечивает тип Real48, сохраняемый только для обратной совместимости с более ранними версиями языка.
Тип Extended обладает максимальной точностью, но могут возникать проблемы с его переносимостью на другие платформы.
Тип Comp является, строго говоря, большим целым, а не действительным числом, но отличается от целого, например, тем, что к нему нельзя применять функции инкремента и декремента. Этот тип оставлен только для обратной совместимости с более ранними версиями языка, поскольку его возможности перекрываются целым типом 1п164.
Тип Currency используется для представления денежных величин. В памяти он хранится как масштабированное в 10000 раз 8-байтовое целое. Благодаря этому при операциях с величинами типа Currency минимизируются ошибки округления, что очень важно для денежных расчетов.
Булевы типы данных
Переменные булевых типов данных представляют логические значения, например, true (истина) и false (ложь). Булевы типы относятся к целым порядковым типам.
Тип |
Значения |
Требования к памяти в байтах |
|
Boolean |
Булева величина в один байт |
1 |
|
ByteBool |
Булева величина в один байт |
1 |
|
WordBool |
Булева величина в одно слово |
2 |
|
LongBool |
Булевская величина в два слова |
4 |
Предопределенные в языке константы true и false обладают в разных булевых типах несколько разными свойствами, которые просуммированы в приведенной ниже таблице.
Тип Boolean |
Типы ByteBool, WordBool, LongBool |
|
false < true |
false<>true |
|
Ord(false)=0 |
Ord(false)=0 |
|
Ord(true)=1 |
Ord(true)<>0 |
|
Succ(false)=true |
Succ(false)=true |
|
Pred(true)=false |
Pred(true)=true |
Для булевых типов определены операции and (И), or (ИЛИ), not (НЕ, отрицание) и xor (исключающее ИЛИ). Использование этих операций расширяет возможности по формированию сложных условий в ряде операторов.
Символьные типы данных
Символьные типы предназначены для хранения одного символа. Они относятся к целым порядковым типам.
Тип |
Размер в байтах |
Что может хранить |
|
ANSIChar |
1 |
Один символ ANSI |
|
ANSIChar |
2 |
Один символ Unicode |
|
Char |
1 |
Эквивалентен ANSIChar |
Родовым (т.е. обеспечивающим максимальную производительность) является тип Char. Именно тип Char имеет смысл использовать во всех случаях, кроме обращений к функциям, требующим другой тип символьных данных.
Для символьного типа предопределена функция Chr, возвращающая символ любого целого значения в пределах ANSIChar или ANSIChar.
Типы строк
Строки представляют собой последовательность символов.
Тип строки |
Максимальная длина |
Используется для |
Нулевой символ в конце |
|
ShortString |
255 |
обратной совместимости |
нет |
|
AnsiString |
~231 (~2 Гб) |
символов ANSI |
Есть |
|
String |
или 255, или до ~2 Гб |
символов ANSI или Unicode |
Есть или нет |
|
WideString |
~230 (~1 Гб) |
символов Unicode, в серверах COM и интерфейсах |
есть |
Родовым является тип String, который имеет разный смысл в зависимости от директивы компилятора $Н. Если включена директива {$Н+} (она включена по умолчанию), то String интерпретируется компилятором как тип AnsiString -- длинная строка с нулевым символом в конце. Если же включить директиву {$Н-}, то String интерпретируется компилятором как тип ShortString -- короткая строка без нулевого символа в конце. Если в объявлении типа после ключевого слова String следует число символов в квадратных скобках (например, String [4]), то, независимо от директив компилятора, тип трактуется как строка без нулевого символа в конце с указанным числом символов.
Стандартная функция Length возвращает число символов в строке, переданной ей в качестве параметра. Процедура SetLength устанавливает длину строки.
Для строк определены операции сравнения >, <, = и т.п. Если сравниваются строки разной длины, то большей считается более длинная строка. Если сравниваются строки одинаковой длины, то принимаются в расчет символы в одинаковых позициях -- сравниваются коды этих символов.
Со строками можно оперировать как с индексированными массивами символов. Например, S[i] -- это символ, расположенный в строке в позиции i (индексы отсчитываются от 1, т.е. индекс 1 соответствует первому символу). Для строк типа ShortString или AnsiSting выражение S[i] имеет тип AnsiChar, для строк типа WideString - WideChar.
Сцепление (конкатенация) строк осуществляется операцией "+". Например, выражение S1+S2 даст в результате строку, в которой после символов строки S1 будут расположены символы строки S2.
Строки разных типов могут присваиваться друг другу и смешиваться в одном выражении. Компилятор при этом осуществляет автоматическое приведение типов. Но строки, передаваемые как параметры в функции и процедуры, должны иметь тип, указанный в объявлениях этих функций и процедур. В этих случаях при необходимости надо использовать операцию явного приведения типов или другие приемы программирования.
Типы строк можно классифицировать по двум признакам: длинные или короткие строки и строки, использующие или не использующие нулевой символ в конце.
Рассмотрим сначала различие между короткими (ShortString) и длинными (AnsiString) строками. Они различаются прежде всего организацией хранения в памяти. Строки типа ShortString хранят в своем нулевом байте число символов в строке, а в последующих байтах -- сами символы (не более 255). Поэтому, если S -- строка типа ShortString, то Ord(S[0]) возвращает длину строки, т.е. то же значение, которое возвращает функция Length(S). Соответственно присваивание значения S[0] эквивалентно вызову функции SetLength, устанавливающему длину строки.
Размещение в памяти длинных строк отличается от рассмотренного выше для коротких строк. Переменная типа AnsiString является указателем на динамически выделяемую область памяти, в которой хранится строка. Поэтому может быть несколько переменных, ссылающихся на одну и ту же строку. В этом случае в памяти хранится только один экземпляр строки, что позволяет экономить ресурсы. Если длина строки равна 0, то этот указатель равен nil и память под строку не выделяется. Если же строка не пустая, то в выделенной для нее области памяти хранится сама строка, ее длина и число ссылок на данную строку (число переменных, ссылающихся на данную строку). Если переменной типа AnsiString присваивается новое значение, то число ссылок в прежней строке уменьшается на 1, а в новой -- увеличивается на 1. Если число ссылок на строку становится равным 0, то строка уничтожается, освобождая место в памяти. Если с помощью индексного обращения в строке изменяется один символ, то строка копируется только в том случае, если число ссылок на нее больше 1. Все это позволяет эффективно использовать память.
Теперь остановимся на использовании в строках нулевого конечного символа. В настоящее время тип ShortString поддерживается только для обеспечения обратной совместимости с более ранними версиями языка. А основным типом строк становятся строки с нулевым символом в конце. Строки с нулевым символом в конце представляют собой массивы символов с индексами, начинающимися с 0. В массиве хранятся символы строки и в конце нулевой символ (#0), указывающий на окончание строки. Таким образом, тип строки с нулевым символом в конце может, например, объявляться как AnsiString, а может объявляться как статический массив символов, например:
Type
TS = array[0..15] of Char;
Если значение переменной строки с нулевым символом в конце инициализируется при ее объявлении, то после значащих символов остальные элементы массива надо инициализировать символами #0. Например:
Const SHello: array[0..7] of Char = `Привет!'#0;
Этого не надо делать в операторах присваивания. Например:
SHello := `Привет!';
Отметим, что ту же самую типизированную константу SHello можно было бы с тем же успехом объявить следующим образом:
const SHello: AnsiString = `Привет!';
При работе со строками с нулевым символом в конце часто используют специальные типы указателей: PChar и PWideChar, которые являются указателями соответственно на массивы с элементами типов Char и WideChar с нулевым символом в конце. Переменные этих типов часто требуется передавать в различные функции и процедуры в качестве параметров. К тому же, типы PChar и PWideChar существенно упрощают коды. Дело в том, что эти типы совместимы со строковыми константами. Например, объявление и использование переменной типа PChar может иметь вид:
Var P: PChar;
…
P:='Привет!';
Это эквивалентно операторам
Const SHello: array[0..7] of char = `Привет!'#0;
Var P: PChar;
…
P :=@SHello;
но, конечно, гораздо короче.
Совместимость указателей типов PChar и PWideChar со строковыми константами позволяет в вызовах функций и процедур с параметрами соответствующих типов использовать просто строки символов. Например, если некоторая процедура F требует параметр типа PChar, то обратиться к ней можно так:
Var P: PChar;
…
P:='Привет!';
F(P);
Или
F(`Привет!');
Указатели типов PChar и PWideChar могут индексироваться точно так же, как строки и массивы символов. Например, Р[0] -- это первый символ строки, на которую указывает Р.
В выражениях, операторах присваивания и при передаче параметров в функции и процедуры можно смешивать длинные строки (AnsiString) и строки с нулевым символом в конце типа PChar. Но иногда требуется явное приведение типа PChar к типу длинной строки. Например, операция склеивания (конкатенации) строк требует, чтобы хотя бы один ее операнд был типа строки. Если же требуется склеить два объекта типа PChar, то это надо делать с помощью приведения типа:
S := string(P1)+string(P2);
В ряде случаев требуется обратное преобразование типов строк: длинной строки типа AnsiString в строку с нулевым символом в конце типа PChar. Это приходится делать при передаче параметров в функции, требующие тип PChar. В этих случаях надо явным образом приводить тип строки к PChar. Например:
Var s: string;
…
S:=StrLower(PChar(Edit1.Text));
Свойство Text окна редактирования Edit имеет тип string, а функция StrLower преобразования текста к нижнему регистру требует параметр типа PChar. Поэтому в вызове функции необходимо явное приведение типа. В то же время преобразование возвращаемого функцией StrLower значения типа Pchar к типу string переменной s производится автоматически.
Перечислимые типы
Перечислимые типы определяют упорядоченное множество идентификаторов, представляющих собой возможные значения переменных этого типа. Вводятся эти типы для того, чтобы сделать код более понятным. В частности, многие типы Delphi являются перечислимыми, что упрощает работу с ними, поскольку дает возможность работать не с абстрактными числами, а с осмысленными значениями. Пример: Пусть в программе должна быть переменная Mode, в которой зафиксирован один из возможных режимов работы приложения: чтение данных, их редактирование, запись данных.
Переменная перечисленного типа может определяться предложением вида:
var <имя переменной> : (<значение 1>, …, <значение n>);
Например
Var Mode : (mRead, mEdit, mWrite);
Если переменная определена так, то ей можно присваивать указанные значения, можно проверять ее величину, сравнивая с возможными значениями. Кроме того, надо учитывать, что перечислимые типы относятся к целым порядковым типам и к ним применимы любые операции сравнения (>, < и т.п.), а также процедуры и функции, определенные для порядковых типов.
Если возможные значения типа определены, как указано выше, в переменной при ее объявлении, то нельзя будет ввести другую переменную с теми же значениями. Если такая потребность имеется, то перечислимый тип надо определять именно как тип:
type <имя типа>=(<значение 1>, …, <значение n>);
Тогда можно ввести в программе несколько переменных этого типа. Например:
Type TMode =: (mRead, mEdit, mWrite);
Var Mode1, Mode2 : TMode;
Ограниченные типы
Для порядковых типов можно задать поддиапазон их возможных значений для вводимого вами типа или переменной -- это и будет ограниченный тип. Задается диапазон значений ограниченного типа выражением вида
<минимальное значение>..<максимальное значение>
Например:
Var Letter: 'a'..'z';
Num : 1..12;
Type Caps = 'A'..'z';
В этих примерах переменная Letter может принимать только символы латинских букв в нижнем регистре, переменная Num -- только целые числа в диапазоне 112 (это могут быть, например, номера месяцев), переменные, чей тип будет объявлен как Caps будут принимать только символы латинских букв в верхнем регистре.
При использовании в объявлении ограниченного типа константных выражений (см. раздел 12.5.1) возможны некоторые ошибки компилятора. Например, объявления
const X=100;
Y=200;
type Scale = (X+Y) div 2..Y;
вызовут сообщение компилятора об ошибке, поскольку, если после знака равенства в объявлении типа следует скобка, то компилятор считает, что описывается перечислимый тип. Чтобы избежать такой ошибки, приведенные выше объявления можно заменить следующими:
const X=100;
Y=200;
type Scale = 1*(X+Y) div 2..Y;
Множества
Множество -- это группа элементов, которая ассоциируется с ее именем и с которой можно сравнивать другие величины, чтобы определить, принадлежат ли они этому множеству. Один и тот же элемент не может входить в множество более одного раза. Как частный случай, множество может быть пустым. Множество определяется перечислением его элементов, заключенным в прямоугольные скобки. Такая форма определения называется конструктором множества. Например, если множество возможных единичных символов, которые могут быть получены в ответ на вопрос программы "Yes/No", содержит символы "y", "Y", "n" и "N", то это множество можно описать таким конструктором: ['y', 'Y, 'n', 'N']. Для определения, принадлежит ли переменная множеству, служит операция in. В предыдущем примере проверить, дал ли пользователь один из допустимых ответов, можно оператором:
If (Key in ['y', 'Y, 'n', 'N'])
Then <оператор, выполняемый при допустимом ответе>
Множества могут содержать не только отдельные значения, но и ограниченные типы. Например, если вы хотите контролировать символы, вводимые пользователем при вводе целого положительного или отрицательного числа, вы можете определить множество ['0'..'9','+','-'] и использовать его, например, при обработке события OnKeyPress какого-то окна редактирования:
In not (Key in ['0'..'9','+','-']) then Key:=#0;
Подобный оператор не позволяет пользователю ввести какие-то символы, отличные от имеющихся в множестве. В приведенных операторах множество заранее не объявлялось в виде типа. Но если, например, в приложении в ряде мест надо проводить проверки, аналогичные приведенным выше, то целесообразнее объявить переменную или типизированную константу типа множества или тип множества и несколько переменных этого типа. Объявление типа множества делается в форме
set of <базовый тип>
Приведем примеры.
Объявление глобальной переменной с инициализацией:
Var K: set of Char=['0'..'9','+','-'];
...
If (Key in K) then ...
Объявление типизированной константы:
const K: set of Char=['0'..'9','+','-'];
Объявление типа множества и переменных этого типа:
Type TDigit=set of '0'..'9';
Var D1,D2: TDigit;
D1:=['0','1'];
D2:=['2'..'9'];
Помимо операции in для множеств определен еще ряд операций: объединение, пересечение, операции отношения и ряд других.
Тип Variant
В переменных типа variant могут хранился данные любых типов, кроме записей, множеств, статических массивов, файлов, классов, ссылок на классы, указателей и Int64. Иначе говоря, переменные типа Variant могут хранить все, кроме структур, указателей и Int64. Они могут также хранить объекты СОМ и СОRВА, обеспечивая доступ к их методам и свойствам. Могут они также хранить динамические массивы и специальные массивы variant.
Например, если определить тип переменной V как variant, то могут выполняться такие операторы:
V: variant; // bPV V не определен (xB>DR Unassigned)
…
V:=5; // тип V становится равным integer
…
V:=le10; // тип V становится равным real
…
V:=Edit1.Text; // тип V становится равным string
Тип variant имеет смысл использовать в тех случаях, когда тип того или иного объекта заранее не известен или когда какие-то функции и процедуры требуют именно такой тип аргументов. При этом надо иметь в виду, что затраты памяти и времени на работу с переменными типа variant больше, чем при работе с обычными типами. К тому же недопустимые операции с переменными типа variant приводят к ошибкам времени выполнения, тогда как аналогичные недопустимые операции с переменными других типов выявляются на этапе компиляции.
Переменные типа variant занимают 16 битов и содержат код типа и значение переменной или указатель на это значение. В момент создания эти переменные инициализируются специальным значением Unassigned. Значение переменной null свидетельствует о неизвестном или ошибочном значении переменной.
Переменные типа variant могут использоваться в выражениях как операнды любых операций, кроме ^, is и in, совместно с другими величинами типов variant, integer, real, string, Boolean. Компилятор в этих случаях автоматически осуществляет приведение типов величин в выражении. Если оба операнда операции имеют тип variant и один или оба операнда равны null, то результат операции тоже равен null. Если один или оба операнда имеют значение Unassigned, то генерируется исключение. Если в бинарной операции только один из операндов имеет тип variant, то другой тоже преобразуется в тип variant.
Приведение типов при вычислении выражений, содержащих операнды variant, осуществляется обычным образом. Например, если V1 и V2 типа variant содержат данные типов integer и real, то выражение V1+V2 вернет значение real. Узнать действительный тип значение переменной variant можно с помощью функции VarType, возвращающей значение типа TVarData, содержащее код типа. Запись TVarData определена в модуле System. Имеется также предопределенная константа varTypeMask, сложение которой по операции end с переменной типа TVarData возвращает истинный тип переменной. Например, выражение
VarType(V) and varTypeMask = varDouble;
вернет true, если в переменной V в данный момент хранится значение типа double или массив значений типа double. Возможные значения типов, возвращаемые функцией VarType, следующие:
varEmpty |
Переменная в состоянии Unassigned |
|
varNull |
Значение переменной равно null |
|
VarSmallint |
Тип Smallint |
|
varInteger |
Тип Integer |
|
varSingle |
Тип Single |
|
varDouble |
Тип Double |
|
varCurrency |
Тип Currency |
|
varDate |
Тип Date (дата и время) |
|
varOLEStr |
Ссылка на динамически размещенную строку UNICODE |
|
varDispatch |
Ссылка на автоматический объект (указатель на интерфейс IDispatch) |
|
varError |
Код ошибки операционной системы |
|
varBoolean |
Тип WordBool |
|
varUnknown |
Ссылка на неизвестный объект COM (указатель на интерфейс IUnknown) |
|
varByte |
Тип Byte |
|
varString |
Ссылка на динамически размещенную строку в стиле Pascal (тип AnsiString) |
|
varTypeMask |
Битовая маска для извлечения кода типа |
|
varArray |
Бит, устанавливаемый при ссылке на массив variant |
|
varByRef |
Бит, устанавливаемый при ссылке на тип variant |
Остановимся на массивах типа variant. Переменной типа variant нельзя присвоить значение обычного статического массива. Это можно сделать только специальными функциями VarArrayCreate и VarArrayOf. Функция VarArrayCreate определена следующим образом:
Function VarArrayCreate (const Bounds: array of integer;
VarType: Integer):Variant;
Здесь параметр Bounds является массивом, содержащим четное количество целых чисел, каждая пара которых определяет нижнее и верхнее значения индекса массива (точнее, размерности массива, если массив многомерный). Параметр VarType определяет тип элементов массива. Он может принимать значения, приведенные выше в таблице, кроме varString, varArray, varByRef. Например, операторы
var V: variant;
...
V:=VarArrayCreate ([0,9],varInteger);
создают в переменной V типа variant массив из десяти целых чисел. Операторы
var A: variant;
...
A:=VarArrayCreate ([0,3],varVariant);
A[0] :=1;
A[1] :=1234.5678;
A[2] :='Привет!';
A[3] :=True;
Label1.Caption :=A[0];
Label2.Caption :=A[1];
создают в переменной А тип массив из четырех значений типа variant, в которые можно заносить и затем использовать значения различных типов.
Функция VarArrayOf определена следующим образом:
Function VarArrayOf (const Values: array of Variant): Variant;
Она возвращает одномерный массив элементов, задаваемых параметром Values. Например, приведенный выше пример можно дополнить операторами
A[3] :=VarArrayOf ([1, `привет!', 100, 1000]);
Label3.Caption:=A[3] [1];
Указатель является величиной, указывающей на некоторый адрес в памяти, где хранятся какие-то данные. Указатели бывают типизированные, указывающие на данные определенного типа, и нетипизированные (типа pointer), которые могут указывать на данные произвольного типа. Чаще всего указатели используются для работы с объектами в динамически распределяемой области памяти, особенно при работе с записями.
Ряд предопределенных типов указателей. Это прежде всего типы указателей на строки: PAnsiChar и PWideChar, представляющие собой соответственно указатели на значения AnsiChar и WideChar . Имеется также родовой тип PChar, определяющий указатель на Char (т.е. пока указывающий на AnsiChar). Эти указатели используются при работе со строками с нулевым символом в конце.
Тип указателя |
Тип переменной, на которую указывает указатель |
|
PAnsiString, PString |
AnsiSting |
|
PByteArray |
ByteArray (объявлен в модуле SysUtils). Используется для доступа к динамически размещаемым массивам |
|
PCurrency |
Currency |
|
PExtended |
Extended |
|
POleVariant |
OleVariant |
|
PShortString |
ShortString |
|
PTextBuf |
TextBuf (объявлен в модуле SysUtils). Внутренний тип буфера в записи файлов TTextRec |
|
PVarRec |
TVarRec (объявлен в модуле System) |
|
PVariant |
Variant |
|
PWideString |
WideString |
|
PWordArray |
TWordArray (объявлен в модуле SysUtils). Используется для доступа к динамически размещаемым массивам 2-байтных величин |
Объявление своего типизированного указателя на любой тип имеет вид:
type <имя указателя> = ^<тип данных>;
Например, предложения:
type Print =^integer;
var P1,P2: Print;
объявляют тип Print указателя на величину типа integer и две переменные P1 и P2, являющиеся указателями на значения типа integer. Однако, надо понимать, что объявление переменных Р1 и Р2 не создает самих величин, на которые они указывают. Выделяется только память под хранение указателей, но сами эти указатели ни на что не указывают. Имеется предопределенная константа nil, которая обычно присваивается указателям, которые в данный момент ни на что не указывают. Чтобы получить доступ к данным, на которые указывает типизированный указатель, надо применить операцию его разыменования. Она записывается с помощью символа ^, помещаемого после указателя. Например, если переменная P1 является указателем приведенного выше типа Print, то выражение P1^ - это та целая величина, на которую указывает указатель Р1. Если I -- переменная целого типа, то после выполнения оператора
P1^ := I;
Р1 начнет указывать на переменную I и выражение P1^ будет возвращать значение этой переменной. Того же результата можно добиться операцией адресации. Например, приведенный выше оператор можно заменить эквивалентным оператором
P1 :=@I;
Этот оператор присваивает указателю P1 адрес переменной I.
Таким образом, применение операций разыменования или адресации - один из способов присвоить указателю ссылку на конкретную область памяти. Другой, более распространенный способ -- применение процедуры new, которая выделяет память под переменную соответствующего типа и присваивает указателю ссылку на эту область. Например, оператор
New (P1);
выделит память для хранения целого значения и присвоит указателю P1 ссылку на это значение.
Операция разыменования не применима к указателям типа pointer. Чтобы разыменовать указатель pointer, надо сначала привести его к другому типу указателя. Например, если указатель Р объявлен как указатель типа pointer, то выражение PInt(P) приведет его тип к объявленному выше типу Print, после чего его можно будет разыменовывать. Таким образом, с помощью приведения типа можно записать такие операторы:
PInt(P) :=P1;
I :=PInt(P)^+P2^;
Указатели широко используются в Object Pascal и Delphi, причем часто неявно для пользователя. Например, передача параметров по ссылке в процедуры и функции осуществляется именно через указатели.
Пример программы
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Button1: TButton;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
const
Pi2=2*Pi; //объявление константы удвоенное Пи
var
R, //радиус
H, //высота
S, //площадь
V : real; //масса
begin
//получаем исходные данные
R :=StrToFloat(Edit1.Text);
H :=StrToFloat(Edit2.Text);
//расчет
S :=Pi2*R*(R+H); //Площадь поверхности цилиндра
V :=Pi*(R*R)*H; //Объем цилиндра
//результат
Label6.Caption := format('%f кв.м', [S]);
Label7.caption := format('%f куб.м', [V]);
end;
end.
Размещено на Allbest.ru
Подобные документы
Элементы языка Object Pascal: идентификаторы, константы, переменные, выражения. Структура проекта Delphi. Операторы и метки. Типы данных языка OPascal. Статические и динамические массивы. Записи с вариантными полями. Совместимость и преобразование типов.
курс лекций [385,4 K], добавлен 18.02.2012Общие сведения о функциях, их структура. Области видимости и классы памяти переменных в функциях. Классификация видов памяти, выделяемой под переменные и константы. Примеры объявления глобальных и локальных переменных. Обращение к функции и ее прототип.
презентация [64,6 K], добавлен 09.12.2013Создание программы для перевода кодов с языка Pascal на язык Си. Обработка программ операторами case, assign, rewrite и write. Способы объявления файла, комментария, переменных, логических и арифметических выражений. Виды синтаксических анализаторов.
курсовая работа [461,0 K], добавлен 03.07.2011Выбор метода проектирования транслятора с языка Паскаль на язык Си, разработка и кодирование алгоритма программы. Использование допустимых операторов в исходном тексте, определение типов переменных и синтаксиса логических и арифметических выражений.
курсовая работа [1,0 M], добавлен 03.07.2011Характеристика вычислительной системы и инструментов разработки. Программирование на языке Pascal в среде Turbo Pascal и на языке Object Pascal в среде Delphi. Использование процедур, функций, массивов, бинарного поиска. Создание базы данных в виде файла.
отчет по практике [2,1 M], добавлен 02.05.2014Конструкции Си, базовые типы данных языка программирования. Идентификаторы и типизированные константы. Область видимости и время жизни переменных. Функции преобразования символьных строк. Функции, работающие со строками. Разработка визуальных компонент.
методичка [400,2 K], добавлен 06.07.2009Рассмотрение правил записи, способов ввода и вывода, использования функций обработки символьных данных в Pascal. Описание алгоритмизации и программирования файловых структур данных, проектирования структуры файла. Ознакомление с работой данных массива.
курсовая работа [336,2 K], добавлен 27.06.2015Линейная программа на Паскаль, примеры составления алгоритмов вычисления и обмена значений переменных. Программа с ветвлениями и циклическая программа, массивы, процедуры и функции, файловые данные и записи в Паскале, строки, графика в Турбо-Паскале.
отчет по практике [99,8 K], добавлен 20.07.2010Основные понятия и структура обработчика на языке Pascal. Элективные курсы по информатике в системе профильного обучения. Элективный курс "Программирование в среде Delphi". Методические материалы по изучению программирования на языке Object Pascal.
методичка [55,4 K], добавлен 08.12.2010Разработка программ на языке Turbo Pascal на основе использования массивов данных. Особенности хранения данных, способы объявления переменных, действия над элементами массивов, их ввод и вывод. Практическое применение одномерных и многомерных массивов.
методичка [17,8 K], добавлен 25.11.2010