$Q — Тип Delphi


$Q — Тип Delphi

При создании любой серьёзной программы не обойтись без дополнительных, более сложных, чем числа и строки, типов данных. В Delphi программист может для своих целей конструировать собственные типы данных. Чтобы ввести в программу (описать) новый тип данных, применяется оператор с ключевым словом type:
type название_типа = описание_типа;

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

type FootballTeam = (Spartak, Dinamo, CSKA, Torpedo, Lokomotiv);
var MyTeam: FootballTeam;
begin
MyTeam:=Spartak;
end;

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

  • все целочисленные типы, для которых всегда можно указать число, следующее за числом N;
  • символьные типы (Char): за символом ‘a’ всегда следует ‘b’, за ‘0’ следует ‘1’, и так далее;
  • логические типы — тип Boolean также представляет собой перечислимый тип: type Boolean = (false, true);

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

  • массивы
  • записи
  • множества

Массив — это структура данных, доступ к элементам которой осуществляется по номеру (или индексу). Все элементы массива имеют одинаковый тип.
Описание массива имеет вид:

type имя_типа_массива = array [диапазон] of тип_элемента;

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

type TMyArray = array [1 .. 100] of Integer;

Теперь можно описать переменные типа TMyArray:

var A, B: TMyArray;

Вместо присвоения типа можно явно описать переменные как массивы:

var A, B : array [1..100] of Integer;

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

Иногда требуется узнать верхнюю или нижнюю границу массива. Для этого служат встроенные функции:

High() — вернёт число, являющееся верхней границей массива;
Low() — вернёт число, являющееся нижней границей массива.

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

Выражение B := A означает, что каждый элемент массива B будет равен элементу с таким же индексом массива A. Такое присвоение возможно только если оба массива объявлены через некий поименованный тип, или перечислены в одном списке. И в случае:

его использовать невозможно (но возможно поэлементное присвоение B[1] := A[2]; и т.д.).

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

1 2 3 4
5 6 7 8
9 10 11 12

можно описать в виде массива с двумя измерениями:

type MyTable = array[1..4, 1..3] of Integer;
var X : MyTable;
Y : Integer;
begin
Y:=X[3, 2];
end;

Теперь в результате операции присвоения Y будет равен 7.
Многомерный, например, двумерный массив можно описать как массив массивов:

type TMyArray = array [1 .. 4] of array [1 .. 3] of Integer;

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

type TDinArray = array of Integer;
var A : TDinArray;

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


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

type T3DinArray = array of array of Integer;
var A : T3DinArray;

В программе сначала задаётся размер по первому измерению (количество столбцов):

SetLength(A, 3);

Затем задаётся размер второго измерения для каждого из трёх столбцов, например:

SetLength(A[0], 3);
SetLength(A[1], 2);
SetLength(A[2], 1);



    ТипДиапазон значенииФизический формат
    Shortint-128-1278 бит, со знаком
    Smallint-32 768-32 76716 бит, со знаком
    Longint-2 147 483 648-2 147 483 64732 бит, со знаком
    Byte0-2558 бит, без знака
    Word0-65 53516 бит, без знака


Диапазоны значений и форматы физических целых типов не зависят от микропроцессора и операционной системы, в которых выполняется программа. Они не меняются (или, по крайней мере, не должны меняться) с изменением реализации или версии Object Pascal.
Диапазоны значений логических целых типов (Integer и Cardinal) определяются совершенно иным образом. Как видно из табл. 1.3, они никак не связаны с диапазонами соответствующих физических типов. Обратите внимание, что в Delphi по умолчанию задано 32-разрядное представление.

Таблица 1.3. Логические целые типы


    ТипДиапазон значенийФизический формат
    Integer-32 768-32 76716 бит, со знаком (SmalIInt)
    Integer-2 147 483 648-2 147 483 64732 бит, со знаком (Longint)
    Cardinal0-65 53516 бит, без знака (Word)
    Cardinal0-2 14748364732 бит, без знака (Longint)

Совет: В С и C++ для целых значений определены типы int, short int (или просто short) и long int (или просто long). Тип int из C/C++ соответствует типу Integer из Delphi, a long из C/C++ — Longint из Delphi. Однако Shortint из C/C++ соответствует в Delphi не Shortint, a Smalltlnt. Эквивалент Shortint из Delphi в C/C++— это signed char. Тип unsigned char в C/C++ соответствует типу Byte из Delphi. В C/C++ существует еще тип unsigned long, аналога которому в Delphi нет.

Над целыми данными выполняются все операции, определенные для порядковых типов, но с ними все же удобнее работать как с числами, а не с «нечисленными порядковыми типами». Как и «живые» числа, данные целых типов можно складывать (+), вычитать (-) и умножать (*). Однако некоторые операции и функции, применяемые к данным целых типов, имеют несколько иной смысл.

Операция Результат
Abs (X) Возвращает абсолютное целое значение Х
Х Div Y Возвращает целую часть частного деления Х на Y
Х Mod Y Возвращает остаток частного деления Х на Y
Odd (X) Возвращает булево True (истина), если Х — нечетное целое, и False (ложь) — в противном случае
Sqr (X) Возвращает целый квадрат Х (т.е. Х*Х)

Символьные типы
Смысл символьных данных очевиден, когда они выводятся на экран или принтер. Тем не менее, определение символьного типа может зависеть от того, что подразумевать под словом символ. Обычно символьные типы данных задают схему взаимодействия между участками памяти разного объема и некоторым стандартным методом кодирования/декодирования для обмена символьной информацией. В классическом языке Pascal не задано никакой схемы, и в конкретных реализациях применялось то, что на том же компьютере мог использовать каждый.
В реализациях языка Pascal для первых микропроцессоров была применена 7-битовая схема, названная ASCII (American Standard Code for Information Interchange — Американский стандартный код для обмена информацией). Эта схема и поныне широко распространена, но информация хранится, как правило, в 8-битовых участках памяти. Дополнительный бит удваивает число возможных представлений символов, но реализации расширенного набора символов ASCII часто бывают далеки от стандарта. В данной версии Delphi определен набор 8-битовых символов, известный как расширенный (extended) ANSI (American National Standards Institute — Американский национальный институт стандартов). Как бы то ни было, символьную схему приходится воспринимать так, как ее воспринимает операционная система. Для оконных операционных систем фирмы Microsoft это схема ANSI, включающая ограниченное число предназначенных для вывода международных знаков. В стремлении же применить более обширный набор международных знаков весь компьютерный мир переходит к 16-битовой схеме, именуемой UNICODE, в которой первые 256 знаков совпадают с символами, определенными в схеме ANSI.
Для совместимости со всеми этими представлениями в Object Pascal определены два физических символьных типа и один логический.
Физические типы перечислены ниже.

AnsiChar Однобайтовые символы, упорядоченные в соответствии с расширенным набором символов ANSI
WideChar Символы объемом в слово, упорядоченные в соответствии с международным набором символов UNICODE. Первые 256 символов совпадают с символами ANSI


Символьные типы объемом в двойное слово (32 бит) отсутствуют.
Логический символьный тип именуется char. В классическом языке Pascal char— единственный символьный тип. В Delphi char всегда соответствует физическому типу данных AnsiChar. У американских программистов ассоциация символа с однобайтовой ячейкой памяти укоренилась за долгие годы настолько, что им зачастую просто не приходит в голову, что можно использовать другие схемы кодирования. Однако дискуссии по интернационализации программ в Internet и World Wide Web могут существенно изменить их отношение к проблеме объема символьных данных. Применяя логический тип char, следует делать реализации для других микропроцессоров и операционных систем, в которых char может определяться как WideChar. При написании программ, которые могут обрабатывать строки любого размера, для указания этого размера рекомендуется применять функцию SizeOf, не задавая ее жестко постоянной. Функция Ord (С), где С — любая переменная символьного типа, возвращает целое значение, которым символ С представлен в памяти.


    Chr (X)Преобразует целую переменную в переменную типа char с тем же порядковым номером. В Delphi это эквивалентно заданию типа Char (X)
    UpCaseПреобразует строчную букву в прописную



Совет: Процессор не различает типы char, определенные в C/C++ и Delphi. Однако функционально каждый из этих языков трактует данный тип совершенно по-разному. В C/C++ это целый тип, переменной которого можно присваивать целые значения. Переменной int можно присвоить символьное значение, а переменной char — целое. В Delphi символьные типы жестко отделены от численных. Для присвоения численному значению символьного здесь необходимо воспользоваться функцией Ord. В языке Basic один символ представляется так же, как и строка символов. Функция Chr из Delphi эквивалентна функции CHR$ из Basic. Функция Ord из Delphi, возвращающая код ANSI символьной переменной, подобна функции A3 С из Basic, аргумент которой представляет односимвольную строку.

Булевы типы
На ранней стадии обучения программисты осваивают понятие бита, два состояния которого можно использовать для записи информации о чем-либо, представляющем собой одно из двух. Бит может обозначать 0 или 1, ДА или НЕТ, ВКЛЮЧЕНО или ВЫКЛЮЧЕНО, ВЕРХ или НИЗ, СТОЯТЬ или ИДТИ. В Object Pascal информация о чем-либо, что можно представить как ИСТИНА (True) или ЛОЖЬ (False), хранится в переменных булевых типов. Всего таких типов че-тыре, и они представлены в табл. 1.4.


    Таблица 1.4. Размеры переменных булевых типов


    ТипРазмер
    Boolean1 байт
    ByteBool1 байт
    WordBool2 байт (объем Word)
    LongBool4 байт (объем Longint)


По аналогии с целыми и символьными типами, подразделяющимися на физические и логические, естественно предположить, что ByteBool, WordBool и LongBool — физические типы, Boolean — логический. Но в данном случае это не совсем так. Все четыре типа различны. Для Object Pascal предпочтителен тип Boolean, остальные определены для совместимости с другими языками программирования и операционными системами.
Переменным типа Boolean можно присваивать только значения True (истина) и False (ложь). Переменные ByteBool, WordBool и LongBool могут принимать и другие порядковые значения, интерпретируемые обычно как False в случае нуля и True — при любом ненулевом значении.

Совет: Булевы типы в Delphi можно сравнить с типом LOGICAL языка FORTRAN. В Basic, С и C++ булевы типы как таковые отсутствуют. Булевы выражения в этих языках применяются точно так же, как во всех остальных, однако результаты этих выражений интерпретируются не как значения отдельного типа, а как целые числа. Как в Basic, так и в C/C++ булевы выражения дают численные результаты, интерпретируемые как False в случае 0 и True — в случае любого ненулевого значения. Это совместимо с порядковыми значениями булевых выражений в Delphi. В C/C++ простые сравнения дают результат 1 (True) или 0 (False). Это эквивалентно булевым значениям Delphi. Только результат сравнения в Delphi выводится как булевый, а не целый. В большинстве случаев типу Boolean из Delphi соответствует тип char в C/C++. В Basic зарезервированы слова TRUE (эквивалентно константе -1) и FALSE (эквивалентно константе 0). В Basic TRUE меньше FALSE, в Delphi, наоборот, False меньше True.

Перечислимые типы
Type enum type = (first value, value2, value3, last value);
Обычно данные перечислимых типов содержат дискретные значения, представляемые не числами, а именами. Тип Boolean— простейший перечислимый тип в Object Pascal. Булевы переменные могут принимать два значения, выражаемые именами True и False, а сам тип определен в Object Pascal так, как будто он объявлен следующим образом:
Type Boolean = (False, True);
С помощью типа Boolean в Object Pascal выполняются сравнения, большинство же перечислимых типов — это просто списки уникальных имен или идентификаторов, зарезервированных с конкретной целью. Например, можно создать тип MyColor (мой цвет) со значениями myRed, myGreen и myBlue (мой красный, мой зеленый, мой синий). Это делается совсем просто:
Type MyColor = (myRed, myGreen, myBlue);
В этой строке объявлены четыре новых идентификатора: MyColor, myRed, myGreen и myBlue. идентификатором MyColor обозначен порядковый тип, следовательно, в синтаксисе Object Pascal можно применять этот идентификатор везде, где разрешены перечислимые типы. Остальные три идентификатора— это значения типа MyColor. Подобно символьным и булевым типам перечислимые не являются числами, и использовать их наподобие чисел не имеет смысла. Однако перечислимые типы относятся к порядковым, так что значения любого такого типа упорядочены. Идентификаторам в списке присваиваются в качестве порядковых номеров последовательные числа. Первому имени присваивается порядковый номер 0, второму — 1 и т.д.

Совет: В С и C++ есть тип enema, аналогичный перечислимому типу Delphi. Но в этих языках можно произвольно присваивать идентификаторам постоянные значения. В Delphi же соответствие имен и их значений фиксиро-вано: первому имени присваивается значение 0, каждому последующему — на единицу больше. В С тип enum применяется лишь как средство быстрого определения набора целых постоянных. В C++ объявленные в перечислимом типе идентификаторы можно присваивать только переменным того же типа.

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

Type subrange type = low value. high value;

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

Применение перечисляемых типов Delphi.


Конечно этот пост не вызовет особого интереса у «акул шоубиза Delphi-кодинга», но блог ведь читают и те кто только пробуют разобраться в Delphi и создать что-то свое. Поэтому, думаю, что для таких людей пост «Применение перечисляемых типов Delphi» поможет сделать их приложения более…профессиональными что-ли :).
Не так давно, вдохновленный переводами Александра Божко статей о новом RTTI Delphi 2010 я решил засунуть свою лень поглубже..в портмоне и начать наконец-то разбираться с тем, что такое RTTI, как использовать и т.д. Вообще тема RTTI достаточно обширна и интересна, но сегодня речь пойдет о применении возможностей RunTime Type Information при работе с перечисляемым типом данных. А чтобы не останавливаться на голой теории, рассмотрим применим наши новые знания на практическом примере.

Итак, что такое RTTI.
Runtime Type Information или сокрашенно RTTI (информация о типах времени исполнения) —это данные, генерируемые компилятором Delphi об объектах программы. RTTI представляет собой возможность языка, обеспечивающее приложение информацией об объектах (имя, размер экземпляра, указатели на класс-предок, имя класса и т. д.) и о простых типах во время работы программы. Delphi, например, использует RTTI для доступа к значениям свойств компонент, сохраняемых и считываемых из dfm-файлов и отображения их в Object Inspector.
Основополагающие определения типов, основные функции и процедуры для работы с runtime информацией находятся в модуле TypInfo. Этот модуль содержит две фундаментальные структуры для работы с RTTI — TTypeInfo и TTypeData (типы указателей на них — PTypeInfo и PTypeData соответственно). Попробуем использовать их на конкретном примере.
Допустим, нам необходимо сформировать строку-запрос к тому же Google, чтобы получить доступ к API. Что мы можем почерпнуть из документации по ClientLogin?
1. Это то, что такие параметры как AccountType и Service могут принимать вполне конкретные значения, которые можно представить в виде двух перечисляемых типов данных:

2. Ответ сервера также может содержать ограниченное количество значений (кодов) ошибок и 1 значение («Ok») при успешной аутентификации. Следовательно получим ещё один тип данных:

Теперь, когда все перечисляемые типы данных определены, возникает простой вопрос «Что дальше?». Как бы мы поступили, например, при формировании строки запроса, если б абсолютно ничего не знали про RTTI и модуль TypInfo в частности?
Как минимум, мы бы организовали, что-то наподобие этого:

Примерно то же самое и в отношении TServices. Будет ли этот код работать? Конечно будет…куда он нафиг денется. Но ведь можно сделать и по другому.
В модуле TypInfo определен следующий метод:

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

Мы получим сообщение, содержащее строку «HOSTED». Теперь применив этот метод, мы можем сократить код представленный выше всего до одной строки:

Или, если Вы используете какой-то шаблон для формирования строки, то так:

Типы данных Delphi и работа с ними

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

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

Структурные типы. К структурным типам относятся множества, массивы, записи, файлы, классы, интерфейсы.

Целые типы данных. В переменных целых типов информация представляется в виде целых чисел, т.е. чисел не имеющих дробной части.

Таблица 1 Операции над порядковыми типами

Минимальное значение порядкового типа Т

Максимальное значение порядкового типа Т

Порядковый номер значения выражения порядкового типа. Для целого выражения — просто его значение. Для остальных порядковых типов Ord возвращает физическое представление результата выражения, трактуемое как целое число. Возвращаемое значение всегда принадлежит одному из целых типов

Предыдущее по порядку значение. Для целых выражений эквивалентно Х-1

Следующее по порядку значение. Для целых выражений эквивалентно Х+1

Уменьшает значение переменной на 1. Эквивалентно V := Pred(V)

Увеличивает значение переменной на 1. Эквивалентно V := Succ(V)

8 битов, беззнаковый

16 битов, беззнаковый

32 бита, беззнаковый

Также существует такой тип, как Integer, который эквивалентен типу LongInt. Его диапазон от -2147483648 до 21474836478. Занимает 4 байта в пямяти. Основными являются Integer и Cardinal, так что в большинстве случаев желательно использовать эти типы.

Над целыми данными выполняются все операции, определенные для порядковых типов. Операции над целыми типами:

Возвращает абсолютное целое значение Х

Возвращает целую часть частного деления Х на Y


Возвращает остаток частного деления Х на Y

Возвращает булево True (истина), если Х — нечетное целое, и False (ложь) — в противном случае

Действительные типы данных. В переменных действительных типов содержатся числа, состоящие из целой и дробной частей.

Количество значащих цифр

Основным, обеспечивающим максимальную производительность, является тип Real, который в настоящий момент эквивалентен типу Double.

Таблица 5 Функции действительных типов

Абсолютная величина х

Косинус х (х выражается в радианах, а не в градусах)

Экспоненциальная функция от х

Дробная часть х

Целая часть х. Несмотря на название, возвращает действительное значение (с плавающей запятой), т.е. просто устанавливает нуль в дробной части

Натуральный логарифм от х

Ближайшее к х целое значение. Возвращает значение целого типа. Условие «ближайшее к х» не работает, если верхнее и нижнее значения оказываются равноудаленными (например, если дробная часть точно равна 0,5). В этих случаях Delphi перекладывает решение на операционную систему. Обычно процессоры Intel решают эту задачу в соответствии с рекомендацией IEEE округлять в сторону ближайшего четного целого числа. Иногда такой подход называют «банкирским округлением»

Квадрат х, т.е. X*X

Квадратный корень от х

Целая часть х. В отличие от Int, возвращающей

Символьные типы данных. Символьные типы предназначены для хранения одного символа.

Однобайтовые символы, упорядоченные в соответствии с расширенным набором символов ANSI

Символы объемом в слово, упорядоченные в соответствии с международным набором символов UNICODE. Первые 256 символов совпадают с символами ANSI

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

Таблица 7 Размеры переменных булевых типов

2 байт (объем Word)

4 байт (объем Longint)

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

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

Имя: [нижний_индекс..верхний_индекс] of тип


где: имя — имя массива;

array — зарезервированное слово языка Delphi, обозначающее, что объявляемое имя является именем массива;

нижний_индекс и верхний_индекс — целые константы, определяющие диапазон изменения индекса элементов массива и, неявно, количество элементов (размер) массива;

3.2.2. Вещественные типы Delphi

3.2.2. Вещественные типы Delphi

В Delphi существует четыре вещественных типа: Single , Double , Extended и Real . Их общий формат одинаков (рис. 3.1, а).

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

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

а) общий вид вещественного числа

б) Двоичное представление числа типа Single

Рис. 3.1. Хранение вещественного числа в памяти

Микропроцессор Intel 8086/88 и его улучшенные варианты — 80286 и 80386 — также не имели аппаратной поддержки вещественных чисел. Но у систем на базе этих процессоров была возможность подключения так называемого сопроцессора. Эта микросхема работала с памятью через шины основного процессора и обеспечивала аппаратную поддержку вещественных чисел. В системах средней руки гнездо сопроцессора обычно было пустым, т. к. это уменьшало цену (разумеется, вставить туда сопроцессор не было проблемой). Для каждого центрального процессора выпускались свои сопроцессоры, маркировавшиеся Intel 8087, 80287 и 80387 соответственно. Были даже сопроцессоры, выпускаемые другими фирмами. Они работали быстрее, чем сопроцессоры Intel, но появлялись на рынке позже. Тип вещественных чисел, поддерживаемый сопроцессорами, не совпадает с Real . Он определяется стандартом IEEE (Institute of Electrical and Electronics Engineers).

Чтобы обеспечить в своих системах поддержку типов IEEE, Borland вводит в Turbo Pascal типы Single , Double и Extended . Extended — это основной для сопроцессора тип, a Single и Double получаются из него очень простым усечением. Система команд сопроцессора допускает работу с этими типами: при загрузке числа типа Single или Double во внутренний регистр сопроцессора последний конвертирует их в Extended . Напротив, при выгрузке чисел этих типов из регистра в память сопроцессор усекает их до нужного размера. Внутренние же операции всегда выполняются с данными типа Extended (впрочем, из этого правила есть исключение, на котором мы остановимся позже, после детального рассмотрения формата различных типов). Single и Double позволяют экономить память. Ни один из них также не совпадает с типом Real . В системах с сопроцессорами новые типы обрабатываются заметно (в 2–3 раза) быстрее, чем Real (это с учетом того, что тип Real после соответствующего преобразования также обрабатывался сопроцессором; если же сравнивать обработку типа Extended на машине с сопроцессором и Real на машине без сопроцессора, то там на отдельных операциях достигалась разница в скорости примерно в 100 раз). Чтобы программы с этими типами можно было выполнять и в системах без сопроцессора, была предусмотрена возможность подключать к ним программный эмулятор сопроцессора. Обработка этих типов эмулятором была медленнее, чем обработка Real .

Начиная с 486-й серии Intel берет курс на интеграцию процессора и сопроцессора в одной микросхеме. Процент брака в микросхемах слишком велик, поэтому Intel идет на хитрость: если у микросхемы брак только в сопроцессорной части, то на этом кристалле прожигаются перемычки, блокирующие сопроцессор, и микросхема продается как процессор 80486SX, не имеющий встроенного сопроцессора (в отличие от полноценной версии, которую назвали 80486DX). Бывали и обратные ситуации, когда сопроцессор повреждений не имел, зато процессор был неработоспособен. Такие микросхемы превращали в «сопроцессор 80487». Но это уже из области экзотики, и, по имеющейся у нас информации, до России такой сопроцессор не дошел.

Процессор Pentium во всех своих вариантах имел встроенный блок вычислений с плавающей точкой (FPU — Floating Point Unit), и отдельный сопроцессор ему не требовался. Таким образом, с приходом этого процессора тип Real остался только для обратной совместимости, а на передний план вышли типы Single , Double и Extended . Начиная с Delphi 4, тип Real становится синонимом типа Double , а старый 6-байтный тип получает название Real48 .

Здесь и далее под словом Real мы будем понимать старый 6-байтный тип.

Существует директива компилятора <$REALCOMPATIBILITY ON/OFF>, при включении которой (по умолчанию она отключена) Real становится синонимом Real48 , а не Double .

Размеры полей для различных вещественных типов указаны в табл. 3.1.

Таблица 3.1. Размеры полей в вещественных типах

Тип Размер типа, байты Размер мантиссы, биты Размер экспоненты, биты
Single 4 23 8
Double 8 52 11
Extended 10 64 15
Real 6 40 7

Другие параметры вещественных типов, такие как диапазон и точность, можно найти в справке Delphi.

Использование функциональных типов

23.02.2015, 17:43

Использование подпрограмм для обработки простых типов данных
Разработать подпрограмму для получения «перевернутого» натурального числа,то есть числа, цифры.

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

Использование функциональных клавиш для завершения программы
Вводится текст. Конец ввода . Найти количество заглавных букв. program zaglavnye; uses crt;.

Использование шаблона типов
Прочитал про шаблоны типов, интересный и полезный инструмент, но есть несколько вопросов о кухне.


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

$Q — Тип Delphi

В этом уроке мы рассмотрим одну из ключевых возможностей языков программирования — создание собственных типов данных.
Для того чтобы создать свой собственный тип переменной, необходимо сначала его объявить. В Delphi делается это внутри раздела type:
[cc lang=»delphi»]type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
< Private declarations >
public
< Public declarations >
end;[/cc]
Внутри раздела type в стандартных проектах Delphi уже существует тип TForm1. Однако к рассмотрению подобных типов, которые также называются классами, мы перейдем в следующем уроке. В этом уроке мы научимся создавать более простые типы данных.

Для примера того, как нужно объявлять типы данных, давайте создадим самый простейший тип. Он будет представлять дубликат какого-либо другого типа. Укажем его сразу после объявления типа TForm1, т.е. после ключевого слова end, который указывает на завершение описания этого типа. Создается наш собственный тип вот таким образом:
[cc lang=»delphi»]TMyArray = array [1..100] of integer;[/cc]
Т.е. в целом раздел type будет выглядеть следующим образом:
[cc lang=»delphi»]type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
< Private declarations >
public
< Public declarations >
end;

TMyArray = array [1..100] of integer;[/cc]
Мы только что создали свой тип под названием TMyArray, который представляет собой обыкновенный массив сотни целочисленных переменных. Теперь, если мы захотим объявить какой-либо массив, мы можем не указывать эту длинную запись «array [1..100] of integer», а укажем «TMyArray»:
[cc lang=»delphi»]var
a: TMyArray;[/cc]
Этот прием очень удобно использовать, когда требуется объявить одинаковый массив в нескольких участках кода, т.е. много раз. В качестве представляемого типа данных может выступать абсолютно любой тип. Будь то integer, double, string, array и т.п. Итак, мы рассмотрели простейший пример создания типа. Перейдем к более сложным примерам.

Записями record называют более сложные типы, которые могут включать в себя некоторое количество полей. Полями мы будем называть переменные, которые будут входить в состав записи. Создадим запись TBook, в которой опишем какие-либо характеристики, связанные с книгой:
[cc lang=»delphi»]type
TBook = record
Title, Author: string;
PagesCount: integer;
Price: integer;
end;[/cc]
В данном случае Title, Author, PagesCount и Price являются полями типа TBook и описывают какие-то свойства, значения, которые характерны только для типа TBook. Т.е. по сути запись представляет собой совокупность нескольких переменных. Этот тип данных очень удобно использовать тогда, когда мы хотим как-то структурировать данные в нашем коде. Создание переменной TBook будет выглядеть также, как и создание переменной любого другого типа:
[cc lang=»delphi»]var
a: TBook;[/cc]
И теперь мы можем обращаться к тем самым полям записи достаточно просто:
[cc lang=»delphi»]a.Title := ‘Уроки Delphi для начинающих’;
a.Author := ‘Cybern.ru’;
a.PagesCount := 1000;
a.Price := ‘100’;[/cc]
Т.е. мы сначала указываем имя переменной, затем ставим точку и указываем поле нашего типа. Работать с этими полями мы будем абсолютно также, как и с обычными переменными. Для примера мы можем создать тип TBooks, который будет описывать массив книг TBook:
[cc lang=»delphi»]type
TBooks = array [1..100] of TBook;[/cc]
Тогда мы сможем обращаться к каждому полю отдельно взятой книги, например так:
[cc lang=»delphi»]var
Books: TBooks;

for i := 1 to 100 do
Books[i].Title := ‘Book #’ + IntToStr(i); // Присвоим сотне книг имена[/cc]
Поля записей также могут иметь абсолютно любой известный тип, но
[warning]Необходимо учитывать правильный порядок объявления типов. Если тип A используется при объявлении типом B, то тип A обязательно должен быть описан ДО описания типа B. В противном случае (т.е. если тип A будет указан после B в разделе type) компилятор скажет, что он не знает про тип A, который используется при объявлении типа B.[/warning]
В качестве типа поля может выступать даже тип самой записи, например, чтобы один какой-то объект мог содержать информацию о другом каком-то объекте того же типа. Более подробно о полях мы будем говорить при рассмотрении классов и объектно-ориентированного программирования, т.к. там они имеют гораздо больше функционала, нежели в записях.

Перечисляемые типы достаточно просты. Они представляют собой типы таких переменных, которым могут быть присвоены только определенные значения. Например, объявим перечисляемый тип TOperatingSystem:
[cc lang=»delphi»]type
TOperatingSystem = (OSWindows, MacOS, Ubuntu, IOS, Android);[/cc]
Теперь всем переменным типа TOperatingSystem могут быть присвоены только значения OSWindows, MacOS, Ubuntu, IOS и Android:
[cc lang=»delphi»]
var MyOS: TOperatingSystem;

MyOS := OSWindows;[/cc]
Такие типы также могут являться полями записей, да и вообще:
[tip]Абсолютно любой тип может использоваться при описании другого типа. Исключение составляют только те типы, которые описаны после описания данного типа. Их в данном типе мы использовать не можем, т.к. их просто не увидит компилятор.[/tip]

Delphi.Generics types

В данном посте разбираюсь с обобщенными типами данных, руководствуясь книгой Д. Осипова “Delphi. Программирование для Windows. OS X, iOS и Android”. Цель – отработать на практике возможности обобщенных типов.

Зачем нужны обобщенные типы?

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

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

Типы данных

Любые данные, т.е. константы, переменные, свойства, значения функции или выражения, в Object Pascal характеризуются своими типами.

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

Возвращает абсолютное целое значение Х

Возвращает целую часть частного деления Х на Y

Возвращает остаток частного деления Х на Y

Возвращает булево True (истина), если Х — нечетное целое, и False (ложь) — в противном случае

Возвращает целый квадрат Х (т.е. Х*Х)

Согласно принятому в Delphi соглашению, имена типов должны начинаться с латинской буквы Т (от слова Туре-тип).

После объявления типа можно объявить переменную, относящуюся к этому типу в разделе Var.

Переменные любого перечисляемого типа можно объявлять и без предвари­тельного описания этого типа, например: Var TCol: (black, red, green);

Тип-диапазон (или интервальный тип). Это один из типов данных, определяе­мых программистом.

Операции над порядковыми типами

Функции действительных типов


Абсолютная величина х

Косинус х (х выражается в радианах, а не в градусах)

Экспоненциальная функция от х

Дробная часть х

Целая часть х. Несмотря на название, возвращает действительное значение (с плавающей запятой), т.е. просто устанавливает нуль в дробной части

Натуральный логарифм от х

Ближайшее к х целое значение. Возвращает значение целого типа. Условие «ближайшее к х» не работает, если верхнее и нижнее значения оказываются равноудаленными (например, если дробная часть точно равна 0,5). В этих случаях Delphi перекладывает решение на операционную систему. Обычно процессоры Intel решают эту задачу в соответствии с рекомендацией IEEE округлять в сторону ближайшего четного целого числа. Иногда такой подход называют «банкирским округлением»

Квадрат х, т.е. X*X

Квадратный корень от х

Целая часть х. В отличие от Int, возвращающей действительное значение, Trunc возвращает целое

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

Function Date: TdateTime;

Возвращает текущую дату

Преобразует дату в строку символов

Преобразует дату и время в строку символов

Function Time: TdateTime;

Возвращает текущее время

Преобразует время в строку

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

Если длина сцепленной строки превысит максимально допустимую длину N, то «лишние » символы отбрасываются.

Встроенные строковые функ­ции и процедуры:

Function Concat(sl, s2, s3: String): String;

Возвращает последовательное соединение строк. Эквивалентна оператору si + s2 + s3

Function Copy(s: String, pos, len: Integer): String;

Возвращает подстроку длиной максимум len символов, начинающуюся в позиции pos строки s

Procedure Delete(s: String, pos, len: Integer);

Удаляет максимум len символов из строки s, начиная с позиции pos


Procedure Insert(sourse:String, target, pos: Integer);

Вставляет строку source в строковую переменную target, начиная с позиции pos

Function Length (s:String): Integer;

Возвращает динамическую длину строки

Function Pos(substring, s: String): Integer;

Возвращает место первого вхождения подстроки substring в строку s

Стандартные функции и процедуры преобразования строк в другие типы:

Functoin StrToDate(st: String): TdateTime;

Преобразует символы строки в дату

Functoin StrToDateTime (st: String): TdateTime;

Преобразует символы строки в дату и время

Functoin StrToFloat(st: Sting): Extended;

Преобразует символы строки в вещественное число

Functoin StrToInt(st: String): Integer;

Преобразует символы строки в в целое число

Functoin StrToInt(St: String; Default: Integer);

Преобразует символы строки St в целое число. Если строка не содержит правильного представления целого числа, возвращается значение Default

Functoin StrToTime (st: String): TdateTime;

Преобразует символы строки st во время. Строка должна содер­жать два-три числа, разделенных символом «:» (двоеточие)

Procedure Val(St: String; var x; Code: Integer;

Преобразует строку символов во внутреннее представление целой или вещественной переменной X, которое определяется типом этой переменной

Стандартные функции и процедуры обратного преобразования:

Function DateToStr(Value: TDateTime): String;

Преобразует дату из параметра Value в строку символов

Function DateTimeToStr (Value:TDateTime): String;

Преобразует дату и время из параметра Value в строку символов


Procedure DateTimeToString(var St: String; Format: String; Value: TDateTime);

Преобразует дату и время из параметра Value в строку St в соответствии со спецификаторами даты/времени параметра Format

Function FloatToStr(Value: Extended): String;

Преобразует вещественное значение Value в строку символов

Function lntToStr(Value: Integer): String;

Преобразует целое значение Value в строку символов

Function TimeToStr(Value: TDateTime):String;

Преобразует время из параметра Value в строку символов

Procedure Str(X[: Width[: Decimals]]; var St:String);

Преобразует число X любого вещественного или целого типа в строку символов St; параметры Width и Decimals, если они присутствуют, задают формат преобразования. (Width — ширина поля, Decimals — количество символов в дробной части)

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

Различают массивы статические и динамические. Статический массив представляет собой массив, границы индексов и, соответственно, размеры которого задаются при объявлении, т.е. они известны еще до компиляции программы. Формат описания типа статистического массива:

Типы данных Delphi

Язык Delphi поддерживает семь целых типов данных, описание которых приведено в табл. 3.

Таблица 3. Целые типы

Тип Диапазон Формат
Shortint -128 – 127 8 битов
Smallint -32768 – 32767 16 битов
Longint -2147483648 – 2147483647 32 бита
Int64 -2 63 – 2 63 -1 64 бита
Byte 0 – 255 8 битов
Word 0 – 65535 16 битов
Longword 0 – 4294967295 32 бита

Язык Delphi поддерживает и наиболее универсальный целый тип — Integer, который эквивалентен Longint.

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

Таблица 4. Вещественные (дробные) типы

Тип Диапазон Значащих цифр Байтов
Real48 2.9 x 10 -39 – 1.7 x 10 38 11 – 12
Single 1.5 x 10 -45 – 3.4 x 10 38 7 – 8
Double 5.0 x 10 -324 ­– 1.7 x 10 308 15 – 16
Extended 3.6 x 10 -4951 – 1.1 x 10 4932 19 – 20
Comp -2 63 +1 – 2 63 -1 19 – 20
Currency -9223372036854775808 –9223372036854775807 19 –20

Язык Delphi поддерживает и наиболее универсальный вещественный тип – Real, который эквивалентен Double.

Язык Delphi поддерживает два символьных типа: Ansichar и Widechar:

· тип Ansichar — это символы в кодировке ANSI, которым соответствуют числа в диапазоне от 0 до 255;

· тип widechar — это символы в кодировке Unicode, им соответствуют числа от 0 до 65535.

Язык Delphi поддерживает и наиболее универсальный символьный тип –Char, который эквивалентен Ansichar.

Язык Delphi поддерживает три строковых типа: Shortstring, Longstring и WideString:

· тип Shortstring представляет собой статически размещаемые в памяти компьютера строки длиной от 0 до 255 символов;

· тип Longstring представляет собой динамически размещаемые в памяти строки, длина которых ограничена только объемом свободной памяти;

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

Каждый символ строки типа WideString является Unicode-символом. В языке Delphi для обозначения строкового типа допускается использование идентификатора String. Тип String эквивалентен типу Shortstring.

Логическая величина может принимать одно из двух значений True (истина) или False (ложь). В языке Delphi логические величины относят к типу Boolean.

Илон Маск рекомендует:  Write писать в файл
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL