Mod — Ключевое слово Delphi


Mod — Ключевое слово Delphi

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

будет равен не 1, как в случае последовательного выполнения, а 6.2 .

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

Вот теперь X будет равен 1.

Помимо четырёх математических действий в Delphi доступно множество математических функций, таких, например, как тигонометрические, логарифмические, и т.д. Они становятся доступны в программе после добавления в секцию Interface uses модуля Math. Их описание также можно найти в модуле Math.pas (можно найти воспользовавшись поиском Windows). Многие из них можно реализовать и самому, но встроенные функции наверняка будут работать быстрее и лучше, т.к. написаны на языке ассемблера.

Логические выражения

Операторы Delphi

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

  • оператора присваивания
  • условного оператора
  • оператора цикла

С оператором присваивания «:=» мы уже знакомились в уроке Delphi 2. Он работает следующим образом. Переменная, стоящая в левой части оператора, становится равной той величине, которая находится справа. Типы этих величин должны совпадать. В выражении, стоящем справа, также может использоваться переменная, стоящая слева. С математической точки зрения это неправильно, но в программировании это означает, что из ячейки памяти берётся исходное значение, производятся вычисления, и результат записывается в эту же ячейку памяти, затирая прежнее значение. Пример:

В начале фрагмента переменная A равна 3, а в конце -25.

Условный оператор позволяет изменить порядок выполнения операторов в зависимости от выполнения некоторого условия. Вот как он записывается:

if условие then действие else альтернатива ;

Слова if (если), then (тогда), else (иначе) — зарезервированные. Действие и else альтернатива — это любые операторы Delphi, или несколько операторов, заключённых в логические скобки begin/end, или вызов подпрограммы. Если условие истинно, то выполняется действие , если ложно, то выполняется альтернатива .
Условие представляет собой логическое выражение. В нём сравниваются значения выражений (в том числе также и логических), вызов функций, возвращающих значения типа Boolean, и комбинирование этих значений с помощью логических операций:

Знак
операции
Название операции Логические операции могут комбинироваться с помощью связок:
and (логическое И)
or (логическое ИЛИ)
xor (исключающее ИЛИ)
Для некоторых типов данных есть дополнительные операции. Например, для множеств — оператор in, которая проверяет, входит ли некоторое значение в множество. Например:
X := [2, 4, 5, 7, 8, 10] ;
Выражение 2 in X истинно (имеет значение true);
Выражение 6 in X ложно (имеет значение false);
= Равно
<> Не равно
> Больше
= Больше или равно
действие ;
Счётчик — это переменная, которая должна быть объявлена перед логическим блоком, в котором оператор цикла расположен, и её тип должен относиться к одному из перечислимых типов, обычно Integer.
Выражение-1 и выражение-2 могут быть как константой или идентификатором, так и вызовом функции.
Действие — один или несколько операторов Delphi. Если это группа операторов, то они должны быть заключены в логические скобки begin/end.
В начале работы оператора переменная-счётчик получает значение выражения-1 . Если при этом значение счётчика окажется меньше или равно значению выражения-2 , то выполняются операторы, входящие в действие . Это и есть один цикл. Затем переменная-счётчик принимает значение, следующее за текущим, и начинается новый цикл, то есть сравнение счётчика и выражения-2 , выполнение действия , и так далее, до тех пор, пока значение переменной-счётчика не превысит значение выражения-2 .
Возможна работа оператора цикла, при котором переменная-счётчик будет не увеличиваться, а уменьшаться. В этом случае ключевое слово to заменяется на downto:
for счётчик := выражение-1 downto выражение-2 do действие ;
Соответственно, выражение-1 должно быть больше или равно выражению-2 .

Условный оператор цикла удобно использовать в том случае, когда количество повторений заранее не известно:
while условие do
тело цикла ;
Этот цикл будет выполняться до тех пор, пока истинно условие (логическое выражение, возвращающее значение типа Boolean). При этом если это выражение сразу равно false, тело цикла не будет выполнено ни разу.
Нужно очень внимательно следить за написанием условия и контролем завершения цикла, так как в результате ошибки цикл while будет повторяться бесконечное количество раз, что приведёт к «зацикливанию» и «зависанию» программы.

Условный оператор повторения сначала выполняет тело цикла , а затем уже проверяет выполнение условия :
repeat
тело цикла
until условие ;
Таким образом, этот вариант цикла гарантирует, что тело цикла будет выполнен по крайней мере один раз. И будет выполняться до тех пор, пока условие не станет истинным (т.е. true). Стоит отметить, что это единственный оператор Delphi, в котором тело цикла не требуется заключать в логические скобки begin/end. Начало и конец тела цикла определяются по ключевым словам repeat и until.

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

  • команда прерывания цикла
  • команда продолжения цикла

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

Справедливости ради стоит рассказать об ещё одном операторе, позволяющем изменить последовательность выполнения программы. Это оператор перехода:
goto метка ;
В качестве метки может использоваться любой допустимый идентификатор или число в диапазоне от 0 до 9999. Метку предварительно необходимо объявить в разделе описания переменных, но с помощью не ключевого слова var, а ключевого слова label:
label меткa ;
или
label список меток ;

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

Из этого примера видно, что оператор end ; завершающий программу, никогда не будет выполнен, то есть программа зациклится. Именно поэтому, вообще, использование оператора перехода является плохим стилем программирования, и без его использования вполне можно обойтись использованием условных операторов и операторов цикла. Единственный случай, когда использование оператора goto может быть оправдано — это выход из нескольких вложенных циклов, что иначе требует применения нескольких операторов Break.

Пример. Сортировка одномерного массива

Рассматриваются процедуры программы, приводятся подробные комментарии. Также можно скачать проект в виде архива. Цикл while и операторы goto использованы только для демонстрации работы с ними. Здесь — более правильный вариант с применением цикла repeat и оператора break.
Параллельно замечу, что сортировка массива «методом пузырька» — неэффективный метод. Количество итераций (проходов цикла) растёт гораздо быстрее роста количества элементов, . Сортировка 50 000 элементов выполняется на моём компьютере секунд за пять. Но сортировка 100 000 — не за 10 секунд, а около 35 секунд! Можете поэкспериментировать, для этого достаточно во 2 варианте установить в описании массива нужное количество элементов.

Сортировка массивов — типичная задача, где используются циклы. Существует множество методов сортировки массивов. В рассматриваемом примере рассматривается сортировка массива методом «пузырька». В ручном режиме работы программы можно видеть, как числа поднимаются вверх по массиву, подобно всплывающему пузырьку, и становится понятным такое название метода.

type Point=Record //Объявляем тип: Запись
n, digit: Integer; //номер и значение: целые числа
end;
var
Form1: TForm1;
tab: array[1..20] of Point; //Создаём массив записей типа Point

procedure TForm1.FormCreate(Sender: TObject);
begin
StringGr ;//Инициализируем столбцы таблицы
StringGr ;
end;

procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
begin
Randomize; //Инициализируем «случайную» процедуру
For i:=1 to StringGrid1.RowCount-1 do
begin
tab[i].n:=i; //Присваиваем ячейкам массива порядковые номера
tab[i].digit:=Random(100); //Присваиваем ячейкам массива случайные значения в диапазоне от 0 до 100
StringGr ; //Нумеруем таблицу
StringGr >
end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
Application.Terminate; //Процедура завершения программы
end;

procedure TForm1.Button2Click(Sender: TObject);
var i, n: Integer; //переменные цикла
Sort: Boolean; //Переменная — признак окончания сортировки
Obmen: Point; //Служебная переменная перестановки значений массива
Label manual1, manual2; //Метки операторов перехода
begin
Sort:=True; //Признак неотсортированности массива
n:=StringGrid1.RowCount-1; //Количество строк в таблице (без заголовка)
if RadioButton1.Checked then goto manual1; //Переход на ручной режим
while(Sort=True) do //Начало автоматического режима: в предыдущем цикле было событие сортировки
manual1: //Начало ручного режима
begin
Sort:=False; //Допустим, что массив уже отсортирован (сортировка не нужна)
for i:=1 to n-1 do //Опять проверяем все значения от 1 до n
if(tab[i+1].digit
begin //Если неверно, то переставляем соседние значения:
Obmen:=tab[i]; //1. Сохраняем одно из значений
tab[i]:=tab[i+1]; //2. На его место переписываем соседнее значение
tab[i+1]:=Obmen; //3. Переписываем сохранённое значение на новое место
Sort:=True; //Признак того, что состоялось событие сортировки
end;
if RadioButton1.Checked then goto manual2; //Пропускаем переход к новому циклу автоматического режима
end; //Здесь заканчивается очередной цикл авторежима и осуществляется переход к новому
manual2:
for i:=1 to n do //Переписываем отсортированные значения массива в таблицу
begin
StringGr ;
StringGr >
end;
end;

Есть возможность немного улучшить процедуру сортировки, что ускорит её примерно на четверть. Дело в том, что после каждого завершённого цикла наибольший ещё неотсортированный элемент перемещается на своё место в низ таблицы. То есть, очередной k-й цикл уже последние k элементов может не просматривать. Для реализации этого нужно ввести переменную — счётчик циклов, и отнять её от переменной цикла. При этом те же 100 000 элементов сортируются уже за 24 секунды! Реализацию этого варианта предоставляю читателю, ввиду его крайней простоты.

Mod — Ключевое слово Delphi

Прежде чем перейдем к дальнейшему описанию языка Delphi, формально опреде-
лим несколько терминов. Во-первых, это слово «идентификатор». Идентификатор —
это строка символов, используемая для именования некоторого элемента программы.
Это может быть переменная, запись, функция, процедура или конструкция более вы-
сокого уровня, например сама программа.
Идентификатор может иметь любую длину, однако в языке Delphi только первые
его 255 символов являются значимыми (что более чем достаточно!). Идентификатор
должен начинаться с буквы или символа подчеркивания (_) и не может содержать
пробелов. После первого символа идентификатора можно использовать буквы, цифры
и символы подчеркивания. Как и в зарезервированных словах, в идентификаторах
можно использовать как строчные, так и прописные буквы (компилятор их не разли-
чает). Приведенные ниже идентификаторы означают одно и то же.

CalculateValue
calculateValue
calculatevalue
CALCULATEVALUE
Ключевые слова не могут быть идентификаторами.
Далее рассмотрим лексемы. Это минимальные значимые единицы текста в про-
грамме. Они представлены такими категориями, как специальные символы, иденти-
фикаторы, метки, числа и строковые константы.
Программа, написанная на языке Delphi, состоит из лексем и разделителей, при-
чем разделитель представляет собой пробел или комментарий. Две соседних лексемы,
если они представляют собой зарезервированное слово, идентификатор, метку или
число, должны быть отделены друг от друга одним или несколькими разделителями.
В Delphi используются следующие подмножества набора символов кода ASCII.
• Буквы английского алфавита от А до Z и от а до z.
• Цифры — арабские цифры от 0 до 9.
• Шестнадцатеричные цифры — арабские цифры от 0 до 9, буквы от А до F и бу-
квы от а до f.
• Пробелы — символ пробела ($32) и все управляющие символы кода ASCII ($0-$31),
включая символ конца строки или символ возврата каретки ($13). Это шестна-
дцатеричные числа, так как перед ними стоит символ доллара «$».
Теперь определим смысл слова «выражение». Это фрагмент языка программирова-
ния, представляющий способ вычисления некоторого значения.
И наконец, определим смысл слов «операнд» и «оператор».
Операнд — часть выражения, над которым производятся операции. Например,
в выражении, присваивающем А сумму в и с (А := В+С;), А, в, с являются операн-
дами, а над значениями, представленными идентификаторами А й в , производится
операция суммирования. Идентификатор — это строка символов, используемая для именования некоторого
элемента программы.
Лексемы — это минимальные значимые единицы текста в программе.
Выражение — это фрагмент языка программирования, представляющий способ вы-
числения некоторого значения.
Операнд — часть выражения, над которым производятся операции.
Оператор — действие, которое может быть выполнено над одним или несколькими
операндами.
Оператор — действие, которое может быть выполнено над одним или несколькими
операндами. Если обратиться к вышеприведенному примеру, то оператором является
знак плюс (+). Хотя в некоторых случаях оператором можно назвать целое выражение,
заканчивающееся точкой с запятой. Более правильно такие операторы надо называть
структурированными операторами. Например, выражение
while i:=0 to 10 do x := i ;
можно назвать оператором, так как здесь выполняется операция цикла над пере-
менной X.
Теперь можно переходить непосредственно к ключевым словам. Обычно ключевые
слова пишутся строчными буквами, но Delphi безразличен к регистру клавиатуры, по-
этому можно использовать в своей программе как строчные (нижний регистр), так
и прописные (верхний регистр) буквы. Я рекомендую использовать какой-то один
стиль написания, например, тот, к которому вы уже привыкли. Но если вы только на-
чинаете программировать, то лучше использовать общепринятые правила и писать
ключевые слова строчными буквами. В табл. 3.1 приведен перечень всех ключевых
слов с кратким комментарием.
Таблица 3.1. Ключевые слова
Ключевое слово Комментарий
and Булев оператор И
array Массив
as Используется при проверке соответствия типов, определяет объект как операнд
asm Используется для выделения ассемблерного кода
begin Начало блока
case Оператор выбора. Используется при выборе из многих вариантов
class Определяет тип «класс»
const Определяет константы, т.е. неизменяемые переменные. Однако в Delphi есть
режим, допускающий изменение констант в теле программы
constructor Специальный метод класса, необходимый для создания и инициализации
экземпляра класса (объекта)
destructor Специальный метод класса, необходимый для разрушения объекта
d i s p i n t e r f a c e Определяет тип интерфейса
div Целочисленное деление
do Определяет начало исполнимой части в операторах цикла, конструкции
t r y . . . except и в операторе w i t h
downto Определяет направление итерации в операторе f o r
else Используется в операторах выбора case, условном операторе i f и в операторе
проверки исключений t r y . . .except
end
except
e x p o r t s
f i l e
f i n a l i z a t i o n
f i n a l l y
for
f u n c t i o n
goto
i f
implementation
i n
i n h e r i t e d
i n i t i a l i z a t i o n
i n l i n e
i n t e r f a c e
i s
l a b e l
l i b r a r y
mod
n i l
not
o b j e c t
of
or
out
Обычно используется совместно с ключевым словом begin и отмечает конец
блока. Также ставится в конце описания типа, например класса или записи
Используется в операторе проверки исключений t r y . . . except
Определяет список экспортируемых процедур, функций и переменных
Устанавливает тип переменной как файл. Используется при работе с файлами
Определяет начало раздела, который в программе всегда выполняется
последним
Используется в операторе проверки исключений t r y . . . f i n a l l y
Используется в операторах цикла f o r . . . to и f o r . . .downto
Используется при объявлении функций
Переход на метку
Используется в операторах выбора i f . . . then и i f . . . then. . .else
Определяет раздел реализации, в котором находятся описания процедур,
функций, методов и коды разрабатываемой программы
После этого ключевого слова может указываться путь к необходимому модулю.
Также используется при работе с множествами
Дословно можно перевести как «унаследованный». Используется при работе
с классами, поддерживая возможности полиморфизма
Определяет раздел инициализации, который всегда располагается перед
разделом f i n a l i z a t i o n . Если раздела f i n a l i z a t i o n нет, то раздел
инициализации находится перед завершением программы. Выполняется сразу
после запуска программы, перед всеми другими операторами. Обычно
используется для инициализации переменных
Используется при работе с ассемблерным кодом. Устаревшее ключевое слово
к применению не рекомендуется
Определяет тип интерфейса. Используется при опережающем объявлении
интерфейса
Используется при проверке типов
Метка. Используется совместно с ключевым словом goto. Может быть
выражена любым идентификатором или числом от 0 до 9999
Директива-напоминание или рекомендательная директива. Используется
наравне с директивами p l a t f o rm и deprecated для напоминания об
особенностях стандартных типов, методов или модулей. Во время компиляции
вызывает появление предупреждающего сообщения
Остаток от деления целых чисел
Специальная константа, которая может быть присвоена любому указателю,
после чего считается, что указатель не ссылается ни на что
Булев оператор отрицания
Используется как альтернатива слову class. Сохранено в языке для
совместимости со старыми версиями. Не рекомендуется к использованию
Используется во многих операторах как связующее ключевое слово
Булев оператор ИЛИ
Используется при объявлении параметров процедуры, функции или метода.
Предупреждает о том, что данный параметр используется только для
выдачи значений
packed
p r o c e d u r e
program
p r o p e r t y
r a i s e
r e c o r d
r e p e a t
r e s o u r c e s t r i n g
s e a l e d
set
shl
s h r
s t r i n g
then
t h r e a d v a r
t o
t r y
type
u n i t
u n t i l
uses
var
while
w i t h
xor
Используется для более плотного размещения данных в структурированных
типах (массивы, множества, записи, файлы, классы)
Используется при объявлении процедур
Определяет имя программы, которое должно быть выражено
идентификатором
Используется при объявлении свойств
Используется при генерации исключений
Определяет тип записи
Используется в операторе цикла repeat. . . u n t i l
Определяет раздел объявления ресурсов
Используется при объявлении класса, запрещая наследование данного класса
Ключевое слово для объявления множества
Логический оператор сдвига влево
Логический оператор сдвига вправо
Используется при объявлении строковых типов
Используется в операторах i f . . . then и i f . . . t h e n . . .else
Используется при разработке многопоточных приложений
Используется в операторе f o r . . . t o
Используется в операторе проверки исключений t r y . . . f i n a l l y ,
t r y . . .except и в операторе выбора case
Определяет раздел объявления типов
Модуль. Обычно это функционально законченный фрагмент программы,
сохраняемый в файле с таким же именем
Используется в операторе repeat. . . u n t i l
Определяет раздел подключаемых модулей
Определяет раздел переменных
Используется в операторе w h i l e . . . do
Используется для определения идентификатора, который всегда записывается
с другими идентификаторами. Код получается более компактным и понятным
Булев оператор Исключающее ИЛИ
Есть еще несколько ключевых слов, о которых мы поговорим при изучении объектно-
ориентированного программирования и которые могут использоваться как директивы.
Именно эти ключевые слова выделяются жирным шрифтом в редакторе кода, хотя
кое-что может вызвать недоумение: почему, например, слово Break, которое в других
языках программирования является ключевым, в редакторе кодов не подсвечивается?
В Delphi это не ключевое слово, а процедура, и для нее существует отдельное описа-
ние в библиотеке. А процедура write не описана в библиотеках, так как ее код встро-
ен в компилятор. Сейчас мы не будем разбираться в этих тонкостях, а только отме-
тим, что все ключевые слова обычно пишутся строчными буквами, а процедуры
обычно начинаются с прописной буквы.
Написание идентификаторов также можно сделать нагляднее, если использовать слова,
отражающие назначение идентификатора, и начинать каждое слово с прописной буквы.
Например, идентификатор для счетчика символов можно написать так: SymbolCounter. Здесь слова использованы полностью, а разделение достигается за счет того, что второе
слово начинается с большой буквы. Каждый, кто будет читать программу, где использо-
ваны подобные идентификаторы, сможет понять ее без дополнительных комментариев.
Используйте это правило, и ваши программы станут понятнее и для вас самих. (К сожа-
лению, все идентификаторы должны писаться только английскими буквами, поэтому
учите английский, в настоящее время это язык общения программистов.)

Ключевое слово Delphi

Я изучаю Delphi, читаю книгу Марко Канту, и она супер полная. Это очень ясно, но я сомневаюсь в ключевом слове self . У меня уже есть опыт работы с ООП, и у меня есть основы этого. Мой вопрос очень прост. Можно ли сравнить ключевое слово self (Delphi) с ключевым словом this (Java)?

Когда я прочитал книгу о self используемой внутренней записи, я понял, что-то вроде self : Delphi = this : Java . Посмотрите на код, который я создал для проведения теста:

Я собираюсь отрезать большую часть кода, я просто показываю конструктор здесь:

Используя ключевое слово self здесь, я имею в виду символ записи , а не символ, переданный в методе. Правильно ли это использовать себя? Может ли это быть братом Java this ?

Mod — Ключевое слово Delphi

В первую очередь пошел искать в хелпе, не нашел (хотя узнал много интересного ^^), в яндексе тоже глухо. В книжках по делфи, которые мне попадались о сабже тоже нет упоминаний. Итак, что же делает ключевое слово «object»? Ссылки на документацию приветствуются, но и ответом «своими словами» не побрезгую.

ЗЫ В общем-то, какой-то конкретной цели не преследую, просто для повышения образованности.

Это устаревший способ работы с самодельными объектами. Теперь гораздо целесообразнее использовать class

> Это устаревший способ работы с самодельными объектами

Моё любопытсво все еще не удовлетворено :). Чем object отличается от class, что именно устарело. Попадался мне как то код с этим волшебным словом, так что хотелось бы понять что это из себя представляет.

Идеальное слово для описания всего.

Даже для искуственного интелекта.

> Desdechado © (03.03.07 17:06) [1]
> Это устаревший способ работы с самодельными объектами. Теперь гораздо целесообразнее использовать class

В Делфях классом считается все, что прождено от TObject. Но проблема в том, что нужно было объявить сам TObject в юните «system.pas», для чего и использовали ключевое слово языка Паскаль object. Ключевое слово class не является зарезервированным словом языка Паскаль, хотя поддерживается и зарезервировано сейчас почти всеми компиляторами (Delpi, FPC, Lazarus, Kylix, TNT).


> Чем object отличается от class, что именно устарело

object в общем-то позволяет создать статический объект. Подробнее о нем ты лучше прочитай в любом руководстве по Турбо-Паскалю 5.5-7.0, с тех пор ничего не изменилось. В Delphi object только для совместимости и поддерживается

Руководство щас погуглю.
А под статическим объектом понимается объект, все методы которого статические? А конструктор с деструктором присутствуют? (=

Servelat © (03.03.07 17:19) [6]
нет просто память под такой объект выделяется статически, то есть при загрузке программы в память, а не когда программист соизволит

> PEAKTOP © (03.03.07 17:14) [4]
TObject = class;
T >
купи «твикс». жуй. молчи. заодно почитай материалы по Object Pascal (тому, из которого упёрли концепцию обёектов в Turbo Pascal 5.5).

Собственно, вопрос закрыт; нашел у себя на винте UserGuide по BP70 (что прям удивительно, на русском), где тема полностью раскрыта, просвещаюсь. Всем спасибо за ответы.

Удобен тем, что содержит в себе идеи ООП (наследование) и не требует лишней работы и памяти. Посмотри, сколько всего делается и создается в конструкторе TObject! Если мне нужно будет использовать сотню-другую тысяч объектов, то выбор будет за object»ами, а не за классами, наверное.

> Если мне нужно будет использовать сотню-другую тысяч объектов,
> то выбор будет за object»ами, а не за классами, наверное.

Так и до record»a дойти не долго :))

> Ketmar © (03.03.07 17:34) [8]

> Loginov Dmitry © (03.03.07 18:58) [11]

Структурное программирование рулит. Я серьезно.


> Посмотри, сколько всего делается и создается в конструкторе
> TObject! Если мне нужно будет использовать сотню-другую
> тысяч объектов, то выбор будет за object»ами, а не за классами,
> наверное.

Гм. Наверное наооборот :-) class как раз под такие случаи и заточен :-)

> tesseract © (03.03.07 20:52) [14]

На пустых объектах/классах поэкспериментировал, 100000000 TObject»ов создано за 19 секунд и использовано 720 метров памяти, столько просто обджектов — за ноль секунд и использовано памяти метр с копейками. Если объекты буду содержать какие-то данные и выполнять какие-то действия, то и на сотне разницу почуствуем.

> использовано памяти метр с копейками

Сами-то в это верите?

> Если объекты буду содержать какие-то данные и выполнять
> какие-то действия, то и на сотне разницу почуствуем.

Или эта разница просто-напросто исчезнет.

> Сами-то в это верите?

Четырехзначная цифирь, начинается на один .

to PEAKTOP © (03.03.07 17:14) [4]:
Что за трава? Или это были грибы? :)))

to TUser © (03.03.07 21:04) [15]:
>На пустых объектах/классах поэкспериментировал
Угу, а производительность будем на «Hello, World!» мерять. :)
Пустой object занимает 0 байт, в отличие от наследника TObject, который занимает 4 минимум байта.

>Если объекты буду содержать какие-то данные и выполнять какие-то
>действия, то и на сотне разницу почуствуем.
Фиг. Если в object будет поле, допустим integer, вес уравняется. Преимуществ не будет почти никаких. При одинаковом количестве полей будут те самые 400 байт на сотне.

И вообще, что-то цифры подозрительные. Что там в коде-то?

TUser © (03.03.07 21:04) [15]

Тут такой момент — пустые объекты, как и пустые классы никому не нужны. Давай ты полные насоздаешь ?

33 секунды для объектов vs минута думанья и Out of memory в случае классов :) Объекты и классы содержали по два поля типа integer + то, что от TObject. Говорю же — объекты (те, которые экземпляры классов) память любят кушать. Больше, чем объекты, которые просто, т.е. типа record с наследованием.

> Говорю же — объекты (те, которые экземпляры классов) память
> любят кушать. Больше, чем объекты, которые просто, т.е.
> типа record с наследованием.

Ай-ай! Какая беда! 100000000 объектов всю память скушали!
Только нюансик один: что вообще в принципе можно делать с таким количеством объектов? Их же надо где-то индексировать (в массиве там, или в списке), это еще 400 метров памяти надо. Нужен метод доступа, поиска и т.п., что при таком количестве объектов (будь то object или class) будет выполняться катастрофически долго.
То есть пример со 100000000 объектов выглядет очень уж надуманным.

to TUser © (04.03.07 04:27) [21]:
>Говорю же — объекты (те, которые экземпляры классов) память любят
>кушать. Больше, чем объекты, которые просто, т.е. типа record с
>наследованием.
А вот мои подсчеты говорят, что памяти в результате понадобится одинаковое количество. Догадываетесь, почему? А времени, тут да, создание экземпляра класса требует чуть больше, т.к. экземпляру класса требуется инициализация, а у object её по-умолчанию нет, но это опять же, до тех пор пока там данных в нормальном количестве нет.

Поэтому еще раз говорю, что-то там не то с методикой. Код в студию.

Чтобы вопросов не возникало:

uses
SysUtils,
Windows;

type
Cls = class
a,b: integer;
end;

PObj = ^Obj;
Obj = object
private
a,b: integer;
end;

procedure AllocCls(count: integer);
var
i: integer;
begin
for i := 0 to Count — 1 do
Cls.Create;
end;

procedure AllocObj(count: integer);
var
i: integer;
o: PObj;
begin
for i := 0 to Count — 1 do
new(o);
end;

var
T1, T2, T3: Cardinal;
S1, S2, S3: Cardinal;
begin
T1 := GetTickCount;
S1 := GetHeapStatus.TotalAllocated;
AllocCls(10000000);
S2 := GetHeapStatus.TotalAllocated;
T2 := GetTickCount;
AllocObj(10000000);
S3 := GetHeapStatus.TotalAllocated;
T3 := GetTickCount;
writeln(Format(«%d %d», [T2-T1, S2-S1]));
writeln(Format(«%d %d», [T3-T2, S3-S2]));
readln;
end.

Результат (CoreDuo 6600 2.4 ГГц, RAM 2ГБ):
500 120000000
109 120000000

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

Но проблема в том, что нужно было объявить сам TObject в юните «system.pas», для чего и использовали ключевое слово языка Паскаль object

О как. Оказывается, object использовали для создания class. Вот так и возникают религии. Хвала всевышнему, объект придумавшему, ибо класс и экземпляр класса — суть порождение его. Во имя object, class и instance его! Аминь.

Я, наверное, еретик. бо у меня возник вопрос, откуда же в таком случае взялся сам object :0)

и если от record»а, то откуда взялся record? и так далее. )

to Virgo_Style © (04.03.07 12:29) [26]:
>откуда взялся record?
record был всегда :)

record придумал Вирт, а Вирта придумали мама с папой. выводы очевидны :)

хех
неужто настолько делать нефига людям что ещё не влом думать о такой архаике как object:)

> PEAKTOP © (03.03.07 19:03) [12]
расслабься. приведённый мной код — цитата из system.pas. советую перед тем, как вещать, таки читать генофонд. ну и — да, язык, о котором вещаешь, тоже выучить бы не помешало.

>>неужто настолько делать нефига людям что ещё не влом думать о такой архаике как object:)
что за наезды на обжект? фундаментальная штука. это класс придумка борланда, насколько помню в стандарте паскаля нет такого словечка:)

object — это отнюдь не архаика.

Во-первых, без слова object затруднительно определить callback типа

type
TForProgressBar = procedure(Current, Total: Integer) of object;

Это, ясное дело, очень мощное и «современное» средство, не реализованное, к примеру, в С++. Там аналог убогий.

Во-вторых, object позволяет создавать «интеллектуальные записи» (с методами), которые к тому же обладают свойством наследования. В некоторых диалектах С я встречал это свойство «наследования» с применением анонимных структур.

> просто так (04.03.07 14:07) [32]
я-таки скажу откровение: в том стандарте и object ни разу нет.


> я-таки скажу откровение: в том стандарте и object ни разу
> нет

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

_uw_ (04.03.07 14:08) [33]
ну я не про все применения ключевого слова object, а именно про то применение которое оставлено для совместимости

в .NET структуры наделённые свойствами ООП юзаются порой в качестве «легковесных» объектов ибо для них в стеке память выделяется(то есть быстро) и освобождается быстро(а не когда GC соизволит)
в каком-то таком же смысле использования object-объектов возможно и может быть оправдано

Информатизация

Блог о информационных технологиях и не только

вторник, 23 марта 2010 г.

Стилевое оформление исходного кода в Delphi

Естественно переход с собственного стиля оформления на предлагаемый может оказаться непростым, но рано или поздно это надо делать. Есть утилита которая может посодействовать более комфортабельно перейти на этот стандарт. Называется она «delforexp» (Доступна для Delphi 2/3/4/5/6/7/9/2007). В среде Delphi 2010 есть уже встроенный свой инструмент форматирования исходного кода.

Кстати в компании Borland, на Web-сайте компании Borland, на CD, DVD купленных у компании Borland, везде где есть исходный код, стандарт форматирования является законом.

Данный документ не является попыткой определить грамматику языка Object Pascal. В нем приводятся базовые примеры как можно поступить при оформлении исходного кода.

Файлы исходного кода (Наверх) Исходный код Object Pascal подразделяется на модули и файлы проекта, которые подчиняются одинаковым соглашениям. Файл проекта Delphi имеет расширение dpr. Этот файл является главным исходным файлом для всего проекта. Любые модули, используемые в проекте, всегда будут иметь расширение pas. Дополнительные файлы, используемые в проекте могут играть важную роль, но эта глава описывает форматирование только pas и dpr файлов. Более подробно о расширениях файлов можно прочитать в статье: Описание типов файлов в среде Delphi.

Именование файлов (Наверх)
Язык Object Pascal поддерживает длинные имена файлов. Если при создании имени файла Вы используете несколько слов, то необходимо использовать заглавную букву для каждого слова в имени, например: MyFirstProjectName.pas. Такой стиль оформления известен как InfixCaps или CamelCaps. Расширения файлов должны быть в нижнем регистре.

Все файлы модулей которые созданы в какой либо организации, например: ХХХ должны иметь префикс ХХХ

Организация исходных файлов (Наверх)
Все модули Object Pascal могут содержать следующие элементы в определенном порядке:

  • Информация о правах (Copyright/ID);
  • Имя модуля (Unit Name);
  • Секцию интерфейса (Interface section);
    • Подключаемые модули
  • Объявление классов и интерфейсов
    • Дополнительные определения (Additional defines);
  • Реализаця (Implementation)
    • Объявление используемых модулей и директив (Uses clause);
    • Исходный код;
  • Закрывающий оператор и точку (end.) (A closing end and a period).

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

При создании нового проекта – среда разработки генерирует исходный код, пример которго приведен ниже:

interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

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

  • Назначение модуля;
  • Копирайт;
  • Разработчик;
  • Дата последней модификации для исполняемой версии

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

Имя модуля (Наверх)
Оно начинается с ключевого слова unit. Имя модуля может содержать символы как в верхнем, так и в нижнем регистре. Например: unit XXXModule1; В результате этот модуль будет назван XXXModule1.pas при сохранении.

Секция интерфейса (Наверх)
Она состоит из определения подключаемых модулей, описания типов, констант, массивов, переменных:

Подключаемые модули(Наверх)
Внутри модуля объявление используемых модулей должно начинаться со слова uses (в нижнем регистре). Затем следуют наименования модулей с сохранением регистра символов.
Каждый используемый модуль должен отделяться от следующего с помощью запятой. Объявление используемых модулей должно заканчиваться точкой с запятой. Список используемых модулей необходимо располагать на следующей строке после слова uses. Если используются модули из разных проектов или производителей, то необходимо сгруппировать модули по проектам или производителям и каждую новую группу начинать с новой строки и прокомментировать каждую группу:

uses
Windows, SysUtils, >// модули Delphi
XХХMyUnit1, ХХXMyUnit2; // модули ХХХ

Если список используемых модулей не умещается по ширине в 80 символов (в редакторе кода есть вертикальная полоса, которая показівает границу в 80 символов), то его необходимо перенести на следующую строку.

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

ManageLayout //глагол
delphi_is_new_to_me //подчерк

Объявление класса и типов начинается с двух пробелов, затем идет идентификатор класса(его имя) с префиксом Т.

Следом за идентификатором класса идет пробел, знак равенства, пробел и слово class в нижнем регистре:

TMy > Если необходимо определить родителя класса, то следует добавить открывающую скобку, имя класса — родителя и закрывающую скобку:

TMy > Объявления областей видимости начинаются с двух пробелов и, следовательно, области видимости распологаются на одном уровне с идентификатором класса:

TMy > private
FMyData: Integer;
function GetData: Integer;
procedure SetData(Value: Integer);
public
published
property MyData: Integer read GetData write SetData;
end;

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

Ключевое слово type размещается без отступов, перечисление типов начинается с новой строки:

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

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

Закрывающий оператор и точку (end.) (A closing end and a period) (Наверх)
И конечно же в конце всего этого долен стоять оператор end. – что сведетельствует о окончании модуля.

Соглашение об именовании (Наверх)
Исключая зарезервированные слова и директивы, которые всегда пишутся в нижнем регистре, все идентификаторы Object Pascal должны использовать InfixCaps (Каждое слово начинается с большой буквы):

MyIdentif, MyFTPClass, NewModuleName;

Самое главное исключение для всех правил состоит в использовании оттранслированных заголовочных файлов С/С++. В этом случае всегда используются соглашения, принятые в файле источнике. Например будет использоваться WM_LBUTTONDOWN, а не wm_LButtonDown.

Именование (Наверх)
При именовании полей всегда необходимо использовать InfixCaps. Объявлять переменные только в приватных частях и использовать свойства для доступа к переменным. Для переменных использовать префикс F.

Имена всех локальных переменных должны подчиняться тем же правилам, которые установлены для именования полей, исключая префикс F.

В имени метода всегда должна содержаться команда к действию или глагольная фраза:

ShowStatus
DrawCircle
AddLayoutComponent

MouseButton; //Существительное, не описывает функцию
drawCircle; //Начинается с маленькой буквы
add_layout_component; //Используются символы подчерка
ServerRunning; //Глагольная фраза, но без команды

Обратите внимание на последний пример (ServerRunning) — непонятно, что делает этот метод, он может быть использован как для запуска сервера (лучше использовать StartServer) так и для проверки работы сервера (лучше использовать IsServerRunning).

Имена процедур или методов для установки/получения значений свойств должны составляться по правилу: для получения — Get+имя свойства; для установки — Set+имя свойства.

Методы для теста/проверки булевских свойств класса должны именоваться с префиксом Is+имя свойства.

IsResizable, IsVisible, IsServerRunning;

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

Правильно

Исключение для Венгерской нотации делается в случае объявления перечислимого типа:

TBtnKind = (bkCustom, bkOK, bkCancel, bkHelp,bkYes, bkNo, bkClose, bkAbort, bkRetry,bkIgnore, bkAll);

bk обозначает ButtonKind;

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

Переменные цикла именуются I и J. Другие случаи использования однобуквенных переменных это S (строка) и R (результат). Однобуквенные имена должны всегда использовать символ в верхнем регистре, но лучше использовать боле значимые имена. Также не рекомендуется использовать переменную l (эль), потому что она похожа на 1 (единица).

Зарезервированные слова (Наверх)
Зарезервированные слова и директивы должны быть все в нижнем регистре. Производные типы должны начинаться с большой буквы (Integer), однако string — это зарезервированное слово и оно должно быть в нижнем регистре.

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

  • После блока копирайта;
  • После декларации пакета;
  • После секции импорта;
  • Между объявлениями классов;
  • Между реализациями методов;

Использование пробелов(Наверх)
Язык Object Pascal является очень легким для понимания языком, поэтому нет особой необходимости в использовании большого количества пробелов. Следующие пункты дадут Вам понимание — в каком случае необходимо использовать пробелы.

Пробелы, запрещенные к использованию в следующих случаях:

  • До или после оператора .(точка);
  • Между именем метода и открывающей скобкой;
  • Между унарным оператором и его операндом;
  • Между выражением приведения (cast) и приводимым выражением;
  • После открывающей скобки или перед закрывающей;
  • После открывающей квадратной скобки [ или перед закрывающей ];
  • Перед точкой с запятой;

Примеры правильного использования:

function TMyClass.MyFunc(var Value: Integer);
MyPointer := @MyRecord;
My > MyInteger := MyIntegerArray[5];

Примеры неправильного использования:


function TMyClass.MyFunc( var Value: Integer ) ;
MyPointer := @ MyRecord;
My > MyInteger := MyIntegerArray [ 5 ] ;

Использование отступов (Наверх)
Всегда необходимо использовать два пробела для всех уровней отступа. Другими словами, первый уровень отступает на два пробела, второй на четыре и так далее. Можно настроить табуляцию на ширину в 2 пробела и пользоваться табуляцией.

Существует несколько исключений из этого правила. Зарезервированные слова unit, uses, type, interface, implementation, initialization и finalization, они всегда должны примыкать к левой границе.

Также должны быть отформатированы финальные end-ы , завершающий исходный модуль и отдельные блоки. В файле проекта выравнивание по левой границе применяется к также к словам program, главным begin и end. Код внутри блока beginend должен иметь отступ два символа.

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

procedure Foo(Param1: Integer; Param2: Integer);

procedure Foo( Param :Integer; Param2:Integer );

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

while (LongExpression1 or LongExpression2) do begin
// DoSomething

В случае с логическими операторами предпочтительнее будет следующий вариант:

Комментарии (Наверх)
Язык Object Pascal поддерживает два типа комментариев: блочные и однострочные. Общие правила по использованию комментариев могут быть следующими:

  • Помещайте комментарий недалеко от начала модуля для пояснения его назначения;
  • Помещайте комментарий перед объявлением класса;
  • Помещайте комментарий перед объявлением метода;
  • Избегайте очевидных комментариев: (i := i + 1 // добавить к i единицу);
  • Помните, что вводящий в заблуждение комментарий хуже чем его отсутствие;
  • Избегайте помещать в комментарий информацию, которая со временем может быть не верна;
  • Избегайте разукрашивать комментарии звездочками или другими символами;
  • Для временных (отсутствующие в релизе) комментариев используйте «TODO«.

Блочные комментарии(Наверх)
Object Pascal поддерживает два типа блочных комментариев. Наиболее часто используемый блочный комментарий — это пара фигурных скобок: . Команда разработчиков Delphi предпочитает использовать этот комментарий как можно проще и как запасной. Используйте в таких комментариях пробелы для форматирования текста и не используйте символы зведочка «*». При переносе строк необходимо сохранять отступы и выравнивание

DelphiComponent.ru — бесплатно видеоуроки по Delphi, статьи, исходники

Основы языка SQL

Язык структурированных запросов SQL (Structured Query Language) существует в нескольких стандартах. Наиболее распространенными являются стандарты SQL-89 и SQL-92. Последний также называют стандартом ANSI. Из-за частичной несовместимости стандартов языка существует множество его диалектов. Мы рассмотрим только основные команды SQL для простых операций с таблицами баз данных.

В языке SQL нет многих типов команд, которые присущи большинству языков программирования. Так, в нем отсутствуют операторы цикла, перехода и т. д. SQL-запрос — это команда на языке SQL.

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

Все SQL-запросы можно условно разделить на два вида:

  1. статический SQL-запрос — включается в код приложения во время его разработки и не изменяется во время выполнения. Единственным способом поправить что-либо в запросе такого типа является включение в SQL-запрос параметров и их дальнейшая модификация в ходе работы приложения;
  2. динамический SQL-запрос — создается и изменяется в процессе выполнения приложения. Такие запросы являются самыми гибкими и могут более адекватно отвечать конкретным желаниям пользователя.

Все операторы и команды языка SQL можно разделить на три группы. Рассмотрим эти группы, а также операторы, входящие в каждую из групп.

Операторы определения данных предназначены для создания, удаления и изменения структуры данных. Основные из них перечислены в табл. 11.1.

Таблица 11.1. Основные операторы определения данных

Оператор Описание
Grand Назначает привилегии пользователя
REVOKE Отменяет привилегии пользователей

Операторы манипулирования данными осуществляют работу с записями таблиц. Наиболее часто используемые операторы кратко описаны в табл. 11.3.

Таблица 11.3. Основные операторы манипулирования данными

Функция Описание
AVG( ) Получение среднего значения
COUNT( ) Определяет количество значений
COUNT(*) Определяет количество ненулевых значений
MAX() Максимальное значение
MIN() Минимальное значение
SUM() Сумма значений

Строковые функции — функции, предоставленные для работы со строковыми значениями. Наиболее часто задействуем ые из них представлены в табл. 11.5.

Таблица 11.5 Основные строковые функции


Установите свойство Dataset у TDatasource в Query1.

Разместите на форме TDBGrid.

  • Установите его свойство Datasource в Datasource1.
  • Свойство SQL имеет тип TStrings. Объект TStrings представляет собой список строк, и чем-то похож на массив. Тип данных TStrings имеет в своем арсенале команды добавления строк, их загрузки из текстового файла и обмена данными с другим объектом TStrings. Другой компонент, использующий TStrings — TMemo. В демонстрационном проекте ENTRSQL.DPR (по идее, он должен находится на отдельной дискете, но к «Советам по Delphi» она не прилагается — В.О.), пользователь должен ввести SQL-запрос и нажать кнопку «Do It» («сделать это»). Результаты запроса отображаются в табличной сетке. В Листинге 1 полностью приведен код обработчика кнопки «Do It».

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

    Если вам нужно протестировать, или установить для параметра значение по умолчанию, выберите свойство Params объекта Query1. Щелкните на кнопке ‘. ‘. Должен появиться диалог настройки параметров. Выберите параметр Dept_no. Затем в выпадающем списке типов данных выберите Integer. Для того, чтобы задать значение по умолчанию, введите нужное значение в поле редактирования «Value».

    Для изменения SQL-запроса во время выполнения приложения, параметры необходимо связать (bind). Параметры могут изменяться, запрос выполняться повторно, а данные обновляться. Для непосредственного редактирования значения параметра используется свойство Params или метод ParamByName. Свойство Params представляет из себя массив TParams. Поэтому для получения доступа к параметру, необходимо указать его индекс. Для примера,

    Свойство asInteger читает данные как тип Integer (название говорит само за себя). Это не обязательно должно указывать но то, что поле имеет тип Integer. Например, если тип поля VARCHAR(10), Delphi осуществит преобразование данных. Так, приведенный выше пример мог бы быть записан таким образом:

    Если вместо номера индекса вы хотели бы использовать имя параметра, то воспользуйтесь методом ParamByName. Данный метод возвращает объект TParam с заданным именем. Например:

    В листинге 2 приведен полный код примера.

    Обратите внимание на процедуру, первым делом подготавливающую запрос. При вызове метода prepare, Delphi посылает SQL запрос на удаленный сервер. Сервер выполняет грамматический разбор и оптимизацию запроса. Преимущество такой подготовки запроса состоит в его предварительном разборе и оптимизации. Альтернативой здесь может служить подготовка сервером запроса при каждом его выполнении. Как только запрос подготовлен, подставляются необходимые новые параметры, и запрос выполняется.

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

    Примечание: Следующий пример использует TTable с именем Table1. Для Table1 имя базы данных IBLOCAL, имя таблицы — DEPARTMENT. DataSource2 TDatasource связан с Table1. Таблица также активна и отображает записи в TDBGrid.

    Способ подключения TQuery к TTable — через TDatasource. Есть два основных способа сделать это. Во-первых, разместить код в обработчике события TDatasource OnDataChange. Например, листинг 3 демонстрирует эту технику.

    Листинг 3 — Использования события OnDataChange для просмотра дочерних записей

    Техника с использованием OnDataChange очень гибка, но есть еще легче способ подключения Query к таблице. Компонент TQuery имеет свойство Datasource. Определяя TDatasource для свойства Datasource, объект TQuery сравнивает имена параметров в SQL-запросе с именами полей в TDatasource. В случае общих имен, такие параметры заполняются автоматически. Это позволяет разработчику избежать написание кода, приведенного в листинге 3 (*** приведен выше ***).

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

    Листинг 4 — Связывание TQuery c TTable через свойство Datasource

    Выберите у Query1 свойство SQL и введите:

    Выберите свойство Datasource и назначьте источник данных, связанный с Table1 (Datasource2 в нашем примере)

    Выберите свойство Active и установите его в True

    Это все, если вы хотите создать такой тип отношений. Тем не менее, существуют некоторые ограничения на параметризованные запросы. Параметры ограничены значениями. К примеру, вы не можете использовать параметр с именем Column или Table. Для создания запроса, динамически изменяемого имя таблицы, вы могли бы использовать технику конкатенации строки. Другая техника заключается в использовании команды Format.

    Команда Format заменяет параметры форматирования (%s, %d, %n и пр.) передаваемыми значениями. Например,

    Результатом вышеприведенной команды будет ‘Select * from EMPLOYEE’. Функция буквально делает замену параметров форматирования значениями массива. При использовании нескольких параметров форматирования, замена происходит слева направо. Например,

    Результатом команды форматирования будет ‘Select * from EMPLOYEE where EMP_ >

    Листинг 5 — Использование команды Format для создания SQL-запроса

    В этом примере мы используем методы Clear и Add свойства SQL. Поскольку «подготовленный» запрос использует ресурсы сервера, и нет никакой гарантии что новый запрос будет использовать те же таблицы и столбцы, Delphi, при каждом изменении свойства SQL, осуществляет операцию, обратную «подготовке» (unprepare). Если TQuery не был подготовлен (т.е. свойство Prepared установлено в False), Delphi автоматически подготавливает его при каждом выполнении. Поэтому в нашем случае, даже если бы был вызван метод Prepare, приложению от этого не будет никакой пользы.

    Open против ExecSQL

    В предыдущих примерах TQuerie выполняли Select-запросы. Delphi рассматривает результаты Select-запроса как набор данных, типа таблицы. Это просто один класс допустимых SQL-запросов. К примеру, команда Update обновляет содержимое записи, но не возвращает записи или какого-либо значения. Если вы хотите использовать запрос, не возвращающий набор данных, используйте ExecSQL вместо Open. ExecSQL передает запрос для выполнения на сервер. В общем случае, если вы ожидаете, что получите от запроса данные, то используйте Open. В противном случае допускается использование ExecSQL, хотя его использование с Select не будет конструктивным. Листинг 6 содержит код, поясняющий сказанное на примере.

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

    3. Компонент TStoredProc

    Хранимая процедура представляет собой список команд (SQL или определенного сервера), хранимых и выполняемых на стороне сервера. Хранимые процедуры не имеют концептуальных различий с другими типами процедур. TStoredProc наследуется от TDataset, поэтому он имеет много общих характеристик с TTable и TQuery. Особенно заметно сходство с TQuery. Поскольку хранимые процедуры не требуют возврата значений, те же правила действуют и для методов ExecProc и Open. Каждый сервер реализует работу хранимых процедур с небольшими различиями. Например, если в качестве сервера вы используете Interbase, хранимые процедуры выполняются в виде Select-запросов. Например, чтобы посмотреть на результаты хранимой процедуры, ORG_CHART, в демонстрационной базе данных EMPLOYEE, используйте следующих SQL-запрос:

    При работе с другими серверами, например, Sybase, вы можете использовать компонент TStoredProc. Данный компонент имеет свойства для имен базы данных и хранимой процедуры. Если процедура требует на входе каких-то параметров, используйте для их ввода свойство Params.

    4. TDatabase

    Компонент TDatabase обеспечивает функциональность, которой не хватает TQuery и TStoredProc. В частности, TDatabase позволяет создавать локальные псевдонимы BDE, так что приложению не потребуются псевдонимы, содержащиеся в конфигурационном файле BDE. Этим локальным псевдонимом в приложении могут воспользоваться все имеющиеся TTable, TQuery и TStoredProc. TDatabase также позволяет разработчику настраивать процесс подключения, подавляя диалог ввода имени и пароля пользователя, или заполняя необходимые параметры. И, наконец, самое главное, TDatabase может обеспечивать единственную связь с базой данных, суммируя все операции с базой данных через один компонент. Это позволяет элементам управления для работы с БД иметь возможность управления транзакциями.

    Транзакцией можно считать передачу пакета информации. Классическим примером транзакции является передача денег на счет банка. Транзакция должна состоять из операции внесения суммы на новый счет и удаления той же суммы с текущего счета. Если один из этих шагов по какой-то причине был не выполнен, транзакция также считается невыполненной. В случае такой ошибки, SQL сервер позволяет выполнить команду отката (rollback), без внесения изменений в базу данных. Управление транзакциями зависит от компонента TDatabase. Поскольку транзакция обычно состоит из нескольких запросов, вы должны отметить начало транзакции и ее конец. Для выделения начала транзакции используйте TDatabase.BeginTransaction. Как только транзакция начнет выполняться, все выполняемые команды до вызова TDatabase.Commit или TDatabase.Rollback переводятся во временный режим. При вызове Commit все измененные данные передаются на сервер. При вызове Rollback все изменения теряют силу. Ниже в листинге 7 приведен пример, где используется таблица с именем ACCOUNTS. Показанная процедура пытается передать сумму с одного счета на другой.

    И последнее, что нужно учесть при соединении с базой данных. В приведенном выше примере, TDatabase использовался в качестве единственного канала для связи с базой данных, поэтому было возможным выполнение только одной транзакции. Чтобы выполнить это, было определено имя псевдонима (Aliasname). Псевдоним хранит в себе информацию, касающуюся соединения, такую, как Driver Type (тип драйвера), Server Name (имя сервера), User Name (имя пользователя) и другую. Данная информация используется для создания строки соединения (connect string). Для создания псевдонима вы можете использовать утилиту конфигурирования BDE, или, как показано в примере ниже, заполнять параметры во время выполнения приложения.

    TDatabase имеет свойство Params, в котором хранится информация соединения. Каждая строка Params является отдельным параметром. В приведенном ниже примере пользователь устанавливает параметр User Name в поле редактирования Edit1, а параметр Password в поле Edit2. В коде листинга 8 показан процесс подключения к базе данных:

    Этот пример показывает как можно осуществить подключение к серверу без создания псевдонима. Ключевыми моментами здесь являются определение DriverName и заполнение Params информацией, необходимой для подключения. Вам не нужно определять все параметры, вам необходимо задать только те, которые не устанавливаются в конфигурации BDE определенным вами драйвером базы данных. Введенные в свойстве Params данные перекрывают все установки конфигурации BDE. Записывая параметры, Delphi заполняет оставшиеся параметры значениями из BDE Config для данного драйвера. Приведенный выше пример также вводит такие понятия, как сессия и метод GetTableNames. Это выходит за рамки обсуждаемой темы, достаточно упомянуть лишь тот факт, что переменная session является дескриптором database engine. В примере она добавлена только для «показухи».

    Другой темой является использование SQLPASSTHRU MODE. Этот параметр базы данных отвечает за то, как натив-команды базы данных, такие, как TTable.Append или TTable.Insert будут взаимодействовать с TQuery, подключенной к той же базе данных. Существуют три возможных значения: NOT SHARED, SHARED NOAUTOCOMMIT и SHARED AUTOCOMMIT. NOT SHARED означает, что натив-команды используют одно соединение с сервером, тогда как запросы — другое. Со стороны сервера это видится как работа двух разных пользователей. В любой момент времени, пока транзакция активна, натив-команды не будут исполняться (committed) до тех пор, пока транзакция не будет завершена. Если был выполнен TQuery, то любые изменения, переданные в базу данных, проходят отдельно от транзакции.

    Два других режима, SHARED NOAUTOCOMMIT и SHARED AUTOCOMMIT, делают для натив-команд и запросов общим одно соединение с сервером. Различие между двумя режимами заключаются в передаче выполненной натив-команды на сервер. При выбранном режиме SHARED AUTOCOMMIT бессмысленно создавать транзакцию, использующую натив-команды для удаления записи и последующей попыткой осуществить откат (Rollback). Запись должна быть удалена, а изменения должны быть сделаны (committed) до вызова команды Rollback. Если вам нужно передать натив-команды в пределах транзакции, или включить эти команды в саму транзакцию, убедитесь в том, что SQLPASSTHRU MODE установлен в SHARED NOAUTOCOMMIT или в NOT SHARED.

    5. Выводы

    Delphi поддерживает множество характеристик при использовании языка SQL с вашими серверами баз данных. На этой ноте разрешите попрощаться и пожелать почаще использовать SQL в ваших приложениях.

    Информатизация

    Блог о информационных технологиях и не только

    вторник, 23 марта 2010 г.

    Стилевое оформление исходного кода в Delphi

    Естественно переход с собственного стиля оформления на предлагаемый может оказаться непростым, но рано или поздно это надо делать. Есть утилита которая может посодействовать более комфортабельно перейти на этот стандарт. Называется она «delforexp» (Доступна для Delphi 2/3/4/5/6/7/9/2007). В среде Delphi 2010 есть уже встроенный свой инструмент форматирования исходного кода.

    Кстати в компании Borland, на Web-сайте компании Borland, на CD, DVD купленных у компании Borland, везде где есть исходный код, стандарт форматирования является законом.

    Данный документ не является попыткой определить грамматику языка Object Pascal. В нем приводятся базовые примеры как можно поступить при оформлении исходного кода.

    Файлы исходного кода (Наверх) Исходный код Object Pascal подразделяется на модули и файлы проекта, которые подчиняются одинаковым соглашениям. Файл проекта Delphi имеет расширение dpr. Этот файл является главным исходным файлом для всего проекта. Любые модули, используемые в проекте, всегда будут иметь расширение pas. Дополнительные файлы, используемые в проекте могут играть важную роль, но эта глава описывает форматирование только pas и dpr файлов. Более подробно о расширениях файлов можно прочитать в статье: Описание типов файлов в среде Delphi.

    Именование файлов (Наверх)
    Язык Object Pascal поддерживает длинные имена файлов. Если при создании имени файла Вы используете несколько слов, то необходимо использовать заглавную букву для каждого слова в имени, например: MyFirstProjectName.pas. Такой стиль оформления известен как InfixCaps или CamelCaps. Расширения файлов должны быть в нижнем регистре.

    Все файлы модулей которые созданы в какой либо организации, например: ХХХ должны иметь префикс ХХХ

    Организация исходных файлов (Наверх)
    Все модули Object Pascal могут содержать следующие элементы в определенном порядке:

    • Информация о правах (Copyright/ID);
    • Имя модуля (Unit Name);
    • Секцию интерфейса (Interface section);
      • Подключаемые модули
    • Объявление классов и интерфейсов
      • Дополнительные определения (Additional defines);
    • Реализаця (Implementation)
      • Объявление используемых модулей и директив (Uses clause);
      • Исходный код;
    • Закрывающий оператор и точку (end.) (A closing end and a period).

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

    При создании нового проекта – среда разработки генерирует исходный код, пример которго приведен ниже:

    interface
    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs;

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

    • Назначение модуля;
    • Копирайт;
    • Разработчик;
    • Дата последней модификации для исполняемой версии

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

    Имя модуля (Наверх)
    Оно начинается с ключевого слова unit. Имя модуля может содержать символы как в верхнем, так и в нижнем регистре. Например: unit XXXModule1; В результате этот модуль будет назван XXXModule1.pas при сохранении.

    Секция интерфейса (Наверх)
    Она состоит из определения подключаемых модулей, описания типов, констант, массивов, переменных:

    Подключаемые модули(Наверх)
    Внутри модуля объявление используемых модулей должно начинаться со слова uses (в нижнем регистре). Затем следуют наименования модулей с сохранением регистра символов.
    Каждый используемый модуль должен отделяться от следующего с помощью запятой. Объявление используемых модулей должно заканчиваться точкой с запятой. Список используемых модулей необходимо располагать на следующей строке после слова uses. Если используются модули из разных проектов или производителей, то необходимо сгруппировать модули по проектам или производителям и каждую новую группу начинать с новой строки и прокомментировать каждую группу:

    uses
    Windows, SysUtils, >// модули Delphi
    XХХMyUnit1, ХХXMyUnit2; // модули ХХХ

    Если список используемых модулей не умещается по ширине в 80 символов (в редакторе кода есть вертикальная полоса, которая показівает границу в 80 символов), то его необходимо перенести на следующую строку.

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

    ManageLayout //глагол
    delphi_is_new_to_me //подчерк

    Объявление класса и типов начинается с двух пробелов, затем идет идентификатор класса(его имя) с префиксом Т.

    Следом за идентификатором класса идет пробел, знак равенства, пробел и слово class в нижнем регистре:

    TMy > Если необходимо определить родителя класса, то следует добавить открывающую скобку, имя класса — родителя и закрывающую скобку:

    TMy > Объявления областей видимости начинаются с двух пробелов и, следовательно, области видимости распологаются на одном уровне с идентификатором класса:

    TMy > private
    FMyData: Integer;
    function GetData: Integer;
    procedure SetData(Value: Integer);
    public
    published
    property MyData: Integer read GetData write SetData;
    end;

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

    Ключевое слово type размещается без отступов, перечисление типов начинается с новой строки:

    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs;

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

    Закрывающий оператор и точку (end.) (A closing end and a period) (Наверх)
    И конечно же в конце всего этого долен стоять оператор end. – что сведетельствует о окончании модуля.

    Соглашение об именовании (Наверх)
    Исключая зарезервированные слова и директивы, которые всегда пишутся в нижнем регистре, все идентификаторы Object Pascal должны использовать InfixCaps (Каждое слово начинается с большой буквы):

    MyIdentif, MyFTPClass, NewModuleName;

    Самое главное исключение для всех правил состоит в использовании оттранслированных заголовочных файлов С/С++. В этом случае всегда используются соглашения, принятые в файле источнике. Например будет использоваться WM_LBUTTONDOWN, а не wm_LButtonDown.

    Именование (Наверх)
    При именовании полей всегда необходимо использовать InfixCaps. Объявлять переменные только в приватных частях и использовать свойства для доступа к переменным. Для переменных использовать префикс F.

    Имена всех локальных переменных должны подчиняться тем же правилам, которые установлены для именования полей, исключая префикс F.

    В имени метода всегда должна содержаться команда к действию или глагольная фраза:

    ShowStatus
    DrawCircle
    AddLayoutComponent

    MouseButton; //Существительное, не описывает функцию
    drawCircle; //Начинается с маленькой буквы
    add_layout_component; //Используются символы подчерка
    ServerRunning; //Глагольная фраза, но без команды

    Обратите внимание на последний пример (ServerRunning) — непонятно, что делает этот метод, он может быть использован как для запуска сервера (лучше использовать StartServer) так и для проверки работы сервера (лучше использовать IsServerRunning).

    Имена процедур или методов для установки/получения значений свойств должны составляться по правилу: для получения — Get+имя свойства; для установки — Set+имя свойства.

    Методы для теста/проверки булевских свойств класса должны именоваться с префиксом Is+имя свойства.

    IsResizable, IsVisible, IsServerRunning;

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

    Правильно

    Исключение для Венгерской нотации делается в случае объявления перечислимого типа:

    TBtnKind = (bkCustom, bkOK, bkCancel, bkHelp,bkYes, bkNo, bkClose, bkAbort, bkRetry,bkIgnore, bkAll);

    bk обозначает ButtonKind;

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

    Переменные цикла именуются I и J. Другие случаи использования однобуквенных переменных это S (строка) и R (результат). Однобуквенные имена должны всегда использовать символ в верхнем регистре, но лучше использовать боле значимые имена. Также не рекомендуется использовать переменную l (эль), потому что она похожа на 1 (единица).

    Зарезервированные слова (Наверх)
    Зарезервированные слова и директивы должны быть все в нижнем регистре. Производные типы должны начинаться с большой буквы (Integer), однако string — это зарезервированное слово и оно должно быть в нижнем регистре.

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

    • После блока копирайта;
    • После декларации пакета;
    • После секции импорта;
    • Между объявлениями классов;
    • Между реализациями методов;

    Использование пробелов(Наверх)
    Язык Object Pascal является очень легким для понимания языком, поэтому нет особой необходимости в использовании большого количества пробелов. Следующие пункты дадут Вам понимание — в каком случае необходимо использовать пробелы.

    Пробелы, запрещенные к использованию в следующих случаях:

    • До или после оператора .(точка);
    • Между именем метода и открывающей скобкой;
    • Между унарным оператором и его операндом;
    • Между выражением приведения (cast) и приводимым выражением;
    • После открывающей скобки или перед закрывающей;
    • После открывающей квадратной скобки [ или перед закрывающей ];
    • Перед точкой с запятой;

    Примеры правильного использования:

    function TMyClass.MyFunc(var Value: Integer);
    MyPointer := @MyRecord;
    My > MyInteger := MyIntegerArray[5];

    Примеры неправильного использования:

    function TMyClass.MyFunc( var Value: Integer ) ;
    MyPointer := @ MyRecord;
    My > MyInteger := MyIntegerArray [ 5 ] ;

    Использование отступов (Наверх)
    Всегда необходимо использовать два пробела для всех уровней отступа. Другими словами, первый уровень отступает на два пробела, второй на четыре и так далее. Можно настроить табуляцию на ширину в 2 пробела и пользоваться табуляцией.

    Существует несколько исключений из этого правила. Зарезервированные слова unit, uses, type, interface, implementation, initialization и finalization, они всегда должны примыкать к левой границе.

    Также должны быть отформатированы финальные end-ы , завершающий исходный модуль и отдельные блоки. В файле проекта выравнивание по левой границе применяется к также к словам program, главным begin и end. Код внутри блока beginend должен иметь отступ два символа.

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

    procedure Foo(Param1: Integer; Param2: Integer);

    procedure Foo( Param :Integer; Param2:Integer );

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

    while (LongExpression1 or LongExpression2) do begin
    // DoSomething

    В случае с логическими операторами предпочтительнее будет следующий вариант:

    Комментарии (Наверх)
    Язык Object Pascal поддерживает два типа комментариев: блочные и однострочные. Общие правила по использованию комментариев могут быть следующими:

    • Помещайте комментарий недалеко от начала модуля для пояснения его назначения;
    • Помещайте комментарий перед объявлением класса;
    • Помещайте комментарий перед объявлением метода;
    • Избегайте очевидных комментариев: (i := i + 1 // добавить к i единицу);
    • Помните, что вводящий в заблуждение комментарий хуже чем его отсутствие;
    • Избегайте помещать в комментарий информацию, которая со временем может быть не верна;
    • Избегайте разукрашивать комментарии звездочками или другими символами;
    • Для временных (отсутствующие в релизе) комментариев используйте «TODO«.

    Блочные комментарии(Наверх)
    Object Pascal поддерживает два типа блочных комментариев. Наиболее часто используемый блочный комментарий — это пара фигурных скобок: . Команда разработчиков Delphi предпочитает использовать этот комментарий как можно проще и как запасной. Используйте в таких комментариях пробелы для форматирования текста и не используйте символы зведочка «*». При переносе строк необходимо сохранять отступы и выравнивание

    Режимы компиляции

    18.04.2005
    Иван Шихалев

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

    Режим компиляции выставляется при помощи ключа командной строки -S или непосредственно в модуле при помощи директивы <$MODE xxx>.

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

    Режим по умолчанию. Соответственно в ключах командной строки своего символа не имеет. Что, впрочем, не есть хорошо, по­сколь­ку существует же еще и файл ppc386.cfg — его установки таким образом мы можем сменить на FPC только через директиву.

    При присваивании значения процедурной переменной вы можете использовать как @

    . Что са­мое интересное — это распространяется и на функции. Выражение @

    однозначно трактуется как адрес переменной, а не процедуры, на которую она ссылается. Кстати, в справке по этому поводу ошибка, или я что-то не так понял: «You must use the address operator to assign procedural variables.»

    Заголовок предварительно объявленной (в интерфейсной части модуля или при помощи директивы forward ) функции или про­це­ду­ры должен полностью совпадать с ее заголовком при реализации. То есть опускать список аргументов и тип результата — не­ль­зя.

    Разрешена перегрузка (overloading) процедур и функций. Кстати, в отличие от Delphi, директиву overload использовать не­обя­за­тель­но.

    Разрешены вложенные комментарии, таким образом, конструкция < comment < nested comment >> не вызовет ошибки ком­пи­ля­то­ра.

    Не поддерживаются классы. Из-за того, что обработка исключений реализована a-la Delphi, не поддерживается оператор try .

    Не подгружается модуль ObjPas . Что это за зверь, я слегка опишу, когда перейдем к <$MODE OBJFPC>, пока лишь замечу, что тип integer без ObjPas соответствует 2м байтам, а с ним — 4м.

    Не поддерживается ключевое слово resourcestring .

    До кучи ко всем огорчениям, не поддерживается псевдо(?)переменная result — результат функции присваивается ее имени.

    Зато поддерживается директива cvar и внешние переменные.

    Автоматически производится присваивание PChar -> string .

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

    Режим совместимости с Turbo Pascal фирмы Borland версии 7. Соответствует ключу командной строки -So .

    Совместимость обеспечивается полная — единственное различие в том, что исполняемый файл 32-разрядный, других Free Pascal не создает.

    Писать программы непосредственно в этом режиме, на мой взгляд — мазохизм. А вот портировать старые программы для TP легко — как правило, не требуется вносить каких-либо изменений в код.

    В силу полной совместимости, воздержусь от подробного описания этого режима — чего-чего, а уж литературы по Turbo Pascal до­ста­точ­но, и в Сети, и в книжных магазинах.

    По идее — режим совместимости с GPC — GNU Pascal. Ключ командной строки — -Sp .

    Судя по всему — разработка данного режима для команды FPC — мягко говоря, задача не приоритетная. Реально никаких свой­ствен­ных GPC расширений не поддерживается, и от <$MODE TP>этот режим отличается только использованием адресного опе­ра­то­ра для процедурных переменных.

    Это — режим Object Pascal. Соответствует ключу командной строки -S2 .

    Работа с процедурными переменными полностью аналогична режиму <$MODE FPC>. Аналогично с заголовками функций и про­це­дур — они должны повторяться в точности при реализации. Вообще, режимы очень похожи, главное отличие — поддержка клас­сов.

    Классы почти полностью идентичны классам в Delphi. Естественно, published практически эквивалентно public . Кроме того, пе­ре­груз­ка методов не требует директивы overload . Обидно, что не поддерживаются интерфейсы, но авторы обещают сделать это к версии 1.2.

    Автоматически подгружается модуль ObjPas . Данный модуль по сути дополняет функциональность модуля System с уровня Turbo Pascal до уровня Delphi. Хотя, конечно, это грубое упрощение. Что реально он делает?

    • Во-первых, определяет тип smallint — целое со знаком длиной в слово, и переопределяет тип integer — в отличие от других режимов он означает целое со знаком размером в двойное слово, что соответствует типу longint , который остается таким же.
    • Во-вторых, для совместимости с Delphi определены процедуры AssignFile и CloseFile .
    • В-третих, переопределяет процедуры GetMem и FreeMem . К сожалению, я пока не ковырялся в исходниках и не могу сказать, что именно в их реализации изменено.
    • И в-четвертых, в этом модуле определяются функции для работы с ресурсными строками.

    Free Pascal при <$MODE OBJFPC>поддерживает работу с ресурсными строками, через resourcestring .

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

    Преобразование PChar -> string производится при присваивании автоматически.

    Второе (после классов) по важности преимущество данного режима — обработка исключений в блоках try . except . end и try . finally . end . Данный механизм Free Pascal поддерживает полностью аналогично Delphi — то есть вы можете пе­ре­хва­ты­вать исключения, обрабатывать в зависимости от класса с помощью ключевого слова on , определять собственные классы ис­клю­че­ний и вызывать их (или стандартные) посредством оператора raise . Для корректной работы с исключениями нужно под­клю­чать, как и в Delphi, модуль SysUtils , который содержит базовый класс Exception и стандартные классы исключений.

    В общем и целом данный режим очень похож на Object Pascal a-la Borland Delphi. Разработчики намерены реализовать и ин­тер­фей­сы к версии 1.2, но когда она выйдет, пока неизвестно.

    Режим совместимости с Borland Delphi версии 2, если я не ошибаюсь. Соответствует ключу командной строки -Sd .

    От <$MODE OBJFPC>отличается весьма незначительно:

    • Во-первых, необязательно в секции implementation повторять заголовок процедуры или функции.
    • И, во-вторых, не разрешена перегрузка функций, процедур и операторов.

    В целом, я бы рекомендовал все-таки <$MODE OBJFPC>, который соединяет в себе объектную модель Object Pascal со всеми пре­лес­тя­ми собственно FPC.

    Прочие расширения языка

    Поддержка inline- процедур, функций и операторов. Определяется директивой компилятора <$INLINE ON/OFF>и ключом ко­манд­ной строки -Si . Inline-процедуры описываются директивой inline в заголовке, могут быть как нормальными пас­ка­лев­ски­ми, так и ассемблерными (при использовании директивы assembler ), то есть не требуют знания машинных кодов, как директива inline в Turbo Pascal. При использовании этой возможности следует помнить, что в случае ошибки (рекурсия, etc.) компилятор по­че­му-то не выдает осмысленного сообщения, а слетает на «Internal Error». Если inline-процедура используется за пределами про­грамм­но­го модуля, где она непосредственно описана, то трактуется как обычная вызываемая процедура.

    Поддержка простых макросов. Определяется директивой компилятора <$MACRO ON/OFF>и ключом командной строки -Sm . Са­ми макросы определяются так <$DEFINE MACRO_NAME := EXPRESSION>, где MACRO_NAME — идентификатор, который в даль­ней­шем тексте программы будет заменяться на выражение EXPRESSION .

    Поддержка специальных операторов присваивания в стиле Си. Определяется ключом командной строки -Sc , собственной ди­рек­ти­вы компилятора не имеет. Разрешает присваивание с одновременным сложением, вычитанием, умножением или делением, ис­поль­зуя операторы += , -= , *= и /= соответственно.

    Илон Маск рекомендует:  Пунктирная линия. Свойство stroke-dashoffset
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL