Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ракитин Р.Ю. ООП в Turbo Delphi

.PDF
Скачиваний:
55
Добавлен:
18.03.2015
Размер:
3.59 Mб
Скачать

81

значение переменной, нужно добавить имя этой переменной в список наблюдения (Watch List). Для этого надо из меню выбрать Run Add Watch

(Запуск → Добавить наблюдаемый элемент) и в поле Expression (Выражение)

появившегося диалогового окна Watch Properties (Параметры наблюдения) ввести имя переменной или выражения.

В результате в окно Watch List (Список наблюдения) будет добавлен новый элемент.

Так как переменные программы существуют (и, следо-вательно, доступны) только во время выполнения программы, после имени переменной выводится сообщение: process not accessible (процесс недоступен).

Существует еще один способ, позволяющий проверить значение переменной, не добавляя ее имя в список Watch List. Заключается он в следующем. После того, как программа достигнет точки останова, откроется окно редактора кода, нужно установить курсор мыши на имени переменной, значение которой надо проверить. В окне редактора кода появится окно подсказки, в котором будет выведено значение переменной.

Чтобы завершить процесс пошагового выполнения программы, нужно из меню выбрать Run Program Reset.

82

Глава 6. Числовые типы данных

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

Типы данных специальные конструкции языка, которые

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

объем памяти, выделяемый для размещения элемента (константы, переменной);

набор допустимых действий над элементами данного типа.

Целые типы данных

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

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

В среде Delphi используются следующие целые типы данных:

Название типа

Диапазон

Память,

байт

 

 

Shortint

-128..127

1

Integer

-2147483648..2147483647

4

Longint

-2147483648..2147483647

4

Byte

0..255

1

Word

0..65535

2

Cardinal

0..4294967295

4

Smallint

-32768..32767

2

Int64

-263..+263-1

8

Longword

0..4294967295

4

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

83

+ При использовании операции деления для целых типов нужно быть

внимательным, так как результат может быть дробным, что приведет к несоответствию типов, а следовательно – к ошибке.

Вещественные типы данных

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

Название

Диапазон

Минимальное

Память,

Точность,

типа

значение

байт

всего цифр

 

Real

-1.7976931348623210308..

5.010

-324

8

15-16

1.7976931348623210308

 

 

Single

-3.4028231038..

1.510

-45

4

7-8

3.4028231038

 

Double

-1.7976931348623210308..

5.010

-324

8

15-16

1.7976931348623210308

 

 

Extended

-1.1104392..1.1104392

3.610-4932

10

19-20

Comp

-263..+263-1

1

 

 

8

19-20

Real48

-2.91039..71038

2.910-39

6

11-12

Currency

-922337203685477.5808..

0.0001

8

19-20

922337203685477.5807

 

 

 

 

 

 

Вещественное число в памяти компьютера состоит из трех частей:

ЗНАК ЭКСПОНЕНТА МАНТИССА

Поле «знак» представляет собой знаковый разряд числа, «экспонента» – экспоненциальную часть. «Мантисса» может быть представлена 23-63 разрядами двоичных чисел, что обеспечивает точность представления от 6..8 до 19..20 знаков. Десятичная точка подразумевается перед левым разрядом мантиссы. Однако при действиях с числами ее положение сдвигается влево или вправо (в зависимости от порядка числа, хранящегося в экспоненциальной части). Именно поэтому часто действия над вещественными числами называют арифметикой с плавающей точкой.

+Компьютер всегда обрабатывает числа в формате Extended, а все

остальные типы в этом случае получаются усечением результатов до нужных размеров и применяются в основном для экономии памяти.

Выражения и операции

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

84

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

В языке Delphi определены следующие операции:

унарные (например, not);

мультипликативные (*, /, div, mod, and);

аддитивные (+, - , or);

отношения (=, <>, >, <, >=, <=).

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

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

Приведение типов

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

Явное приведение типов осуществляется программистом с помощью сле- дующей конструкции:

<идентификатор типа>(<выражение>)

Если выражение представляет собой просто переменную, то говорят о

приведении типа переменной. В противном случае говорят о приведении типа значения.

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

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

function Round (const Number: Extended): Int64; – округляет число с плавающей запятой (Number) до целого значения;

function Trunc (const Number: Extended): Integer; – возвращает целочисленную часть числа с плавающей запятой.

Целые же переменные преобразуются в действительные неявно.

В приложениях VCL Win32 явное приведение типа переменной может использоваться и в правой, и в левой частях оператора присваивания.

85

Например, могут быть записаны такие операторы (предполагается, что переменная Ch имеет тип char, а I integer):

Ch:= Char(I); Shortint(Ch):= I;

Эти два оператора дают один и тот же результат. Например, если I = 122 (код ASCII символа «z»), то значение переменной Ch в результате выполнения любого из этих операторов станет равно символу «z».

Способы форматирования и парсинга данных

Практически в каждой программе приходится иметь дело с форматированием и парсингом данных. Под форматированием мы будем понимать перевод данных в строковое (текстовое) представление. Задачу

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

Функции FloatToStr, IntToStr преобразуют в строку соответственно передаваемое в качестве аргумента действительное, целое значение. Пусть объявлены и инициализированы переменные:

var

I: integer; A: real; S: string;

...

I := 123456;

A := I * 1E10;

...

Следующие операторы занесут в переменную S текстовые представления этих переменных:

IntToStr(I); //в S заносится текст ‘123456’ FloatToStr(A); //в S заносится текст ‘1,23456815’

А далее строку S можно отобразить пользователем в метке или в окне редактирования.

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

I:= StrToInt(S); А:= StrToFloat(S);

86

В строке S должно быть записано текстовое представление числа соответствующего типа. Если текст строки не может быть переведен в число, то генерируется исключение EConvertError. Если пользователь вводит текст в окне редактирования, то желательно предвидеть возможность ошибки пользователя и обеспечивать перехват исключения. Для приложения VCL это может быть сделано так:

try

А := StrToFloat(Editl.Text); except

ShowMessage (‘Введено ошибочное число:’ + Editl.Text); end;

Ранее рассмотренные функции и методы не предусматривают возможности влиять на формат отображения данных. Имеются также варианты функций и методов, обеспечивающие формирование собственного, заказного формата. Для использования функций необходимо, чтобы был подключен модуль SysUtils.

Богатое форматирование чисел и текста в строке (Format)

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

function Format (const Formatting: string; Data: array of const): string;

Параметр Formatting определяет, как массив Data данных управляется в возвращенной строке.

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

Спецификатор формата имеет вид

%[<индекс>:][-][<ширина>][.<точность>]<тип>

Как отмечалось выше, спецификатор формата начинается с символа «%», затем без пробелов следует ряд необязательных полей:

[<индекс>:] определяет индекс (номер) аргумента в заданном списке, к которому относится данный спецификатор формата;

[-] индикатор выравнивания влево; [<ширина>] – устанавливает ширину поля; [.<точность>] спецификатор точности.

Затем также без пробела записывается единственное обязательное поле <тип>, определяющее, как и в каком формате будет интерпретироваться аргумент. Ниже приводится список спецификаторов типа.

87

dдесятичное целое. Значение преобразуется в строку десятичных цифр. Если форматируемое значение содержит меньше цифр, то оно дополняется слева нулями;

eнаучный формат значения с плавающей запятой. Значение преобразуется в

формат вида «-d,ddd...E+ddd», где «d» означает цифру. Общее число цифр (включая цифру перед запятой) равно числу, указанному спецификатором точности;

f формат с фиксированной точкой значения с плавающей запятой. Значение преобразуется в формат вида «-ddd,ddd...». Число цифр после десятичной запятой равно числу, указанному спецификатором точности;

mмонетарный формат чисел с плавающей запятой. Значение преобразуется в строку, представляющую собой денежную сумму;

nформат, подобный формату с фиксированной точкой для чисел с плавающей запятой, но отличающийся наличием в результирующей строке разделителей тысяч. Иными словами, число представляется в форме «-d ddd ddd,ddd...»;

p формат отображения указателей. Значение преобразуется в строку вида «XXXX:YYYY», где ХХХХ и YYYY сегмент и смещение указателя, отображаемые четырьмя шестнадцатеричными цифрами;

s формат строки для аргументов вида символ, строка или строка типа PChar. Строка или символ просто вставляются в результирующую строку. Если задан спецификатор точности, то он определяет максимальное число вставляемых символов. Если вставляемая строка длиннее, она усекается;

x шестнадцатеричный формат целых чисел. Значение аргумента преоб- разуется в строку шестнадцатеричных цифр. Если задан спецификатор точности, то он указывает минимальное число цифр в строке; если строка оказывается короче, она дополняется слева нулями.

Богатое форматирование числа с плавающей запятой в строку (FormatFloat)

Функция обеспечивает богатое форматирование числа с плавающей запятой Value в строку.

function FormatFloat (const Formatting: string; Value: Extended): string;

Форматируемая строка Formatting может содержать соединение текста свободного формата и управляющих символов:

0 вызывает отображение цифр или 0;

# дополнительное цифровое отображение; , вызывает отображение тысяч;

. вызывает отображение десятичных чисел;

E+ вызывает отображение знаковой экспоненты; E- дополнительное отображение знака экспоненты;

; разделитель положительных, отрицательных и нулевых значений.

88

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

Ниже приведены строки форматирования и соответствующие им

выходные строки для значений 1234, -1234, 0.5, 0.

 

 

 

 

 

 

Строка

 

 

 

 

форматирования

 

 

 

 

пустая

1234

-1234

0.5

0

0

1234

-1234

1

0

0.00

1234,00

-1234,00

0,50

0,00

#.##

1234

-1234

,5

 

#,##0.00

1 234,00

-1 234,00

0,50

0,00

#,##0.00;

1 234,00

(1 234,00)

0,50

0,00

(#,##0.00)

 

 

 

 

#,##0.00;;Нуль

1 234,00

-1 234,00

0,50

Нуль

0.000Е+00

1.234Е+03

-1.234Е+03

5,000Е-01

0,000Е+00

#.###Е-0

1.234ЕЗ

-1.234ЕЗ

5Е-1

0Е0

89

Глава 7. Работа с текстовой информацией

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

Символы

Для хранения и обработки символов используются переменные типа AnsiChar и WideChar. Тип AnsiChar представляет собой набор ANSI- символов, в котором каждый символ кодируется восьмиразрядным двоичным числом (байтом). Тип WideChar представляет собой набор символов в кодировке Unicode, в которой каждый символ кодируется двумя байтами.

Для обеспечения совместимости с предыдущими версиями поддерживается тип Char, эквивалентный AnsiChar.

Значением переменной символьного типа может быть любой отображаемый символ:

буква русского или латинского алфавитов;

цифра;

знак препинания;

и специальные символы, например, «новая строка».

Переменная символьного типа должна быть объявлена в разделе объявления переменных.

Как и любая переменная программы, переменная типа Char может получить значение в результате выполнения инструкции присваивания. Если

переменная типа Char получает значение в результате выполнения операции присваивания, то справа от знака «:=» должно стоять выражение типа Char, например, переменная типа Char или символьная константа символ, заключенный в кавычки.

Переменную типа Char можно сравнить с другой переменной типа Char или с символьной константой.

Символам русского алфавита соответствуют числа большие, чем символам латинского алфавита, при этом справедливо следующее соотношение:

'А'<'Б'<'В'<..<'Ю'<'Я'<'а'<'б'<'в'<...<'э'<'ю'<'я'

В тексте программы вместо символа можно указать его код, поставив перед числом оператор #. Например, вместо константы 'в' можно записать код #193. Такой способ записи, как правило, используют для записи служебных символов или символов, которые во время набора программы нельзя ввести с клавиатуры. Например, часто используемый при записи сообщений символ «новая строка» записывается как #13.

В программах обработки символьной информации часто используют функции Chr и Ord. Значением функции Chr является символ, код которого

90

указан в качестве параметра. Например, в результате выполнения инструкции c:=Chr(32) переменной с будет присвоено значение пробел.

Функция Ord позволяет определить код символа, который передается ей в качестве параметра. Например, в результате выполнения инструкции k:=Ord('*') переменная k будет содержать число 42 код символа '*'.

Строки

В среде Delphi доступны следующие строковые типы данных:

Название

Максимальная

Занимаемая память

Размер

типа

длина, символов

 

символа, байт

ShortString

255

От 2 до256 байт

1

AnsiString

231

От 4байт до 2 ГБ

1

WideString

230

От 4байт до 2 ГБ

2

Тип ShortString введен для обратной совместимости с Pascal под DOS. При компиляции переменной, описанной с использованием устаревшего типа String, назначается тип ShortString или AnsiString в зависимости от состояния директивы {$Н}. Строковые типы данных являются динамическими, то есть память под них выделяется в зависимости от введенного в них значения.

Доступ к отдельным символам строки осуществляется как к символьному массиву по индексам. Индексы отсчитываются от 1. Если индекс превышает число символов в строке, возвращается нулевой символ с кодом #0.

Для определения числа символов строки SourceString без нулевого символа используется функция

Length (const SourceString: string): Integer;

Пусть объявлена строка:

var

S1, S2: string;

...

S1:=’1234567890’;

S2:=’ABCD’;

...

При применении функции Length для строк S1 и S2 получим соответственно ответ 10 и 4.

Можно установить необходимый размер переменной и программно, с помощью процедуры:

SetLength(var S: string; NewLength: Integer);

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