Практика
Константы в Delphi

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика
Константа – это объект, значение которого известно еще до начала работы программы. Константы очень удобно использовать когда в тексте программы какое-либо значение повторяется многократно (вы оцените удобство их использования, когда возникнет необходимость изменения этих значений сразу во всей программе).

В Delphi существует следующие виды констант:
  • неименованные
  • именованные
    • нетипизированные
    • типизированные
  • зарезервированные
Неименованные константы (как следует из названия) не имеют имен, и потому их не нужно описывать. Тип неименованной константы определяется компилятором автоматически:
  • любая последовательность цифр (возможно, предваряемая знаком "-" или "+" или разбиваемая одной точкой) воспринимается компилятором как число (целое или вещественное);
  • любая последовательность символов, заключенная в апострофы, воспринимается как строка;
  • любая последовательность целых чисел либо символов через запятую, обрамленная квадратными скобками, воспринимается как множество.
Пример использования неименованных констант:

r := -15.0;
i := 12;
c := 'z';
s := 'a' + 'bc';
v := [1,3,5];
b := True;

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

const 
  n = -1;
  m = 1;
  nm = n * m;
  r = 3.14;
  c = 'z';
  s = c + 'str';
  b = c = s;

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

Примеры типизированных констант:

const 
  i: Integer = -1;
  r: Real = 3.15;
  c: Char = 'z';
  b: Boolean = True;

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

const
  a, b, c: Byte = 0;

Типизированная константа, как и переменная, приобретает указанное в ее объявлении значение (инициируется) лишь один раз: к моменту начала работы (под)программы. Разница между переменной и константой в том, что инициализировать при объявлении можно только глобальные переменные (объявленные в интерфейсной или исполняемой частях модулей, вне процедуры или функции), в то время как типизированные константы таких ограничений не имеют. Более того, при повторном входе в блок (процедуру или функцию), в котором объявлена типизированная константа, повторная инициализация не производится, и она сохраняет то значение, которое имела к моменту выхода из блока. Таким образом, типизированная константа, объявленная внутри процедуры или функции, может быть использована в качестве переменной так называемого долговременного хранения, так как она сохраняет свое значение (в пределах своего блока кода) до завершения работы приложения.

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

function Test: Boolean;
const
  Count: Cardinal = 0;
begin
   Inc( Count );
   {...}
   Result := {...};
end;

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

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

Возможностью изменения значения типизированной константы можно управлять с помощью настроек проекта: Project – Options… – Delphi Compiler – Compiling – Syntax options – Assignable typed constants. Кроме того эту опцию дублирует директива компилятора {$WRITEABLECONST ON} (или ее более краткий аналог {$J+}). По умолчанию эта возможность отключена – {$J-}.

Пример изменения значения типизированной константы в runtime:

const
{$J+}
  N: Byte = 10;
{$J-}

procedure TForm1.Button1Click(Sender: TObject);
begin
   Inc( N, 10 );
   ShowMessage( IntToStr( N ) );
end;

Есть и другой способ изменения значения типизированной константы в runtime, без применения директив условной компиляции. В этом способе результат достигается путем нехитрой манипуляции с указателями.

const
  N: Integer = 10;
  S: string = 'text sample';

procedure ChangeConst( const Constant; var Value; Size: Integer );
begin
   Move( ( @Value )^, ( @Constant )^, Size );
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  NewN: Integer;
  NewS: string;
begin
   // String Demo:
   NewS := 'new text';
   ChangeConst( S, NewS, SizeOf( string ) );
   ShowMessage( S );
   // Integer Demo:
   NewN := 20;
   ChangeConst( N, NewN, SizeOf( Integer ) );
   ShowMessage( IntToStr( N ) );
end;

Типизированные константы обладают еще одним интересным свойством – будучи объявленной членом класса она будет общей для всех объектов этого класса (в отличие от переменной, значение которой будет “своим” для каждого объекта.

type
  TTest = class
  private
    {$J+}
    const N: Integer = 10;
    {$J-}
  end;

var
  Form1: TForm1;

  t1: TTest;
  t2: TTest;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
   t1 := TTest.Create;
   t2 := TTest.Create;
   ShowMessage( IntToStr( t2.N ) );
   t1.N := 20;
   ShowMessage( IntToStr( t2.N ) );
end;

И, наконец, зарезервированные константы, которые уже определены в Delphi и могут быть использованы без объявления. Их совсем немного:
  • True (тип Boolean);
  • False (тип Boolean);
  • MaxInt (тип Integer);
  • MaxLongint (тип Integer).
Использование этих констант может таить в себе опасность, если вы работаете с чужим кодом. Связано это с тем, что эти константы можно переопределить. Помните старый прикол?

#define TRUE FALSE // счастливой отладки суки

Так вот, тоже самое можно сделать и в Delphi.

const
  False{: Boolean} = Boolean( -1 );
  True{: Boolean} = Boolean( 0 );

Будьте бдительны! Удачи в программировании!


При использовании материала - ссылка на сайт обязательна