суббота, 25 февраля 2012 г.

Объявляемые константы

Перевод из справочной системы Delphi

Несколько видов конструкций языка называют "константами". Существуют числовые константы (их также называют числами), строковые константы (их называют символьными строками или строковыми литералами), например, "Hello world!". Все перечисляемые типы определяют константы, которые являются значениями этих типов. Есть предопределенные константы, такие как True, False и nil. Наконец, есть константы, создаваемые объявлением.

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


Чистые константы

Чистая константа – это объявленный идентификатор, значение которого не может меняться. Например:

const MaxValue = 237;

объявляет константу с именем MaxValue, которая возвращает целочисленное значение 237. Синтаксис объявления чистой константы:

const identifier = constantExpression

где identifier – это любой допустимый идентификатор, а constantExpression – это выражение, которое компилятор может вычислить без выполнения программы.

Если constantExpression возвращает порядковое значение, вы можете определить тип объявленной константы при помощи преобразования типа. Например:

const MyNumber = Int64(17);

объявляет константу с именем MyNumber и типом Int64, которая возвращает целое число 17. В остальных случаях тип объявленной константы – это тип constantExpression.

  • Если constantExpression – это символьная строка, объявленная константа совместима любым строковым типом. Если символьная строка имеет длину 1, она также будет совместима с любым символьным типом.
  • Если constantExpression – это дробное число, его тип - Extended. А если целое число – ее тип можно определить по таблице, приведенной ниже.

Типы целочисленных констант
Диапазон константы (шестнадцатеричный)Диапазон константы (десятичный)ТипПсевдоним
0-$FF0-255ByteUInt8
0-$FFFF0-65535WordUInt16
0-$FFFFFFFF0-4294967295CardinalUInt32, LongWord
0-$FFFFFFFFFFFFFFFF0-18446744073709551615UInt64
-$80 - $7F-128 - 127ShortIntInt8
-$8000 - $7FFF-32768 - 32767SmallIntInt16
-$80000000 - $7FFFFFFF-2147483648 - 2147483647IntegerInt32, LongInt
-$8000000000000000 - $7FFFFFFFFFFFFFFF-9223372036854775808 - 9223372036854775807Int64

32-битный стандартный целочисленный тип
Диапазон константы (шестнадцатеричный)Диапазон константы (десятичный)ТипЭквивалент
-$80000000 - $7FFFFFFF-2147483648 - 2147483647NativeIntInteger
0 - $FFFFFFFF0 - 4294967295NativeUIntCardinal

64-битный стандартный целочисленный тип
Диапазон константы (шестнадцатеричный)Диапазон константы (десятичный)ТипЭквивалент
-$8000000000000000 - $7FFFFFFFFFFFFFFF-9223372036854775808 - 9223372036854775807NativeIntInt64
0 - $FFFFFFFFFFFFFFFF0 - 18446744073709551615NativeUIntUInt64

Далее приведены примеры объявления констант:
const
  Min = 0;
  Max = 100;
  Center = (Max - Min) div 2;
  Beta = Chr(225);
  NumChars = Ord('Z') - Ord('A') + 1;
  Message = 'Out of memory';
  ErrStr = ' Error: ' + Message + '. ';
  ErrPos = 80 - Length(ErrStr) div 2;
  Ln10 = 2.302585092994045684;
  Ln10R = 1 / Ln10;
  Numeric = ['0'..'9'];
  Alpha = ['A'..'Z', 'a'..'z'];
  AlphaNum = Alpha + Numeric;

Константные выражения

Константное выражение – это выражение, значение которого компилятор может определить без выполнения программы, в которую оно включено. Константные выражения включают числа, символьные строки, чистые константы, значения перечисляемых типов, специальные константы True, False и nil и выражения, построенные на базе этих элементов с использованием операторов, преобразования типов и конструкторов множеств. Константные выражения не могут включать переменных, указателей и вызовов функций, зa исключаением:

AbsHighLowPredSucc
ChrLengthOddRoundSwap
HiLoOrdSizeOfTrunc

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

Примеры константных выражений:
100
'A'
256 - 1
(2.5 + 1) / (2.5 - 1)
'Embarcadero' + ' ' + 'Developer'
Chr(32)
Ord('Z') - Ord('A') + 1

Ресурсные строки

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

Ресурсные строки объявляются как и прочие чистые константы, но ключевое слово const заменяется на resourcestring. Выражение справа от символа "=" должно быть константным выражением и должно возвращать строковое значение. Например:

resourcestring
  CreateError = 'Cannot create file %s';
  OpenError = 'Cannot open file %s';
  LineTooLong = 'Line too long';
  ProductName = 'Embarcadero Rocks';
  SomeResourceString = SomeTrueConstant;

Типизированные константы

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

Объявление типизированной константы выглядит следующим образом:
const identifier: type = value

где identifier – это любой допустимый идентификатор, type – это любой тип, за исключением файлов и вариантов, а value – это выражение типа type. Например:

const Max: Integer = 100;

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


Константы-массивы

Чтобы объявить константу-массив следует заключить значения элементов массива в скобки и разделить их запятыми. Значения элементов массива должны представлять собой константные выражения. Например:

const Digits: array[0..9] of Char = 
  ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');

объявляет типизированную константу с именем Digits, которая содержит массив символов.

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

const Digits: array[0..9] of Char = '0123456789';

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

type TCube = array[0..1, 0..1, 0..1] of Integer;
const Maze: TCube = (((0, 1), (2, 3)), ((4, 5), (6,7)));
создает массив с именем Maze, в котором:
Maze[0,0,0] = 0
Maze[0,0,1] = 1
Maze[0,1,0] = 2
Maze[0,1,1] = 3
Maze[1,0,0] = 4
Maze[1,0,1] = 5
Maze[1,1,0] = 6
Maze[1,1,1] = 7
Константы-массивы не могут содержать значения файлового типа на любых уровнях.

Константы-записи

Для объявления константы типа запись нужно определить значение каждого поля следующим образом: fieldName: value. Присваивания значений полям разделяются точками с запятой (;). Значения должны быть константными выражениями. Поля должны быть перечислены в том же порядке, в каком они следуют в объявлении типа записи. Значение для поля-тэга (если такое присутствует) должно быть установлено. Если запись имеет вариантную часть, то значение может быть установлено только для варианта, определенного полем-тэгом.

Примеры:
type
  TPoint = record
     X, Y: Single;
  end;
  TVector = array[0..1] of TPoint;
  TMonth = (Jan, Feb, Mar, Apr, May, Jun, Jul, 
             Aug, Sep, Oct, Nov, Dec);
  TDate = record
    D: 1..31;
    M: TMonth;
    Y: 1900..1999;
  end;
const
  Origin: TPoint = (X: 0.0; Y: 0.0);
  Line: TVector = ((X: -3.1; Y: 1.5), (X: 5.8; Y: 3.0));
  SomeDay: TDate = (D: 2; M: Dec; Y: 1960);

Константы-записи не могут содержать значения файлового типа на любом уровне.


Процедурные константы

Для объявления процедурной константы укажите имя функции или процедуры, совместимой с объявляемым типом константы. Например:

function Calc(X, Y: Integer): Integer;
begin
  ...
end;

type TFunction = function(X, Y: Integer): Integer;
const MyFunction: TFunction = Calc;

Сделав такое объявление, вы сможете использовать процедурную константу MyFunction при вызове функции:

I := MyFunction(5, 7);

Вы можете присвоить значение nil процедурной константе.


Указательные константы

Когда вы объявляете указательную константу, вы должны инициализировать ее значением, которое может быть вычислено в процессе компиляции по крайней мере как относительный адрес. Есть три способа сделать это: оператор @, nil и (если константа имеет тип Pchar или PWideChar) при помощи строкового литерала. Например, если I – это глобальная переменная типа Integer, вы можете объявить константу следующим образом:

const PI: ^Integer = @I;

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

const PF: Pointer = @MyFunction;

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

const WarningStr: PChar = 'Warning!';

Изменяемые типизированные константы

Delphi разрешает изменять типизированные константы в том, случае, если вы устанавливаете директиву компиляторка ($J+} или {$WRITEABLECONST ON}.

При включении директивы $J+ вы можете использовать инструкции присваивания для изменения значения типизированных констант, также как и для переменных. Например:

{$J+} 
const
  foo: Integer = 12;
begin
  foo := 14;
end.
Различия между изменяемыми константами и инициализированными переменными:
  • Изменяемые константы могут быть объявлены глобально или локально в процедурах, функциях или методах;
  • Инициализированные переменные можно объявить только глобально.
  • При попытке присваивания значения инициализированным переменным внутри процедур или методов возникает ошибка компиляции.

Комментариев нет:

Отправить комментарий