Константы в Delphi


Содержание

Чем const отличается от var

04.05.2012, 02:39

Спецификаторы фактических параметров процедур (Var, Const)
В чем отличие? Var G: integer; Select(Var G); или Var C: integer; Select(Var G);

const n=20; type number=0.9; num= array[1.n] of number; var a,b,c: num; t: boolean;
Помогите решить пожалуйста) const n=20; type number=0..9; num= array of number; var.

Чем отличается COM объекты от DLL ?
Чем отличается COM объекты от DLL ?

Чем AbsolutePosition отличается от Position?
Доброго времени суток! Поскажите, пожалуйста, в чём физический смысл AbsolutePosition? Да, я.

Чем отличается делфи от паскаля?
Можно ли выучив паскаль,спокойно перейти на делфи?или они только поверхностно похожи?

Константы в Delphi

ТИПИЗИРОВАННЫЕ КОНСТАНТЫ И ИНИЦИИРОВАННЫЕ ПЕРЕМЕННЫЕ

В Object Pascal допускается использование типизированных констант. Они задаются в разделе объявления констант следующим образом:

Здесь — идентификатор константы; — тип константы; — значение константы.

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

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

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

Типизированную константу нельзя использовать в качестве значения при объявлении других констант или границ типа-диапазона.

15.1. КОНСТАНТЫ ПРОСТЫХ ТИПОВ И ТИПА STRING

Объявление таких констант обычно не вызывает трудностей, так как в качестве их значения используются нетипизированные константы или их идентификаторы.

Программирование Delphi

Все о программировании.

Главное меню

Как объявить константы в записи Delphi

Типы данных Record в Delphi представляют собой смешанный набор элементов. Каждый элемент называется полем. В объявлении типа Record поля определяются по имени и типу данных для каждого поля.

Запись с константами

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

Обратите внимание, что если Вы попробуете назначить какое-либо значение любому из полей MyRecord1, Вы получите ошибку компиляции:

Класс / статические константы в Delphi

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

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

(вы могли бы догадаться. Я знаю свою Java, но я довольно новичок в Delphi. )

в любом случае, я не хочу создавать новый экземпляр MySharedObject каждый раз, когда я создаю экземпляр MyObject, но я хочу, чтобы MySharedObject был доступен из каждого экземпляра MyObject. (На самом деле именно ведение журнала побудило меня попытаться понять это — я использую Log4D, и я хочу сохранить TLogLogger в качестве переменной класса для каждого класса, который имеет функции ведения журнала.)

каков самый аккуратный способ сделать что-то подобное в Delphi?

9 ответов

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

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

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

в прошлом году Hallvard Vassbotn написал в блоге о Delphi-hack, который я сделал для этого, он стал статьей из двух частей:

Да, это долгое чтение, но очень полезно.

В общем, я повторно использовал (устаревшую) запись VMT под названием vmtAutoTable в качестве переменной. Этот слот в VMT можно использовать для хранения любых 4-байтовое значение, но если вы хотите сохранить, вы всегда можете выделить запись со всеми полями, которые вы можете пожелать.

ключевые слова, которые вы ищете, — «class var» — это запуск блока переменных класса в объявлении класса. Вам нужно завершить блок «var», если вы хотите включить после него другие поля (в противном случае блок может быть завершен спецификатором «private», «public», «procedure» и т. д.). Например!—2

(Edit: я перечитал вопрос и переместил счетчик ссылок в TMyClass-поскольку вы не можете редактировать класс TMySharedObjectClass, который хотите поделиться, если он исходит от кого-то библиотека Эльзы)

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

Ну, это не красота, но отлично работает в Delphi 7:

Я использую его для создания объектов singletons.

для того, что я хочу сделать (константа частного класса), самое аккуратное решение, которое я могу придумать (на основе ответов до сих пор):


возможно, немного более объектно-ориентированным будет что-то вроде:

это могло бы иметь больше смысла, если бы было несколько таких констант класса.

два вопроса, я думаю, что нужно ответить, прежде чем придумать «идеального» решения..

  • во-первых, является ли tloglogger потокобезопасным. Может ли один и тот же TLogLogger вызываться из нескольких потоков без звонки на «syncronize»? Даже если это так, следующее может по-прежнему применяться
  • являются ли переменные класса потоковыми или действительно глобальными?
  • если переменные класса действительно глобальны, а tloglogger не является потокобезопасным, вам может быть лучше чтобы использовать unit-global threadvar для хранения TLogLogger (насколько мне не нравится использовать «глобальные» vars в любой форме), например

Edit: кажется, что переменные класса хранятся глобально, а не экземпляр на поток. См.этот вопрос для сведения.

в Delphi статические переменные реализованы как переменные типы констант :)

Это может ввести в заблуждение.

и да, еще одна возможность-использовать глобальную переменную в implementation часть вашего модуля.

это работает только в том случае, если переключатель компилятора «Assignable Consts» включен, глобально или с <$J+>синтаксис (TNX Lars).

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

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

Язык delphi. переменные, константы и их типы

Лк 2. События Delphi

Операционная система Windows — многозадачная, т.е. несколько программ в ней могут функционировать одновременно. Когда, например, мы щёлкаем по кнопке в окне нашей программы, система Windows определяет, что произошло событие именно в нашей программе, и посылает ей сообщение об этом. Наша программа должна соответствующим образом отреагировать на него. Для этого мы, как программисты, должны написать код-обработчик этого события. Таким образом, структура программы для Windows представляет собой набор подпрограмм, каждая из которых ответственна за обработку конкретного события и вызывается только при его возникновении. Удобство Delphi состоит в том, что мы избавлены от необходимости получать сообщения от Windows сами, Delphi это делает за нас. Каждый компонент имеет впечатляющий набор событий, на которые он может реагировать. Программист сам определяет, какие события в программе требуется обрабатывать.

Откройте наш проект из предыдущего урока. Щелкните на компоненте Edit1. Он появится в Инспекторе объектов. Посмотрите: в Инспекторе объектов две вкладки: Properties (свойства) и Events (события). Перейдите на вкладку Events. Чтобы создать обработчик нужного события, нужно дважды кликнуть по нему мышкой. А если раскрыть выпадающий список, в нём будут находиться уже готовые обработчики, которые могут подходить для этого компонента. Таким образом, один обработчик может вызываться для обработки событий нескольких компонентов.

Изменим нашу программу так, чтобы текст на форме появлялся прямо в момент его ввода. В момент ввода у Edit1 меняется свойство Text — в нём появляется новая буква! Значит, воспользуемся событием onChange (change — изменение (англ.)), которое и происходит в этот момент. Итак:

1. Кликаем дважды по onChange, и оказываемся внутри только что созданного обработчика.

2. Присваиваем свойству Caption компонента Label1 значение свойства Textкомпонента Edit1, то есть делаем то же, что и в прошлом уроке: Label1.Caption := Edit1.Text;Или просто копируем из обработчика нажатия кнопки.

3. Запускаем программу, всё работает. Как видим, всё очень просто.

Теперь рассмотрим событие onClick, это событие возникает при щелчке мышкой на компоненте. Воспользуемся им, чтобы очищать строку ввода от уже введённых символов. В обработчике нужно присвоить свойству Text значение пустой строки. Строка в Delphi образуется заключением текста в одинарные кавычки (находятся на кнопке Э): ‘Так в Delphi образуется строка’.Значит, пустая строка — это кавычки без текста: ». Не должно быть даже пробела, иначе он окажется в строке ввода: Edit1.Text:=»;Есть другой способ, воспользоваться специально предназначенным для этого методом компонента Edit, который так и называется Clear (очистка англ.):Edit1.Clear;Но подумайте о пользователе, который будет работать с вашей программой. Ему должно быть удобно. Если при вводе текста он захочет что-то исправить, и щёлкнет мышкой в том месте текста, где нужно внести изменение?! И всё сотрётся! Поэтому лучше использовать событие onEnter, которое происходит, когда вы входите в него и компонент получает фокус ввода, или использовать для очистки специальную кнопку и её событие onClick. Конечно, у каждого компонента свой набор событий. Мы познакомились с тремя из них:

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

  • onExit — возникает, когдакомпонент теряет фокус ввода;
  • onDblClick — возникает при двойномщелчке мышкой по компоненту;
  • onKeyDown — когда при нажатии накнопку на клавиатуре она оказалась в нижнем положении;
  • onKeyUp — когда при отпусканииклавиатурной кнопки она оказалась в верхнем положении;
  • onKeyPress — возникает при нажатиина клавиатурную кнопку. От событийonKeyDown и onKeyUp оноотличается типом используемого параметра Key ;
  • onMouseDown — когда при нажатиикнопки мышки она оказалась в нижнем положении;
  • onMouseUp — когда при отпусканиикнопки мышки она оказалась в верхнем положении;
  • onMouseMove — возникает приперемещении указателя мышки над

В начале работы любой программы происходит очень важное событие событие нашего основного компонента — Формы, onCreate. Оно происходит перед появлением Формы на экране. Это событие используется для задания свойств тех элементов программы, которые нуждаются в настройке, например, размеры и положение Формы на экране. Если вы захотите сделать невидимую программу, можно приравнять нулю ширину Width и высоту Height Формы. На этапе проектирования сделать этого нельзя, т.к. это помешает работе, поэтому делаем это по событию onCreate:
Form1.W >Form1.Height := 0;
Дополнительно нужно убрать и заголовок Формы, выбрав в Инспекторе Объектов параметр BorderStyle равным None. Теперь Форма на экране не появится. Единственным визуальным признаком останется появление её значка на панели задач. В дальнейшем я расскажу, как избавиться и от него

Язык Delphi. Переменные, константы и их типы

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

Любая величина в Delphi может быть постоянной или переменной. Её имя (идентификатор) может состоять из комбинации латинских букв, цифр и знака подчёркивания, и начинаться не с цифры. При этом регистр символов значения не имеет.

Место описания данных в программе — вне логических блоков begin / end. В модуле перед ключевым словом implementation есть блок описания:

var
Form1: TForm1;
Именно здесь, начиная со следующей строки, удобно объявлять глобальные переменные и константы. Как видим, одна (Form1) уже есть! Команда объявления переменных в языке Delphi: var имя_переменной : тип_переменной ;
Слово var — ключевое. Именем может быть любой идентификатор, если он не был описан ранее и не является одним из ключевых или зарезервированных слов языка Delphi. Если нужно описать несколько переменных одного типа, то их перечисляют, отделяя запятой:

var A, B, C : Integer;

Если несколько описаний следуют друг за другом, то ключевое слово var повторно можно не указывать:
var A, B : Integer;C, D : String;

Постоянную величину иначе называют константой. Конечно, в программе можно использовать числа и строки непосредственно: 3.1415 или ‘Это значение числа пи’, но иногда удобнее присвоить их идентификатору. Описание констант аналогично описанию переменных, но используется ключевое слово const, за именем идентификатора следует тип, затем знак равенства и его значение. Причём тип константы допускается не указывать:
const pi=3.1415 ;
ZnakPi : String =’Это значение числа пи’;
К слову, константа Pi встроенная в Delphi, то есть для того чтобы использовать в Delphi число 3,1415… в расчётах, нужно просто присвоить встроенную константу Pi переменной типа Real или просто использовать непосредственно в выражениях.

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

Строкой называется последовательность символов, заключённая в одиночные кавычки:’это текстовая строка’

Если текст должен содержать сам символ кавычки, то его надо повторить дважды: ‘это » — символ одиночной кавычки’

Строка может быть и пустой, не содержащей символов. Тогда она состоит из двух идущих друг за другом без пробела кавычек. Естественно, строка может состоять и только из одних пробелов.
Самый популярный строковый тип — String. Строка типа String может содержать переменное количество символов объёмом до 2 Гбайт. Если нужно ограничить размер строки фиксированным значением, то после ключевого слова String в квадратных скобках указывается число, определяющее количество символов в строке: String[50]. Одиночный символ имеет тип Char и записывается в виде знака в одиночных кавычках: ‘a’. Есть символы, которые на экране отобразить невозможно, например, символ конца строки (равен #13), символ переноса строки (равен #10). Такие символы записываются в виде их числового кода (в кодировке ANSI), перед которым стоит знак #. Например, #0.
Наконец, существуют так называемые нуль-терминированные строки. Отсчёт символов в таких строках начинается с нуля, а заканчивается символом с кодом 0 (#0). Такие строки имеют тип PChar.

Числа бывают целые и дробные. В следующей таблице перечислены стандартные типы целых чисел и соответствующие им дипазоны допустимых значений.

Integer -2147483648.. +2147483647
Cardinal 0.. 4294967295
Shortint -128.. +127
Smallint -32768.. +32767
Int64 -263 .. +263-1
Byte 0.. +255
Word 0.. +65535

Наиболее удобным для использования в программах является тип Delphi Integer. Другие целые типы используются для уменьшения места, занимаемого данными в памяти компьютера.

Дробные числа имеют дробную часть, отделяемую десятичной точкой. Допускается использование символа e (или E), за которым следует число, указывающее, что левую часть нужно умножить на 10 в соответствующей степени: 5e25 — пять умножить на десять в двадцать пятой степени.
Ниже приведены стандартные типы дробных чисел и соответствующие им диапазоны допустимых значений. Для большинства типов указан диапазон положительных значений, однако допустимым является аналогичный диапазон отрицательных значений, а также число 0.

Real 5*10-324 .. 1.7*10308
Real48 2.9*10-39 .. 1.7*1038
Singl 1.5*10-45 .. 3.4*1038
Double 5*10-324 .. 1.7*10308
Extended 3.6*10-4951 .. 1.1*104932-1
Comp -263 .. +263-1
Currency 922337203685477.5807
Наиболееудобным для использования в программах является тип Delphi Real.Ему эквивилентен тип Double, но в будущем это может бытьизменено. Вычисления с дробными числами выполняются приближённо, заисключением типа Currency (финансовый), который предназначендля минимизации ошибок округления в бухгалтерских расчётах.

Следующим типом данных является логический Boolean, состоящий всего из двух значений: True(Истина) и False (Ложь). При этом TrueFalse.
Теперь, используя компоненты, их свойства и события, вводя собственные переменные, можно конструировать программы, содержащие вычисления. Осталось узнать, как вычисленное значение вывести на экран.
Про консольные программы я здесь не говорю! А в нормальных оконных Windows-приложениях это значение нужно поместить в какой-нибудь компонент, имеющий свойства Text или Caption. Это, например, такие компоненты как Label и Edit, да и сама Форма имеет свойство Caption, куда тоже можно выводить информацию. Однако, в Delphi информацию перед выводом, как правило, необходимо преобразовывать. Так как присвоение возможно только между переменными одного типа, то такая программа (не пытайтесь её исполнять):

var A, B, C: Integer ;
begin
A := 5 ;
B := 10 ;
C := A+B ;
Label1.Caption := C ;
end ;


вызовет ошибку, так как свойство Caption имеет текстовый тип String, а использованные переменные — цифровой тип Integer. Значит, нужно преобразовать значение переменной C в текстовый тип. Для этого есть встроенная функция IntToStr. Строка в нашей программе, вызывавшая ошибку, должна выглядеть так: Label1.Caption := IntToStr(C) ; Такая программа, кроме показа числа 15, ни на что не способна. Мы должны научиться вводить в программу другие числа. Используем компоненты Edit. Введённые числа будут содержаться в свойстве Text этих компонентов. Расположим на форме два компонента Edit, один компонент Label и кнопку Button, по нажатию на которую и будем проводить вычисления. В компоненты Edit1 и Edit2будем вводить числа для суммирования. Чтобы переместиться в редактор кода, щёлкнем дважды по нашей кнопке Button1. Мы попадём прямо в сформированную для нас средой Delphi заготовку обработчика нажатия на кнопку, непосредственно между операторами begin и end. Напишем такой простой код:

procedure TForm1.Button1Click(Sender: TObject);
var A, B, C: Integer;//Не забудьте описание переменных
begin
//Начало кода:
A := Edit1.Text;
B := Edit2.Text;
C := A+B;
Label1.Caption := IntToStr(C);
//Конец кода
end ;

При попытке исполнить этот код Delphi покажет ошибки по аналогичной причине — переменные A и Bимеют цифровой тип Integer, а свойство Text — текстовый тип String. Исправить ошибки поможет встроенная функция StrToInt, выполняющая обратное преобразование — текст в целое число. Операторы присвоения переменным A и B должны выглядеть так:

A := StrToInt(Edit1.Text);
B := StrToInt(Edit2.Text);

В данном случае переменные A, B, C использовались для наглядности. Можно обойтись одной строчкой:

Аналогично, имеются функции и для преобразования в строку и обратно действительных чисел c плавающей (Floating англ.) запятой, имеющих тип Real. Для преобразования в строку — FloatToStr, обратно — StrToFloat.
Часто результаты вычислений, имеющие тип Delphi Real, имеют после запятой длинный хвост цифр. При выводе такой переменной в текстовом виде необходимо ограничить количество цифр после запятой.

Статьи к прочтению:

Delphi урок #1 | Основные типы переменных.

Похожие статьи:

Данные в компьютере можно рассматривать как ячейки памяти, имеющие свои имена (идентификаторы). Все данные в программе на языке Delphi должны быть…

Общий формат объявления переменных: [] [][=], [=],…, [=]; Необязательный элемент(необязательный элемент далее в записи форматов будет помещаться в…

Использование процедур и функций в Delphi

Скобки

Добавление скобок при вызове процедур и функций без параметров уже давно не является новинкой в Delphi, тем не менее, эта возможность мало известна. Эту возможность оценят по достоинству те программисты, которым приходится работать на двух языках (C++ и Delphi), так как им не нужно будет постоянно помнить о разнице в синтаксисе при вызове процедур и функций в разных языках. В Delphi оба варианта, приведенные ниже, считаются корректными.

Возможность перегрузки

Впервые концепция перегрузки процедур и функций была реализована в Delphi 4. Она позволяет иметь несколько различных процедур и функций с одинаковыми именами, но с разными списками параметров. Такие процедуры и функции должны быть описаны с применением директивы overload.

procedure Test (I: integer); overload;
procedure Test (S: string); overload;
procedure Test (D: double); overload;

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

Передача параметров

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

Передача параметров по значению

Этот режим передачи параметров применяется по умолчанию. Если параметр передается по значению, создается локальная копия данной переменной, которая и предоставляется для обработки в процедуру или функцию. Посмотрите на следующий пример:

procedure Test(s: string);

При вызове указанной процедуры будет создана копия передаваемой ей в качестве параметра строки s, с которой и будет работать процедура Test. При этом все внесенные в строку изменения никак не отразятся на исходной переменной s.

Однако это не относится к объектам. Например, если в функцию передается переменная (а точнее экземпляр объекта) TStringList, то в данном случае произойдет передача по ссылке (даже если это не указано явно). Этот способ передачи является у большинства самым излюбленным, но в тоже время является и самым не практичным, т.к. для выполнения метода выделяется дополнительная память для создания точной копией передаваемой переменой. Для решения этой проблемы следует использовать один из способов описанных ниже.

Передача параметров по ссылке

Pascal позволяет также передавать параметры в функции или процедуры по ссылке — такие параметры называются параметрами-переменными. Передача параметра по ссылке означает, что функция или процедура сможет изменить полученные значения параметров. Для передачи параметров по ссылке используется ключевое слово var, помещаемое в список параметров вызываемой процедуры или функции.

procedure ChangeMe(var x: longint);
begin
x := 2; // Параметр х изменен вызванной процедурой
end;

Вместо создания копии переменной x, ключевое слово var требует передачи адреса самой переменной x, что позволяет процедуре непосредственно изменять ее значение.

Передача параметров констант

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

procedure Test(const s: string );

Передача открытых массивов

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

function AddEmUp(A: array of integer): integer;

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

Для получения информации о фактически передаваемом массиве параметров в функции или процедуре могут использоваться функции High, Low и SizeOf.

Object Pascal также поддерживает тип array of const, который позволяет передавать в одном массиве данные различных типов. Синтаксис объявления функций или процедур, использующих такой массив для получения параметров, следующий:

procedure WhatHaveIGot( A: array of const );

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

procedure WhatHaveIGot( [‘Text’, 10, 5.5, @WhatHaveIGot, 3.14, true, ‘c’] );

При передаче функции или процедуре массива констант все передаваемые параметры компилятор неявно конвертирует в тип TVarRec. Тип данных TVarRec объявлен в модуле System следующим образом:

PVarRec = ^TVarRec;
TVarRec = record
case Byte of
vtInteger: (VInteger: Integer; VType: Byte);
vtBoolean: (VBoolean: Boolean);
vtChar: (VChar: Char);
vtExtended: (VExtended: PExtended);
vtString: (VString: PShortString);
vtPointer: (VPointer: Pointer);
vtPChar: (VPChar: PChar);
vtObject: (VObject: TObject);
vtClass: (VClass: TClass);
vtWideChar: (VWideChar: WideChar);
vtPWideChar: (VPWideChar: PWideChar);
vtAnsiString: (VAnsiString: Pointer);
vtCurrency: (VCurrency: PCurrency);
vtVariant: (VVariant: PVariant);
vtInterface: (VInterface: Pointer);
vtWideString: (VWideString: Pointer);
vtInt64: (VInt64: PInt64);
end;

Поле VType определяет тип содержащихся в данном экземпляре записи TVarRec данных и может принимать одно приведенных значений.


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

procedure WhatHaveIGot( A: array of const );
var
i: integer;
TypeStr: string;
begin
for i := Low(A) to High(A) do
begin
case A[i].VType of
vtInteger : TypeStr := ‘Integer’;
vtBoolean : TypeStr := ‘Boolean’;
vtChar : TypeStr := ‘Char’;
vtExtended : TypeStr := ‘Extended’;
vtString : TypeStr := ‘String’;
vtPointer : TypeStr := ‘Pointer’;
vtPChar : TypeStr := ‘PChar’;
vtObject : TypeStr := ‘Object’;
vt ;
vtW ;
vtPW ;
vtAnsiString : TypeStr := ‘AnsiString’;
vtCurrency : TypeStr := ‘Currency’;
vtVariant : TypeStr := ‘Variant’;
vtInterface : TypeStr := ‘Interface’;
vtW ;
vtInt64 : TypeStr := ‘Int64’;
end;
ShowMessage( Format( ‘Array item %d is a %s’, [i, TypeStr] ) );
end;
end;

Значения параметров по умолчанию

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

procedure HasDefVal( s: string; i: integer = 0 );

Подобное объявление означает, что процедура HasDefVal может быть вызвана двумя путями. В первом случае — как обычно, с указанием обоих параметров:

procedure HasDefVal( ‘Hello’, 26 );

Во втором случае можно задать только значение параметра s, а для параметра i использовать значение, установленное по умолчанию:

procedure HasDefVal( ‘Hello’ );

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

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

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

function Add( I1, I2: integer ): integer;
begin
Result := I1 + I2;
end;

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

function Add( I1, I2: integer; I3: integer = 0 ): integer;
begin
Result := I1 + I2 + I3;
end;

Директива

Директива <$X->запрещает вызов функций как процедур (с игнорированием возвращаемого результата). По умолчанию этот режим включен (<$X+>). Так вот, запомните, использование переменной Result недопустимо при сброшенном флажке опции Extended Syntax, расположенном во вкладке Compiler диалогового окна Project Options, или при указании директивы компилятора <$X->.

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

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

Заметки о Pascal, Delphi и Lazarus

Следует ожидать переводов разделов справочной системы Delphi, компиляций из учебников, переводы статей, «путевые заметки» и прочие интересности. Блог прежде всего ориентирован на студентов, но опытных людей я тоже буду рад видеть;-)

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

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

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

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

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

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

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

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

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

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

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

Типы целочисленных констант

Диапазон константы (шестнадцатеричный) Диапазон константы (десятичный) Тип Псевдоним
0-$FF 0-255 Byte UInt8
0-$FFFF 0-65535 Word UInt16
0-$FFFFFFFF 0-4294967295 Cardinal UInt32, LongWord
0-$FFFFFFFFFFFFFFFF 0-18446744073709551615 UInt64
-$80 — $7F -128 — 127 ShortInt Int8
-$8000 — $7FFF -32768 — 32767 SmallInt Int16
-$80000000 — $7FFFFFFF -2147483648 — 2147483647 Integer Int32, LongInt
-$8000000000000000 — $7FFFFFFFFFFFFFFF -9223372036854775808 — 9223372036854775807 Int64

32-битный стандартный целочисленный тип

Диапазон константы (шестнадцатеричный) Диапазон константы (десятичный) Тип Эквивалент
-$80000000 — $7FFFFFFF -2147483648 — 2147483647 NativeInt Integer
0 — $FFFFFFFF 0 — 4294967295 NativeUInt Cardinal

64-битный стандартный целочисленный тип

Диапазон константы (шестнадцатеричный) Диапазон константы (десятичный) Тип Эквивалент
-$8000000000000000 — $7FFFFFFFFFFFFFFF -9223372036854775808 — 9223372036854775807 NativeInt Int64
0 — $FFFFFFFFFFFFFFFF 0 — 18446744073709551615 NativeUInt UInt64

Далее приведены примеры объявления констант:

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

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

Abs High Low Pred Succ
Chr Length Odd Round Swap
Hi Lo Ord SizeOf Trunc

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

Примеры константных выражений:

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Различия между изменяемыми константами и инициализированными переменными:

  • Изменяемые константы могут быть объявлены глобально или локально в процедурах, функциях или методах;
  • Инициализированные переменные можно объявить только глобально.
  • При попытке присваивания значения инициализированным переменным внутри процедур или методов возникает ошибка компиляции.

Константы

В языке Delphi существует два вида констант: обычные и именованные. Обычная константа — это целое или дробное число, строка символов или отдельный символ, логическое значение.

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

Ниже приведены примеры числовых констант:

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

Таблица 1.3. Примеры записи дробных чисел

Форма с плавающей точкой

  • 1 000 000
  • -123.452
  • 0,0056712
  • 1х10 6
  • -1,23452×10 2
  • 5,6712х10 -3
  • 1 .0000000000Е+06
  • -1 .2345200000Е+02
  • 5,6712000000Е-03

Строковые и символьные константы

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

‘Язык программирования Delphi 1 ‘Delphi 7’

Здесь следует обратить внимание на константу ‘ 2.4’. Это именно символьная константа, т. е. строка символов, которая изображает число «две целые четыре десятых», а не число 2,4.

Логическое высказывание (выражение) может быть либо истинно, либо ложно. Истине соответствует константа True, значению «ложь» — константа False.

Именованная константа — это имя (идентификатор), которое в программе используется вместо самой константы.

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

  • · константа — имя константы;
  • · значение — значение константы.


Именованные константы объявляются в программе в разделе объявления констант, который начинается словом const. Ниже приведен пример объявления именованных констант (целой, строковой и дробной).

Title = ‘Скорость бега’;

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

В отличие от переменной, при объявлении константы тип явно не указывают. Тип константы определяется ее видом, например:

  • · 125 — константа целого типа;
  • · 0.0 — константа вещественного типа;
  • · ‘ выполнить ‘ — строковая константа;

Класс / Статические константы в Delphi

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

Или, если MySharedObject требуется более сложная инициализация, в Java я мог бы создать экземпляр и инициализировать его в статическом блоке инициализации.

(Вы, наверное, догадались . Я знаю, что мой Java, но я довольно новыми для Delphi . )

Во всяком случае, я не хочу, чтобы создавать новый MySharedObject каждый раз, когда я создаю экземпляр MyObject, но я хочу MySharedObject быть доступно из каждого экземпляра MyObject. (Это на самом деле протоколирование, что побудило меня, чтобы попытаться понять это — я использую Log4D и я хочу, чтобы сохранить TLogLogger как переменный класс для каждого класса, который каротажная функциональность.)

Что опрятный способ сделать что-то вроде этого в Delphi?

delphi — Класс/Статические константы в Delphi

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

Или, если MySharedObject нуждался в более сложной инициализации, в Java я мог бы создать и инициализировать его в статическом блоке инициализации.

(Возможно, вы догадались. Я знаю свою Java, но я довольно новичок в Delphi. )

Во всяком случае, я не хочу создавать экземпляр нового MySharedObject каждый раз, когда создаю экземпляр MyObject, но я хочу, чтобы MySharedObject был доступен из каждого экземпляра MyObject. (Фактически это протоколирование, которое побудило меня попытаться понять это — я использую Log4D, и я хочу хранить TLogLogger как переменную класса для каждого класса, имеющего функции ведения журнала.)

Какой самый простой способ сделать что-то подобное в Delphi?

    8 9
  • 28 мар 2020 2020-03-28 19:08:17
  • MB.

9 ответов

В Delphi статические переменные реализуются как константы переменных типов:)

Это может быть несколько вводить в заблуждение.

И да, другая возможность — использовать глобальную переменную в части implementation вашего модуля.

Это работает, только если включен компилятор «Assignable Consts», глобально или с синтаксисом <$J+>(tnx Lars).

  • 28 мар 2020 2020-03-28 19:08:20
  • squadette

До версии 7 у Delphi не было статических переменных, вам нужно было бы использовать глобальную переменную.

Чтобы сделать его как можно более приватным, поместите его в раздел implementation вашего устройства.

  • 28 мар 2020 2020-03-28 19:08:20
  • CL.

Два вопроса, на которые я думаю, должны ответить, прежде чем придумать «идеальное» решение.

  • Во-первых, является ли TLogLogger потокобезопасным. Может ли тот же TLogLogger быть вызван из нескольких потоков без вызовов на «syncronize»? Даже если это так, все еще могут применяться:
  • Являются ли переменные класса нитями в области видимости или действительно глобальными?
  • Если переменные класса действительно глобальны, а TLogLogger не является потокобезопасным, возможно, вам лучше использовать единый глобальный threadvar для хранения TLogLogger (насколько мне не нравится использование «глобальных» варов в любой форме), например

Изменить: Кажется, что переменные класса хранятся глобально, а не экземпляр на поток. Подробнее см. этот вопрос.

  • 28 мар 2020 2020-03-28 19:08:19
  • Graza

Для того, что я хочу сделать (константа частного класса), самым ясным решением, которое я могу предложить (на основе ответов до сих пор), является:

Возможно, более объектно-ориентированное будет выглядеть примерно так:

Это может иметь большее значение, если существует несколько таких констант класса.

  • 28 мар 2020 2020-03-28 19:08:19
  • MB.

В прошлом году, Hallvard Vassbotn blogged о Delphi-хак, который я сделал для этого, стал двухкомпонентной статьей:

Да, это долго читается, но очень полезно.

Итак, я повторно использовал (устаревшую) запись VMT, названную vmtAutoTable в качестве переменной. Этот слот в VMT можно использовать для хранения любого 4-байтового значения, но если вы хотите сохранить, вы всегда можете выделить запись со всеми полями, которые вы могли бы пожелать.

  • 28 мар 2020 2020-03-28 19:08:19
  • PatrickvL

Ключевыми словами, которые вы ищете, являются «класс var» — это начинает блок переменных класса в объявлении класса. Вам нужно закончить блок с помощью «var», если вы хотите включить в него другие поля (в противном случае блок может быть завершен спецификатором «private», «public», «procedure» и т.д.). Например,

(Edit: я перечитаю вопрос и переместил ссылку в TMyClass — так как вы не сможете редактировать класс TMySharedObjectClass, который хотите разделить, если он исходит от другой библиотеки)

Обратите внимание, что приведенное выше не является потокобезопасным, и могут быть лучшие способы подсчета ссылок (например, использование интерфейсов), но это простой пример, который должен вас запустить. Обратите внимание, что TMySharedObjectClass можно заменить на TLogLogger или что угодно.

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