EndOfADay — Функция Delphi


Содержание

Процедуры и функции преобразования дат и времени

CurrentYear: Word;

Возвращает полное обозначение (четыре цифры) текущего года.

Date : TDateTime

Возвращает текущую дату.

DateOf(const AValue: TDateTime): TDateTime

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

DateTimeToFileDate(DateTime: TDateTime): Integer

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

DateTimeToSQLTimeStamp(const DateTime: TDateTime): TSQLTimeStamp

Преобразует дату и время TDateTime в формат TSQLTimeStamp .

DateTimeToStr (DateTime: TDateTime): string

Преобразует дату и время DateTime в строку.

DateTimeToString fvar Result: string; const Format: string;

DateTime: TDateTime)

Преобразует DateTime с помощью строки форматирования Format в стро­ку Result.

DateTimeToSystemTime(DateTime: TDateTime;

var SystemTime: TSystemTime)

Преобразует DateTime типа TDateTime в тип TSystemTime . Используемый в API Windows 32.

DateTimeToTimeStamp(DateTime: TDateTime): TTimeStamp Преобразует DateTime типа TDateTime в тип TTimeStamp .

DateToStr(Date: TDateTime): string

Преобразует дату DateTime в строку, используя формат, заданный гло­бальной переменной ShortDateFormat.

DayOf f(const AValue: TDateTime): Word

Извлекает день месяца из даты AValue типа TDateTime. Идентична функ ции DavOfTheMonth.

DayOfTheMonth f(const AValue: TDateTime): Word

Извлекает день месяца из даты AValue типа TDateTime. Идентична функ­ции DayOf .

DayOfTheWeek(const AValue: TDateTime): Word

Возвращает день недели (1 — понедельник, 7 — воскресенье).

DayOfTheYear(const AValue: TDateTime): Word;

Возвращает число дней между датой AValue и 31 декабря предыдущего года.

DayOfWeek (Date: TDateTime): Integer

Возвращает день неде ли (1 — воскресенье, 7 — суббота).

DaysBetween f(const ANow, AThen: TDateTime): Integer

Возвращает число полных суток между двумя указанными датами ANow и AThen типа TDateTime.

DaysInAMonth(const AYear, AMonth: Word): Word

Возвращает число дней в указанном месяце AMonth в указанном году AYear.

DaysInYear(const AValue: TDateTime): Word

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

DaySpan (const ANow, AThen: TDateTime): Double

Возвращает действительное число, равное числу суток между двумя ука­занными датами ANow и AThen типа TDateTime, учитывая неполные су­тки. В этом отличие данной функции от DaysBetween.

DecodeDate (Date: TDateTime; var Year, Month, Day: Word)

Разбивает дату Date на год — Year, месяц — Month и день — Day.

DecodeDateDay(const AValue: TDateTime; out AYear, ADayOfYear: Word)

Возвращает год AYear, к которому относится дата AValue, и число дней ADayOfYear в этом году.

DecodeDateFully(const DateTime: TDateTime; var Year, Month, Day,

DOW: Word): Boolean

Выделяет из даты DateTime год Year, месяц Month, день Day, день недели DOW. Если год високосный, возвращается true.

DecodeDateMonthWeek(const AValue: TDateTime;

out AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word)

Возвращает год AYear, месяц AMonth, неделю месяца AWeekOfMonth, день недели ADayOfWeek (1 — понедельник) даты AValue.

DecodeDateTime(const AValue: TDateTime; out AYear, AMonth, ADay,

AHour, AMinute, ASecond, AMilliSecond: Word)

Возвращает год AYear, месяц AMonth, день ADay, час AHour, минуту AMinute, секунду ASecond, число миллисекунд AMilliSecond указанной даты и времени AValue.

DecodeDateWeek(const AValue: TDateTime;

out AYear, AWeekOfYear, ADayOfWeek: Word)

Возвращает год AYear, неделю года AWeekOfYear и день недели ADayOfWeek (1 — понедельник) указанной даты AValue.

DecodeDayOfWeekInMonth(const AValue: TDateTime;

out AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word)

Возвращает год AYear, месяц AMonth, который раз ANthDayOfWeek встречается в месяце данный день недели, день недели ADayOfWeek (1 — понедельник).

DecodeTime (Time: TDateTime; var Hour, Min, Sec, MSec: Word)

Разбивает время Time на час — Hour, минуту — Min, секунду — Sec, миллисекунду — MSec.

EncodeDate fYear. Month, Day: Word): TDateTime

Объединяет год Year, месяц Month и день Day в значение типа TDateTime.

EncodeDateDay(const AYear, ADayOfYear: Word): TDateTime

Формирует значение TDateTime по заданному году AYear и дню года ADayOfYear .

EncodeDateMonthWeek(const AYear, AMonth, AWeekOfMonth: Word;

const ADayOfWeek: Word = 1): TDateTime

Формирует значение TDateTime по заданному году AYear, месяцу AMonth, неделе месяца AWeekOfMonth и дню недели ADayOfWeek.

EncodeDateTime(const AYear, AMonth, ADay, AHour,

AMinute, ASecond, AMilliSecond: Word):TDateTime

Формирует значение TDateTime по заданному году AYear, месяцу AMonth, дню ADay, часу AHour, минуте AMinute, секунде ASecond, мил­лисекунде AMilliSecond.

EncodeDateWeek(const, AWeekOfYear: Word;

const ADayOfWeek: Word =1): TDateTime

Формирует значение TDateTime по заданному году AYear и указанному дню ADayOfWeek указанной недели AWeekOfYear.

EncodeDayOfWeekInMonth(const AYear, AMonth,

ANthDayOfWeek, ADayOfWeek: Word): TDateTime

Формирует значение TDateTime по заданному году AYear, месяцу AMonth, дню недели ADayOfWeek и тому, который раз ANthDayOfWeek

этот день встречается в данном месяце.

EncodcTime (Hour. Min, Sec, MSec: Word): TDateTime

Объединяет час Hour, минуту Min, секунду Sec и миллисекунду MSec

в значение типа TDateTime.

EndOfADay(const AYear, ADayOfYear: Word): TDateTime

Возвращает время окончания указанного дня ADayOfYear указанного года AYear.

EndOfADay(const AYear, AMonth, ADay: Word): TDateTime

Возвращает время окончания указанного дня ADay указанного месяца AMonth указанного года AYear.

EndOfAMonth(const AYear, AMonth: Word): TDateTime

Возвращает время окончания последнего дня указанного месяца AMonth указанного года AYear.

EndOfAWeek(const AYear, AWeekOfYear: Word;

const ADayOfWeek: Word = 7): TDateTime

Возвращает время окончания указанного дня ADayOfWeek указанной не­дели AWeekOfYear указанного года AYear.

EndOfAYear(const AYear): TDateTime

Возвращает время окончания указанного года AYear.

EndOfTheDay(const AValue: TDateTime): TDateTime

Возвращает время окончания указанной даты AValue.

EndOfTheMonth(const AValue: TDateTime): TDateTime

Возвращает время окончания месяца, содержащего указанную дату AValue.

EndOfTheWeek(const AValue: TDateTime): TDateTime

Возвращает время окончания недели, содержащей указанную дату

AValue. EndOfTheYear(const AValue: TDateTime): TDateTime

Возвращает время окончания года, содержащего указанную дату

AValue. FormatDateTime (const Format: string; DateTime: TDateTime): string

Возвращает значение DateTime, преобразованное в строку с помощью стро­ки форматирования Format.

. delphi отображать текущую дату delphi функции даты функция даты и времени паскаль c# преобразовать дату delphi дата и время

Типы, функции и процедуры Delphi для работы с датой и временем.

Содержание:


Функции и процедуры Delphi для работы с датой и временем.


Тип TDateTime.


Тип TTimeStamp.


Тип TSQLTimeStamp.


Функции и процедуры Delphi для работы с датой и временем.


Таблица стандартных процедур и функций для работы с датой и временем

Значения символических констант для обозначения дней недели в соответствии с ISO 8601. Используйте эти константы для работы с функциями, работающими в соответствии со стандартом ISO 8601 (функции из модуля DateUtils).

Внимание: Не используйте эти константы с функцией DayOfWeek, которая трактует Воскресение (Sunday) как первый день недели.

Возвращает день недели из значения TDateTime. Возвращаемое функцией значение находится в промежутке между 1 и 7, где 1 соответствует Понедельнику (Monday), а 7 — Воскресение (Sunday).

Внимание: Значения DayOfTheWeek соответствуют ISO 8601 (где Понедельник (Monday) является первым днем недели). Если хотите чтобы первым днем недели считалось Воскресение (Sunday) используйте функцию DayOfWeek вместо функции DayOfTheWeek.

Совет: Чтобы сделать возвращаемые значения более читабельными, используйте константы Day of week.

Возвращает день недели из значения TDateTime. Возвращаемое функцией значение находится в промежутке между 1 и 7, где Воскресение (Sunday) является первым днем недели, а Суббота (Saturday) — седьмым.

Внимание: Значения DayOfWeek не соответствуют ISO 8601 (где Понедельник (Monday) является первым днем недели). Если хотите чтобы первым днем недели считался Понедельник (Monday) используйте функцию DayOfTheWeek вместо функции DayOfWeek.

Наименование Вид
модуль
Описание
CheckSqlTimeStamp процедура
SqlTimSt
Проверяет соответствует ли значение TSQLTimeStamp правильной дате и времени.
CompareDate функция
DateUtils
Сравнивает два значения TDateTime между собой по значению даты.
CompareDateTime функция
DateUtils
Сравнивает два значения TDateTime между собой.
CompareTime функция
DateUtils
Сравнивает два значения TDateTime между собой по значению времени.
CurrentYear функция
SysUtils
Возвращает текущий год.
Date функция
SysUtils
Возвращает текущую дату.
DateDelta константа
SysUtils
Определяет различие между значениями TDateTime и TTimeStamp.
DateOf функция
DateUtils
«Вырезает» значение времени из TDateTime (устанавливает значение времени в 0, что означает полночь).
DateTimeToFileDate функция
SysUtils
Конвертирует объект TDateTime в формат времени операционной системы.
DateTimeToSQLTimeStamp функция
SqlTimSt
Конвертирует значение TDateTime в TSQLTimeStamp.
DateTimeToStr функция
SysUtils
Конвертирует значение TDateTime в строку.
DateTimeToString процедура
SysUtils
Конвертирует значение TDateTime в строку, используя указаный формат строки.
DateTimeToSystemTime процедура
SysUtils
Конвертирует значение TDateTime в системное время Win32 API.
DateTimeToTimeStamp функция
SysUtils
Конвертирует значение TDateTime в соответствующее значение TTimeStamp.
DateToStr функция
SysUtils
Конвертирует значение даты из TDateTime в строку.
Day of week константы
DateUtils
DayOf функция
DateUtils
Возвращает день месяца из значения TDateTime. Возвращаемое функцией значение находится в промежутке между 1 и 31.
DayOfTheMonth функция
DateUtils
Возвращает день месяца из значения TDateTime. Возвращаемое функцией значение находится в промежутке между 1 и 31.
DayOfTheWeek функция
DateUtils
DayOfTheYear функция
DateUtils
Возвращает количество дней между значением, указаным в TDateTime и 31 Декабря предыдущего года.
DayOfWeek функция
SysUtils
DaysBetween функция
DateUtils
Возвращает количество полных дней из промежутка времени, заданного двумя значениями TDateTime.
DaysInAMonth функция
DateUtils
Возвращает количество дней в указаном месяце указаного года.
DaysInAYear функция
DateUtils
Возвращает количество дней в указаном году.
DaysInMonth функция
DateUtils
Возвращает количество дней в месяце, заданом в значении TDateTime.
DaysInYear функция
DateUtils
Возвращает количество дней в году, заданом в значении TDateTime.
DaySpan функция
DateUtils
Возвращает количество дней, включая дробную часть, из промежутка времени, заданного двумя значениями TDateTime.
DecodeDate процедура
SysUtils
Возвращает значения Год, Месяц, День для значения TDateTime.
DecodeDateDay процедура
DateUtils
Возвращает год и день года для значения, указаного в TDateTime.
DecodeDateFully функция
SysUtils
Возвращает значения Год, Месяц, День, День_Недели для значения TDateTime.
DecodeDateMonthWeek процедура
DateUtils
Возвращает значения Год, Месяц, Неделя_Месяца, День_Недели для значения TDateTime.
DecodeDateTime процедура
DateUtils
Возвращает значения Год, Месяц, День, Час, Минута, Секунда, Милисекунда для значения TDateTime.
DecodeDateWeek процедура
DateUtils
Возвращает значения Год, Неделя_Года, День_Недели для значения TDateTime.
DecodeDayOfWeekInMonth процедура
DateUtils
Для заданного значения TDateTime возвращает Год, Месяц, День_Недели и Число_Дней_в_Этой_Неделе_для_Этого_Месяца.
DecodeTime процедура
SysUtils
Разбивает значение TDateTime на часы, минуты, секунды и милисекунды.
EncodeDate функция
SysUtils
Возвращает значение TDateTime, заданое как Год, Месяц, День.
EncodeDateDay функция
DateUtils
Возвращает значение TDateTime, заданое как указаный день указаного года.
EncodeDateMonthWeek функция
DateUtils
Возвращает значение TDateTime, заданое как указаный день указаной недели в указаном месяце и году.
EncodeDateTime функция
DateUtils
Возвращает значение TDateTime, заданое как Год, Месяц, День, Час, Секунда, Милисекунда.
EncodeDateWeek функция
DateUtils
Возвращает значение TDateTime, заданое как указаный день указаной недели в указаном году.
EncodeDayOfWeekInMonth функция
DateUtils
Возвращает значение TDateTime, заданое как положение дня недели в указаном месяце и году.
EncodeTime функция
SysUtils
Возвращает значение TDateTime, заданое как часы, минуты, секунды и милисекунды.
EndOfADay функция
DateUtils
Возвращает значение TDateTime которое представляет последнюю милисекнду указаного дня.
EndOfAMonth функция
DateUtils
Возвращает значение TDateTime которое представляет последнюю милисекнду последнего дня указаного месяца.
EndOfAWeek функция
DateUtils
Возвращает значение TDateTime которое представляет последнюю милисекнду последнего дня указаной недели.
EndOfAYear функция
DateUtils
Возвращает значение TDateTime которое представляет последнюю милисекнду последнего дня указаного года.
EndOfTheDay функция
DateUtils
Возвращает значение TDateTime которое представляет последнюю милисекнду дня, указаного в TDateTime.
EndOfTheMonth функция
DateUtils
Возвращает значение TDateTime которое представляет последнюю милисекнду последнего дня месяца, указаного в TDateTime.
EndOfTheWeek функция
DateUtils
Возвращает значение TDateTime которое представляет последнюю милисекнду последнего дня недели, указаной в TDateTime.
EndOfTheYear функция
DateUtils
Возвращает значение TDateTime которое представляет последнюю милисекнду последнего дня года, указаного в TDateTime.
FormatDateTime функция
SysUtils
Возвращает значение TDateTime в виде форматной строки. Если форматная строка не задана, то принимается та, которая основана на текущей локализации системы.
HourOf функция
DateUtils
Возвращает час дня, из значения TDateTime.
HourOfTheDay функция
DateUtils
Возвращает час дня, из значения TDateTime.
HourOfTheMonth функция
DateUtils
Возвращает количество часов между указаным в значении TDateTime и 12:00 AM первого дня месяца.
HourOfTheWeek функция
DateUtils
Возвращает количество часов между указаным в значении TDateTime и 12:00 AM первого дня недели.
HourOfTheYear функция
DateUtils
Возвращает количество часов между указаным в значении TDateTime и 12:00 AM первого дня года.
HoursBetween функция
DateUtils
Возвращает количество полных часов между двумя значениями TDateTime.
HourSpan функция
DateUtils
Возвращает количество часов, включая дробную часть, между двумя значениями TDateTime.
IncAMonth процедура
SysUtils
Увеличивает дату на один месяц.
IncDay функция
DateUtils
Возвращает дату, сдвинутую на указаное число дней.
IncHour функция
DateUtils
Возвращает дату/время, сдвинутую на указаное число часов.
IncMilliSecond функция
DateUtils
Возвращает дату/время, сдвинутую на указаное число милисекунд.
IncMinute функция
DateUtils
Возвращает дату/время, сдвинутую на указаное число минут.
IncMonth функция
SysUtils
Возвращает дату, сдвинутую на указаное число месяцев.
IncSecond функция
DateUtils
Возвращает дату/время, сдвинутую на указаное число секунд.
IncWeek функция
DateUtils
Возвращает дату, сдвинутую на указаное число недель.
IncYear функция
DateUtils
Возвращает дату, сдвинутую на указаное количество лет.
IsInLeapYear функция
DateUtils
Показывает, принадлежит ли значение, указаное в TDateTime, високосному году.
IsLeapYear функция
SysUtils
Показывает, является ли указаный год високосным.
IsPM функция
DateUtils
Показывает, принадлежит ли значение времени, указаное в TDateTime, второй половине дня .
IsSameDay функция
DateUtils
Показывает, принадлежит ли значение, указаное в TDateTime, заданой дате.
IsToday функция
DateUtils
Показывает, принадлежит ли значение, указаное в TDateTime, текущей дате.
IsValidDate функция
DateUtils
Проверяет, являются ли указаные год, месяц и день допустимой датой.
IsValidDateDay функция
DateUtils
Проверяет, являются ли указаные год и день года допустимой датой.
IsValidDateMonthWeek функция
DateUtils
Проверяет, являются ли указаные год, месяц, неделя месяца и день недели допустимой датой.
IsValidDateTime функция
DateUtils
Проверяет, являются ли указаные год, месяц, день, час, минута, секунда и милисекунда допустимыми значениями даты и времени.
IsValidDateWeek функция
DateUtils
Проверяет, являются ли указаные год, неделя года и день недели допустимой датой.
IsValidTime функция
DateUtils
Проверяет, являются ли указаные час, минута, секунда и милисекунда допустимыми значениями даты и времени.
MilliSecondOf функция
DateUtils
Возвращает милисекунды из значения TDateTime.
MilliSecondOfTheDay функция
DateUtils
Возвращает количество милисекунд, прошедшее между значением указаным в TDateTime и началом этого самого дня.
MilliSecondOfTheHour функция
DateUtils
Возвращает количество милисекунд, прошедшее между значением указаным в TDateTime и началом этого самого часа.
MilliSecondOfTheMinute функция
DateUtils
Возвращает количество милисекунд, прошедшее между значением указаным в TDateTime и началом этой самой минуты.
MilliSecondOfTheMonth функция
DateUtils
Возвращает количество милисекунд, прошедшее между значением указаным в TDateTime и началом месяца.
MilliSecondOfTheSecond функция
DateUtils
Возвращает милисекунды из значения TDateTime.
MilliSecondOfTheWeek функция
DateUtils
Возвращает количество милисекунд, прошедшее между значением указаным в TDateTime и 12:00:00:00 AM первого дня недели.
MilliSecondOfTheYear функция
DateUtils
Возвращает количество милисекунд, прошедшее между значением указаным в TDateTime и 12:00:00:00 AM первого дня года.
MilliSecondsBetween функция
DateUtils
Возвращает количество милисекунд между двумя значениями TDateTime.
MilliSecondSpan функция
DateUtils
Возвращает количество милисекунд между двумя значениями TDateTime. Но в качестве результата вместо целого типа испльзуется число с плавающей точкой.
MinuteOf функция
DateUtils
Возвращает минуты из значения TDateTime.
MinuteOfTheDay функция
DateUtils
Возвращает количество минут между значением указаным в TDateTime и 12:00 AM того же дня.
MinuteOfTheHour функция
DateUtils
Возвращает количество минут, прошедшее между значением указаным в TDateTime и началом этого самого часа.
MinuteOfTheMonth функция
DateUtils
Возвращает количество минут, прошедшее между значением указаным в TDateTime и 12:00 AM первого дня месяца.
MinuteOfTheWeek функция
DateUtils
Возвращает количество минут, прошедшее между значением указаным в TDateTime и 12:00 AM первого дня недели.
MinuteOfTheYear функция
DateUtils
Возвращает количество минут, прошедшее между значением указаным в TDateTime и 12:00 AM первого дня года.
MinutesBetween функция
DateUtils
Возвращает количество полных минут между двумя значениями TDateTime.
MinuteSpan функция
DateUtils
Возвращает количество минут, включая дробную часть, между двумя значениями TDateTime.
MonthOf функция
DateUtils
Возвращает месяц года из значения TDateTime.
MonthOfTheYear функция
DateUtils
Возвращает месяц года из значения TDateTime.
MonthsBetween функция
DateUtils
Возвращает количество полных месяцев между двумя значениями TDateTime.
MonthSpan функция
DateUtils
Возвращает количество месяцев, включая дробную часть, между двумя значениями TDateTime.
MSecsToTimeStamp функция
SysUtils
Конвертирует указаное количество милисекунд в значение TTimeStamp.
Now функция
SysUtils
Возвращает текущие дату и время.
NthDayOfWeek функция
DateUtils
Возвращает сколько дней, с таким же порядковым номером дня недели, было в текущем месяце, представленом значением TDateTime.
NullSQLTimeStamp константа
SqlTimSt
Значение NULL для TSQLTimeStamp.
OneHour Constant;
OneMillisecond Constant;
OneMinute Constant;
OneSecond Constant
константы
DateUtils
Обратные константы времени в модуле Delphi.
RecodeDate функция
DateUtils
Меняет в TDateTime значение даты на новые значения Год, Месяц, День. В случае неудачи вызывает исключение EConvertError.
RecodeDateTime функция
DateUtils
Выборочно изменяет в TDateTime значения Год, Месяц, День, Час, Секунда, Милисекунда на заданые. В случае неудачи вызывает исключение EConvertError.
RecodeDay функция
DateUtils
Меняет значение День месяца в TDateTime на заданое. В случае неудачи вызывает исключение EConvertError.
RecodeHour функция
DateUtils
Меняет значение Час дня в TDateTime на заданое. В случае неудачи вызывает исключение EConvertError.
RecodeMilliSecond функция
DateUtils
Меняет значение Милисекунда в TDateTime на заданое. В случае неудачи вызывает исключение EConvertError.
RecodeMinute функция
DateUtils
Меняет значение Минута часа в TDateTime на заданое. В случае неудачи вызывает исключение EConvertError.
RecodeMonth функция
DateUtils
Меняет значение Месяц года в TDateTime на заданое. В случае неудачи вызывает исключение EConvertError.
RecodeSecond функция
DateUtils
Меняет значение Секунда часа в TDateTime на заданое. В случае неудачи вызывает исключение EConvertError.
RecodeTime функция
DateUtils
Меняет в TDateTime значение времени на новые значения Час, Минута, Секунда, Милисекунда. В случае неудачи вызывает исключение EConvertError.
RecodeYear функция
DateUtils
Меняет значение Год в TDateTime на заданое. В случае неудачи вызывает исключение EConvertError.
ReplaceDate процедура
SysUtils
Заменяет значение даты в TDateTime на заданое.
ReplaceTime процедура
SysUtils
Заменяет значение времени в TDateTime на заданое.
SameDate функция
DateUtils
Показывает, представляют ли два значения TDateTime тот же самый год, месяц и день.
SameDateTime функция
DateUtils
Показывает, представляют ли два значения TDateTime те же самые год, месяц, день, час, секунда, милисекунда.
SameTime функция
DateUtils
Показывает, совпадают ли значения времени в двух значениях TDateTime.
SecondOf функция
DateUtils
Возвращает количество секунд минуты из значения TDateTime.
SecondOfTheDay функция
DateUtils
Возвращает количество секунд между значением указаным в TDateTime и 12:00:00 AM того же самого дня.
SecondOfTheHour функция
DateUtils
Возвращает количество секунд между значением указаным в TDateTime и началом того же самого часа.
SecondOfTheMinute функция
DateUtils
Возвращает количество секунд между значением указаным в TDateTime и началом той же самой минуты.
SecondOfTheMonth функция
DateUtils
Возвращает количество секунд между значением указаным в TDateTime и 12:00:00 AM первого дня месяца.
SecondOfTheWeek функция
DateUtils
Возвращает количество секунд между значением указаным в TDateTime и 12:00:00 AM первого дня недели.
SecondOfTheYear функция
DateUtils
Возвращает количество секунд между значением указаным в TDateTime и 12:00:00 AM первого дня года.
SecondsBetween функция
DateUtils
Возвращает количество секунд между двумя значениями TDateTime.
SecondSpan функция
DateUtils
Возвращает количество секунд, включая дробную часть, между двумя значениями TDateTime.
SQLDayOfWeek функция
SqlTimSt
Возвращает день недели из значения TSQLTimeStamp. Возвращаемое функцией значение находится в промежутке между 1 и 7, где Воскресение (Sunday) является первым днем недели, а Суббота (Saturday) — седьмым.
SQLTimeStampToDateTime функция
SqlTimSt
Конвертирует значение TSQLTimeStamp в TDateTime.
SQLTimeStampToStr функция
SqlTimSt
Конвертирует значение TSQLTimeStamp в строку.
StartOfADay функция
DateUtils
Возвращает значение TDateTime которое представляет 12:00:00:00 AM указаного дня.
StartOfAMonth функция
DateUtils
Возвращает значение TDateTime которое представляет 12:00:00:00 AM первого дня указаного месяца.
StartOfAWeek функция
DateUtils
Возвращает значение TDateTime которое представляет первый момент указаного дня указаной недели.
StartOfAYear функция
DateUtils
Возвращает значение TDateTime которое представляет первый момент первого дня указаного года.
StartOfTheDay функция
DateUtils
Возвращает значение TDateTime которое представляет 12:00:00:00 AM дня, заданого значением TDateTime.
StartOfTheMonth функция
DateUtils
Возвращает значение TDateTime которое представляет 12:00:00:00 AM первого дня месяца, заданого значением TDateTime.
StartOfTheWeek функция
DateUtils
Возвращает значение TDateTime которое представляет 12:00:00:00 AM первого дня недели, заданой значением TDateTime.
StartOfTheYear функция DateUtils Возвращает значение TDateTime которое представляет 12:00:00:00 AM первого дня года, заданого значением TDateTime.
StrToDate функция
SysUtils
Конвертирует строку с датой в TDateTime. В случае неудачи вызывает исключение EConvertError.
StrToDateDef функция
SysUtils
Конвертирует строку с датой в TDateTime со значением по умолчанию в случае ошибки.
StrToDateTime функция
SysUtils
Конвертирует строку в значение TDateTime. В случае неудачи вызывает исключение EConvertError.
StrToDateTimeDef функция
SysUtils
Конвертирует строку в значение TDateTime со значением по умолчанию в случае ошибки.
StrToSQLTimeStamp функция
SqlTimSt
Конвертирует строку в значение TSQLTimeStamp. В случае неудачи вызывает исключение EConvertError.
StrToTime функция
SysUtils
Конвертирует строку со временем в значение TDateTime. В случае неудачи вызывает исключение EConvertError.
StrToTimeDef функция
SysUtils
Конвертирует строку со временем в значение TDateTime со значением по умолчанию в случае ошибки.
SystemTimeToDateTime функция
SysUtils
Конвертирует значение системного времени в значение TDateTime.
Time модульные константы
SysUtils
Значения констант для вычисления времени.
Time,
GetTime
функции
SysUtils
Возвращают текущее время.
TimeOf функция
DateUtils
Убирает значение даты из значения TDateTime.
TimeStampToDateTime функция
SysUtils
Конвертирует значение TTimeStamp в соответствующее значение TDateTime.
TimeStampToMSecs функция
SysUtils
Конвертирует значение TTimeStamp в TTimeStamp в абсолютное число милисекунд.
TimeToStr функция
SysUtils
Конвертирует значение времени из TDateTime в строку.
Today функция
DateUtils
Возвращает значение TDateTime, представляющее текущую дату.
Tomorrow функция
DateUtils
Возвращает значение TDateTime, представляющее следующий день.
TryEncodeDate функция
SysUtils
Создает значение TDateTime, предсталяющее указаный Год, Месяц, День. В случае неудачи возвращает False.
TryEncodeDateDay функция
DateUtils
Вычисляет значение TDateTime которое представляет указаный день для указаного года. В случае неудачи возвращает False.
TryEncodeDateMonthWeek функция
DateUtils
Вычисляет значение TDateTime которое представляет указаный день указаной недели в указаном месяце и году. В случае неудачи возвращает False.
TryEncodeDateTime функция
DateUtils
Вычисляет значение TDateTime которое представляет указаные год, месяц, день, час, минуту, секунду и милисекунду. В случае неудачи возвращает False.
TryEncodeDateWeek функция
DateUtils
Вычисляет значение TDateTime которое представляет указаный день указаной недели в указаном году. В случае неудачи возвращает False.
TryEncodeDayOfWeekInMonth функция
DateUtils
Вычисляет значение TDateTime которое представляет указаный день недели в указаном месяце и году. В случае неудачи возвращает False.
TryEncodeTime функция
SysUtils
Создает значение TDateTime для заданых значений Час, Минута, Секунда и Милисекунда. В случае неудачи возвращает False.
TryRecodeDateTime функция
DateUtils
Выборочно меняет значения Год, Месяц, День, Час, Секунда, Милисекунда в указаном TDateTime. В случае неудачи возвращает False.
TryStrToDate функция
SysUtils
Конвертирует строку с датой в TDateTime. В случае неудачи возвращает False.
TryStrToDateTime функция
SysUtils
Конвертирует строку в значение TDateTime. В случае неудачи возвращает False.
TryStrToSQLTimeStamp функция
SqlTimSt
Конвертирует строку в значение TSQLTimeStamp. В случае неудачи возвращает False.
TryStrToTime функция
SysUtils
Конвертирует строку со временем в значение TDateTime. В случае неудачи возвращает False.
UnixDateDelta константа
SysUtils
Определяет разницу между значениями TDateTime и TIME_T. Тип TIME_T используется в системах Unix и Lnux, а так же в стандартных библиотеках C.
WeekOf функция
DateUtils
Возвращает неделю года из значения TDateTime.
WeekOfTheMonth функция
DateUtils
Возвращает неделю месяца из значения TDateTime.
WeekOfTheYear функция
DateUtils
Возвращает неделю года из значения TDateTime.
WeeksBetween функция
DateUtils
Возвращает количество полных недель между двумя значениями TDateTime.
WeeksInAYear функция
DateUtils
Возвращает количество недель в указаном году.
WeeksInYear функция
DateUtils
Возвращает количество недель в году из значения TDateTime.
WeekSpan функция
DateUtils
Возвращает количество недель, включая дробную часть, между двумя значениями TDateTime.
WithinPastDays функция
DateUtils
Показывает, находятся ли две даты в заданом промежутке дней относительно друг друга.
WithinPastHours функция
DateUtils
Показывает, находятся ли два значения даты/времени в заданом промежутке часов относительно друг друга.
WithinPastMilliSeconds функция
DateUtils
Показывает, находятся ли два значения даты/времени в заданом промежутке милисекунд относительно друг друга.
WithinPastMinutes функция
DateUtils
Показывает, находятся ли два значения даты/времени в заданом промежутке минут относительно друг друга.
WithinPastMonths функция
DateUtils
Показывает, находятся ли два значения даты/времени в заданом промежутке месяцев относительно друг друга.
WithinPastSeconds функция
DateUtils
Показывает, находятся ли два значения даты/времени в заданом промежутке секунд относительно друг друга.
WithinPastWeeks функция
DateUtils
Показывает, находятся ли два значения даты/времени в заданом промежутке недель относительно друг друга.
WithinPastYears функция
DateUtils
Показывает, находятся ли два значения даты/времени в заданом промежутке лет относительно друг друга.
YearOf функция
DateUtils
Возвращает Год из значения TDateTime.
YearsBetween функция
DateUtils
Возвращает приблизительное количество лет между двумя значениями TDateTime.
YearSpan функция
DateUtils
Возвращает приблизительное количество лет, включая дробную часть, между двумя значениями TDateTime.
Yesterday функция
DateUtils
Возвращает значение TDateTime которое соответствует предыдущему дню.

Содержание

Тип TDateTime.

Тип TDateTime — это основной тип в Delphi для работы с датой и временем. Он является числом с плавающей запятой, целая часть которого содержит число дней, отсчитанное от некоторого начала календаря, а дробная часть равна части 24-часового дня, т.е. характеризует время и не относится к дате. Для 32-разрядных версий Delphi за начало календаря принята дата 12/30/1899, 12 часов.

Ниже приведены несколько примеров значения TDateTime и соответсвующие им дата и время:

12/30/1899 12:00 am
2.75 1/1/1900 6:00 pm
-1.25 12/29/1899 6:00 am
35065 1/1/1996 12:00 am

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

Когда обрабатываются отрицательные значения TDateTimes, то вычисление дробной части производится отдельно. Дробная часть отражает часть 24-часового дня не зависимо от знака значения TDateTime. Например, 6:00 am on 12/29/1899 это –1.25, а неt –1 + 0.25, что составило бы –0.75. Значений TDateTime между –1 и 0 не существует. Cовет: В модулях SysUtils и DateUtils для работы с датой и временем имеется большое количество процедур и функций на все случаи жизни. Не заморачивайтесь с обственными вычислениями, не изобретайте велосипед, а пользуйтесь уже готовыми наработками разработчиков Delphi. (См. Функции и процедуры Delphi для работы с датой и временем.) Оно надежнее.

Примечание: В Delphi 1 за начало отсчета принят год 1, т.е. для перевода даты Delphi 1 в дату последующих версий Delphi надо вычесть из даты число 693594.

Содержание

Тип TTimeStamp.

TTimeStamp представляет значения дата и время.

Используйте TTimeStamp если требуется повышеная точность представления значения времени в знчениях дата/время. Если нет необходимости сохранять значение времени с точностью до милисекунд, используйте более компактное TDateTime. Если необходима еще большая точность, то используйте TSQLTimeStamp (но НЕ назначайте его типом Variant).

Поле Time field показывает количество милисекунд, прошедших с полуночи.

Поле Data показывает число календарных дней от начала календаря (число дней с 1/1/0001 плюс один).

Содержание

Тип TSQLTimeStamp.

TSQLTimeStamp представляет значения даты и времени с очень высокой точностью.

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

  • Year определяет год от 1 до 9999.
  • Month определяет месяц от 1 до 12.
  • Day определяет день месяца, от 1 до 28, 29, 30, или 31, в зависимости от значения Month.
  • Hour определяет час от 0 до 23.
  • Minute и Second могут колебаться от 0 до 59.
  • Fractions определяет милисекунды от 0 до 999.

Используя функцию VarSQLTimeStampCreate, Вы можете создать тип Variant который представляет значение TSQLTimeStamp. Фактически, простейший путь манипулирования значениями SQLTimeStamp это создать подобный Variant и использовать встроеные операторы, обеспечивающие работу с Variant.

Функции Delphi

Стандартные функции Delphi:

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

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

откуда ln — функция, вычисляющая натуральный логарифм числа exp(x), exp — функция, вычисляющая экспоненту в степени x, x — число, n-ую степень которого надо найти, а n — степень числа x. Каждая функция обладает следующими характеристиками: тип значений, тип параметров.

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

Математические функции Delphi:

Библиотеки языка Delphi включаются в себя и множество математических функций:

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

где a выражает угол в градусах; 3.1415926 означает число pi. На месте константы 3.1415926 с дробной частью для достижения большей точности чаще всего пользуются стандартной именованной константой pi. Тогда выражения для угла в пересчете в радианы будет выглядеть следующим образом:

Функции преобразования Delphi:

Наиболее частое использование функций преобразования связано с инструкциями, которые обеспечивают ввод/вывод какой-либо информации. Например, для вывода значения переменной c типом real в поле вывода диалогового окна (компонент Label), нужно провести преобразование числа в строку символов, которая собственно изображает данное число. Это можно достичь, применяя функцию FloatToStr, которая заменяет значение выражения (оно указано как параметр функции) его строковым представлением.

Пример.

В приведенном примере значение переменной m будете выведено в поле Label. В таблице ниже Вам будут представлены основные функции преобразования Delphi:

Применение функций Delphi:

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

Примеры.

Структура функции Delphi

Как организована инструкция функции в языке Delphi? В любом языке программирования на первом этапе описания функции указывается ее заголовок. Далее за заголовком программист описывает раздел объявления констант const (если таковы имеются), затем занимается описанием раздела объявления типов type, далее следует раздел объявления переменных var и, наконец, раздел инструкций.

В приведенном примере в заголовке функции вначале указывается зарезервированное слово function, а следом идет имя функции. Далее в скобках программист перечисляет список параметров, и вслед за ним, используя символ «:», указывает тип значения функции. В конце каждого заголовка стоит символ «;». После заголовка следуют раздел констант, раздел типов, раздел переменных. Внутри раздела инструкций кроме констант и переменных, описанных соответственно в разделах const и var, может находится переменная result.

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

EndOfADay — Функция Delphi

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

О подпрограммах в Object Pascal

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

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

Использование подпрограммы состоит из 2 этапов: сначала подпрограмму описывают, а затем, уже в блоке инструкций программы, вызывают. Отметим, что в библиотеке Delphi имеется описание тысяч готовых подпрограмм, описывать которые, разумеется, уже не надо. А их вызовом мы уже неоднократно занимались — достаточно взглянуть на любой пример, где мы встречали инструкции, подобные таким:

write(‘Hello, world!’); readln;

Здесь и write, и readln — стандартные подпрограммы Object Pascal. Таким образом, с вызовом подпрограмм мы уже знакомы. Осталось узнать, как создавать собственные, или пользовательские, подпрограммы. Но прежде отметим, что все подпрограммы делятся на 2 лагеря: процедуры и функции. Мы уже использовали эти термины, и даже давали им описание, однако повторимся: процедуры — это такие подпрограммы, которые выполняют предназначенное действие и возвращают выполнение в точку вызова. Функции в целом аналогичны процедурам, за тем исключением, что они еще и возвращают результат своего выполнения. Результатом работы функции могут быть данные любого типа, включая объекты.

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

Как процедурам, так и функциям могут передаваться данные для обработки. Делается это при помощи списка параметров. Список параметров в описании подпрограммы и список аргументов, указываемых при ее вызове должен совпадать. Иначе говоря, если в описании определено 2 параметра типа Integer, то, вызывая такую подпрограмму, в качестве аргументов так же следует указать именно 2 аргумента и именно типа Integer или совместимого (скажем, Word или Int64).

ПРИМЕЧАНИЕ
На самом деле, Object Pascal позволяет довольно гибко обращаться с аргументами, для чего имеются различные методы, включая «перегружаемые» функции, значения параметров по умолчанию и т.д. Тем не менее, в типичном случае, количество, тип, и порядок перечисления аргументов при объявлении и при вызове процедуры или функции, должны совпадать.

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

Процедуры

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

Заголовок состоит из ключевого слова procedure, за которым следует имя процедуры и, при необходимости, список параметров, заключенных в круглые скобки:

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

ПРИМЕЧАНИЕ
Вопросы локальных и глобальных переменных, и вообще видимости в программах, будет рассмотрен позже в этой главе.

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

procedure TriplePrint(str: string); var i: integer; begin for i := 1 to 3 do begin writeln(‘»‘+str+'»‘); end; // конец цикла for end; // конец процедуры TriplePrint

Здесь мы определили процедуру TriplePrint, которая будет трижды выводить переданную ей в качестве аргумента строку, заключенную в двойные кавычки. Как видно, данная процедура имеет все составные части: ключевое слово procedure, имя, список параметров (в данном случае он всего один — строковая переменная str), блок объявления собственных переменных (целочисленная переменная i), и собственное тело, состоящее из оператора цикла for.

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

Отметим так же, что рассмотренная нами процедура сама содержит вызов другой процедуры — writeln. Процедуры могут быть встроенными. Иначе говоря, объявление одной процедуры можно помещать в заголовочную часть другой. Например, наша процедура TriplePrint может иметь вспомогательную процедуру, которая будет «подготавливать» строку к выводу. Для этого перед объявлением переменной i, разместим объявление еще одной процедуры. Назовем ее PrepareStr:

procedure PrepareStr; begin str := ‘»‘+str+'»‘; end;

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

Таким образом, мы получаем две процедуры, одна из которых (TriplePrint) может использоваться во всей программе, а другая (PrepareStr) — только внутри процедуры TriplePrint. Чтобы преимущество использования процедур было очевидно, рассмотрим их на примере программы, которая будет использовать ее неоднократно, для чего обратимся к листингу 6.1 (см. так же пример в Demo\Part1\Procs).

Листинг 6.1. Использование процедур

program procs; <$APPTYPE CONSOLE>procedure TriplePrint(str: string); procedure PrepareStr; begin str := ‘»‘+str+'»‘; end; var i: integer; begin PrepareStr; for i := 1 to 3 do begin writeln(str); end; end; // конец процедуры TriplePrint begin // начало тела основной программы TriplePrint(‘Hello. ‘); // первый вызов TriplePrint TriplePrint(‘How are you. ‘); // 2-й вызов TriplePrint(‘Bye. ‘); // 3-й readln; end.

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

Функции

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

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

Рассмотрим пример функции, которая будет возвращать куб числа, переданного ей в качестве аргумента:

function cube(value: integer) : integer; result := value * value * value; >

Здесь определена функция, имеющая параметр value типа целого числа, которое она возводит в третью степень путем троекратного умножения, и результат присваивается специальной переменной result. Таким образом, чтобы в любом месте программы вычислить значение числа в 3-й степени, достаточно написать такое выражение:

В результате выполнения этого выражения переменной x будет присвоено значение 27. Данный пример иллюстрирует использование функций в классическом случае — для явного вычисления значения переменной. Однако функции могут использоваться в выражениях и напрямую. Например, можно поставить вызов функции cube в каком-либо месте арифметического выражения подобно обычной переменной:

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

procedure TriplePrint(str: string); function PrepareStr(s: string) : string; begin result := ‘»‘+s+'»‘; end; var i: integer; begin for i := 1 to 3 do begin writeln(PrepareStr(str)); // функция использована как переменная end; end;

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

function cube(value: integer) : integer; cube := value * value * value; >

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

Рекурсия

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

Рассмотрим вопрос рекурсии на следующем примере:

function recfunc(x: integer) : integer begin dec(x); // функция декремента, уменьшает целое на 1 if x > 5 then x := recfunc(x); result := 0; // возвращаемое значение тут не используется end;

Здесь мы объявили функцию recfunc, принимающую один аргумент, и вызывающую саму себя до тех пор, пока значение этого аргумента больше 5. Хотя на первый взгляд может показаться, что такое поведение функции похоже на обычный цикл, на самом деле все работает несколько по-иному: если вы вызовите ее со значением 8, то она выдаст вам 3 сообщения в следующей последовательности: 5, 6, 7. Иначе говоря, функция вызывала саму себя до тех пор, пока значение x было больше 5, и собственно вывод сообщений начала 3-я по уровню получившейся вложенности функция, которая и вывела первое сообщение (в данном случае им стало 5, т.е. уменьшенное на единицу 6).

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

Листинг 6.2. Рекурсия с комментариями

program recurse; <$APPTYPE CONSOLE>function recfunc(x, depth: integer) : integer; begin dec(x); if x > 5 then begin write(‘Current recursion depth is: ‘); write(depth); write(‘, current x value is: ‘); writeln(x); inc(depth); depth:=recfunc(x, depth); end else writeln(‘End of recursive calls. ‘); write(‘Current recursion depth is: ‘); write(depth); write(‘, current x value is: ‘); writeln(x); dec(depth); result := depth; end; begin recfunc(8,0); readln; end.

Исходный код находится в Demo\Part1\Recurse, там же находится и исполняемый файл recurse.exe, результат работы которого вы можете увидеть на своем экране.

Использование параметров

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

procedure Circle (square: real; var radius, length: real);

Данная процедура принимает «на обработку» одно значение — площадь (square), а возвращает через свои параметры два — радиус (radius) и длину окружности (length). Практическая ее реализация может выглядеть таким образом:

procedure Circle (square: real; var radius, length: real); begin radius := sqrt(square / pi); // функция pi возвращает значение числа ? length := pi * radius * 2; end;

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

var r,l: real; . Circle(100,r,l);

После вызова функции Circle, переменные r и l получат значения радиуса и длины окружности. Остается их вывести при помощи writeln. Исходный код программы приведен в листинге 6.3.

Листинг 6.3. Процедура с параметрами

program params; <$APPTYPE CONSOLE>procedure Circle (square: real; var radius, length: real); begin //функция sqrt извлекает корень, а функция pi возвращает значение числа ? radius := sqrt(square / pi); length := pi * radius * 2; end; var r,l: real; begin Circle(100,r,l); writeln(r); writeln(l); readln; end.

Запустив такую программу, можно убедиться, что она работает и выводит верные результаты, однако вид у них получается довольно-таки неудобочитаемый, например, длина окружности будет представлена как «3,54490770181103E+0001». Чтобы сделать вывод более удобным для восприятия, нам понадобится функция FloatToStrF. С ее помощью мы можем определить вывод числа на свое усмотрение, например:

Кроме того, не помешало бы указать, где радиус, а где — длина окружности. Для этого модернизируем строки вывода результатов следующим образом:

writeln(‘Radius is: ‘+FloatToStrF(r,ffFixed,12,8)); writeln(‘Length is: ‘+FloatToStrF(l,ffFixed,12,8));

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

. var s,r,l: real; begin write(‘Input square: ‘); readln(s); Circle(s,r,l); writeln(‘Radius is: ‘+FloatToStrF(r,ffFixed,12,8)); writeln(‘Length is: ‘+FloatToStrF(l,ffFixed,12,8)); readln; end.

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

Таким образом, в случае, если введенное пользователем значение окажется нулевым или отрицательным, выполнение процедуры будет прекращено. Но возникает другой вопрос: как сообщить программе о том, что вычисления не были выполнены? Пожалуй, в данном случае следовало бы заменить процедуру функцией, которая возвращала бы истину, если вычисления произведены, и ложь в противном случае. Вот что у нас получится:

function Circle(square: real; var radius, length: real) : boolean; begin result := false; if (square

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

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

if Circle(s,r,l) then begin // вывод end else // сообщить об ошибке

Результатом проделанной работы будет программа, приведенная в листинге 6.4. Она же находится в Demo\Part1\Params.

Листинг 6.4. Функция с параметрами

program params; <$APPTYPE CONSOLE>uses sysutils; //этот модуль соджержит функцию FloatToStrF function Circle(square: real; var radius, length: real) : boolean; begin result := false; if (square

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

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

function MyBetterFunc(val1: integer; const val2: integer = 2); begin result := val1*val2; end;

Обращение же к такой функции может иметь 2 варианта: с указанием только одного аргумента (для параметра val1), или же с указанием обоих:

x := MyBetterFunc(5); // получим 10 x := MyBetterFunc(5,4); // получим 20

Оба вызова будут верными, просто в первом случае для второго параметра будет использовано значение, заданное по умолчанию.

Области видимости

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

program Project1; procedure Proc1; var a: integer; begin a := 5; //верно. Локальная переменная a здесь видна end; begin a := 10; //Ошибка! Объявленная в процедуре Proc1 переменнаая здесь не видна end.

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

program Project2; var a: integer; // глобальная переменная a procedure Proc1; begin a := 5; // верно b := 10; // Ошибка! Переменая b на этот момент еще не объявлена end; var b: integer; // глобальная переменная b begin a := 10; // верно b := 5; // тоже верно. Здесь видны все г var a: integer; // глобальная переменная end.

Теперь рассмотрим такой вариант, когда у нас имеются 2 переменных с одним и тем же именем. Разумеется, компилятор еще на стадии проверки синтаксиса не допустит, чтобы в программе были объявлены одноименные переменные в рамках одного диапазона видимости (скажем, 2 глобальных переменных X, или 2 локальных переменных X в одной и той же подпрограмме). Речь в данном случае идет о том, что произойдет, если в одной и той же программе будет 2 переменных X, одна — глобальная, а другая — локальная (в какой-либо подпрограмме). Если с основным блоком программы все ясно — в нем будет присутствовать только глобальная X, то как быть с подпрограммой? В таком случае в действие вступает правило близости, т.е. какая переменная ближе (по структуре) к данному модулю, та и есть верная. Применительно к подпрограмме ближней оказывается локальная переменная X, и именно она будет задействована внутри подпрограммы.

program Project3; var X: integer; procedure Proc1; var X: integer; begin X := 5; // Здесь значение будет присвоено локальной переменной X end; begin X := 10; // Здесь же значение будет присвоено голобальной переменной X end.

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

program Project1; procedure Proc1; procedure SubProc; begin end; begin SubProc; // Верно. Вложенная процедура здесь видна. end; begin Proc1; // Верно. Процедура Proc1 объявлена в зоне глобальной видимости SubProc; // Ошибка! Процедура SubProc недоступна за пределами Proc1. end.

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

Видимость в модулях

Все то, что мы уже рассмотрели, касалось программ, умещающихся в одном единственном файле. На практике же, особенно к тому моменту, когда мы перейдем к визуальному программированию, программы будут включать в себя множество файлов. В любом случае, программа на Object Pascal будет иметь уже изученный нами файл проекта — dpr, или основной модуль программы. Все прочие файлы будут располагаться в других файлах, или модулях (units), с типичным для Pascal расширением pas. При объединении модулей в единую программу возникает вопрос видимости переменных, а так же процедур и функций в различных модулях.

Для начала вернемся к рассмотрению структуры модуля, которая имеет ряд отличий от структуры программы. Итак, в простейшем случае, модуль состоит из названия, определяемого при помощи ключевого слова unit, и 2 секций — interface и implementation. Так вот как раз первая секция, interface, и служит для определения (декларации) типов данных, переменных, функций и процедур данного модуля, которые должны быть доступны за пределами данного модуля.

Чтобы лучше в этом разобраться, создадим программу, состоящую из 2 модулей — основного (dpr) и дополнительного (pas). Для этого сначала создайте новый проект типа Console Application, а затем добавьте к нему модуль, для чего из подменю File ‘ New выберите пункт Unit. После этого сохраните проект, щелкнув по кнопке Save All (или File ‘ Save All). Обратите внимание, что первым будет предложено сохранить не файл проекта, а как раз файл дополнительного модуля. Назовем его extunit.pas, а сам проект — miltiunits (см. Demo\Part1\Visibility). При этом вы увидите, что в части uses файла проекта произошло изменение: кроме постоянно добавляемого модуля SysUtils, появился еще один модуль — extunit, т.е. код стал таким:

uses SysUtils, extunit in ‘extunit.pas’;

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

uses SysUtils, extunit;

Тем не менее, оставим код как есть, и приступим к разработке модуля extunit. В нем, в части implementation, напишем 2 процедуры — ExtProc1 и ExtProc2. Обе они будут делать одно и то же — выводить строку со своим названием. Например, для первой:

Теперь вернемся к главному модулю программы и попробуем обратиться к процедуре ExtProc1:

. begin ExtProc1; end.

Попытка компиляции или запуска такой программы приведет к ошибке компилятора «Undeclared identifier», что означает «неизвестный идентификатор». И действительно, одного лишь описания процедуры недостаточно, чтобы она была доступна вне своего модуля. Так что перейдем к редактированию extunit и в секции interface напишем строку:

Такая строка, помещенная в секцию interface, является объявлением процедуры ExtProc1, и делает ее видимой вне данного модуля. Отметим, что в секции interface допускается лишь объявлять процедуры, но не определять их (т.е. тело процедуры здесь будет неуместно). Еще одним полезным эффектом от объявления процедур является то, что таким образом можно обойти такое ограничение, как необходимость определения подпрограммы до ее вызова. Иначе говоря, поскольку в нашем файле уже есть 2 процедуры, ExtProc1и ExtProc2, причем они описаны именно в таком порядке — сначала ExtProc, а потом ExtProc2, то выведя объявление ExtProc2 в interface, мы сможем обращаться к ExtProc2 из ExtProc1, как это показано в листинге 6.5:

Листинг 6.5. Объявление процедур в модуле

unit extunit; interface procedure ExtProc1; procedure ExtProc2; implementation procedure ExtProc1; begin writeln(‘ExtProc1’); ExtProc2; // Если объявления не будет, то компилятор выдаст ошибку end; procedure ExtProc2; begin writeln(‘ExtProc2’); end; end.

Отметим, что теперь процедуры ExtProc2, так же, как и ExtProc1, будет видна не только по всему модулю extunit, но и во всех использующей этот модуль программе multiunits.

Разумеется, все, что было сказано о процедурах, верно и для функций. Кроме того, константы и переменные, объявленные в секции interface, так же будут видны как во всем теле модуля, так и вне него. Остается лишь рассмотреть вопрос пересечения имен, т.е. когда имя переменной (константы, процедуры, функции) в текущем модуле совпадает с таковым в подключенном модуле. В этом случае вновь вступает в силу правило «кто ближе, тот и прав», т.е. будет использоваться переменная из данного модуля. Например, если в extunit мы объявим типизированную константу Z, равную 100, а в multiunits — одноименную константу, равную 200, то обратившись к Z из модуля extunit, мы получим значение 100, а из multiunits — 200.

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

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

Некоторые стандартные функции

В Object Pascal, как уже отмечалось, имеются огромное количество стандартных процедур и функций, являющихся составной частью языка, и с некоторыми мы уже знакомы (например, приведенные в табл. 5.1 и 5.2 функции преобразования). Детальное описание всех имеющихся в Object Pascal процедур и функций можно получить в справочной системе Delphi, однако мы все-таки рассмотрим здесь некоторые из них, чтобы составить общее представление — см. таблицу 6.1.

Таблица 6.1. Некоторые стандартные процедуры и функции Delphi

Синтаксис Группа Модуль Описание
function Abs(X); арифметические System Возвращает абсолютное значение числа
procedure ChDir(const S: string); управления файлами System Изменяет текущий каталог
function Concat(s1 [, s2. sn]: string): string; строковые System Объединяет 2 и более строк в 1
function Copy(S; Index, Count: Integer): string; строковые System Возвращает часть строки
function Cos(X: Extended): Extended; тригонометрические System Вычисляет косинус угла
procedure Delete(var S: string; Index, Count: Integer); строковые System Удаляет часть строки
function Eof(var F): Boolean; ввод-вывод System Проверяет, достигнут ли конец файла
procedure Halt [ ( Exitcode: Integer) ]; управления System Инициирует досрочное прекращение программы
function High(X); диапазона System Возвращает максимальное значение из диапазона
procedure Insert(Source: string; var S: string; Index: Integer); строковые System Вставляет одну строку в другую
function Length(S): Integer; строковые System Возвращает длину строки или количество элементов массива
function Ln(X: Real): Real; арифметические System Возвращает натуральный логарифм числа (Ln(e) = 1)
function Low(X); диапазона System Возвращает минимальное значение из диапазона
procedure New(var P: Pointer); размещения памяти System Создает новую динамическую переменную и назначает указатель для нее
function ParamCount: Integer; командной строки System Возвращает количество параметров командной строки
function ParamStr(Index: Integer): string; командной строки System Возвращает указанный параметр из командной строки
function Pos(Substr: string; S: string): Integer; строковые System Ищет вхождение указанной подстроки в строку и возвращает порядковый номер первого совпавшего символа
procedure RmDir(const S: string); ввод-вывод System Удаляет указанный подкаталог (должен быть пустым)
function Slice(var A: array; Count: Integer): array; разные System Возвращает часть массива
function UpCase(Ch: Char): Char; символьные System Преобразует символ в верхний регистр
function LowerCase(const S: string): string; строковые SysUtils Преобразует ASCII-строку в нижний регистр
procedure Beep; разные SysUtils Инициирует системный сигнал
function CreateDir(const Dir: string): Boolean; управления файлами SysUtils Создает новый подкаталог
function CurrentYear: Word; даты и времени SysUtils Возвращает текущий год
function DeleteFile(const FileName: string): Boolean; управления файлами SysUtils Удаляет файл с диска
function ExtractFileExt(const FileName: string): string; имен файлов SysUtils Возвращает расширение файла
function FileExists(const FileName: string): Boolean; управления файлами SysUtils Проверяет файл на наличие
function IntToHex(Value: Integer; Digits: Integer): string; форматирования чисел SysUtils Возвращает целое в шестнадцатеричном представлении
function StrPCopy(Dest: PChar; const Source: string): PChar; строковые SysUtils Копирует Pascal-строку в C-строку (PChar)
function Trim(const S: string): string; строковые SysUtils Удаляет начальные и конечные пробелы в строке
function TryStrToInt(const S: string; out Value: Integer): Boolean; преобразования типов SysUtils Преобразует строку в целое
function ArcCos(const X: Extended): Extended; тригонометрические Math Вычисляет арккосинус угла
function Log2(const X: Extended): Extended; арифметические Math Возвращает логарифм по основанию 2
function Max(A,B: Integer): Integer; арифметические Math Возвращает большее из 2 чисел
function Min(A,B: Integer): Integer; арифметические Math Возвращает меньшее из 2 чисел

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

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

Функции в действии

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

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

  1. Реализовать-таки возможность повторного прохождения игры без перезапуска программы;
  2. Добавить немного «геймплея». Иначе говоря, введем уровни сложности и подсчет очков. Новые уровни можно реализовать как повторное прохождение игры с увеличением сложности (скажем, за счет расширения диапазона загадываемых значений);
  3. В продолжение п. 2 добавить еще и таблицу рекордов, которая будет сохраняться на диске.

Поскольку часть работы уже выполнена, то для того, чтобы приступить к разработке новой версии игры (назовем ее «Угадай-ка 2.0»), мы не будем как обычно создавать новый консольный проект в Delphi, а откроем уже существующий (Ugadaika) и сохраним его под новым именем, скажем, Ugadaika2, и в новом каталоге. Таким образом, мы уже имеем часть исходного кода, отвечающую за угадывание, в частности, цикл while (см. листинг 4.5). Этот фрагмент логичнее всего выделить в отдельную процедуру, вернее даже функцию, которая будет возвращать число попыток, сделанное пользователем. Для этого создадим функцию, которая будет принимать в качестве аргумента число, которое следует угадать, а возвращаемым значением будет целое, соответствующее числу попыток. Ее объявление будет таким:

function GetAttempts(a: integer):integer;

Данная функция так же должна иметь в своем распоряжении переменную, необходимую для ввода пользователем своего варианта ответа. Еще одна переменная нужна для подсчета результата, т.е. количества попыток. В качестве первой можно было бы использовать глобальную переменную (b), однако во избежание накладок, для локального использования в функции следует использовать локальную же переменную. Что касается переменной-счетчика, то для нее как нельзя лучше подходит автоматическая переменная result. Еще одним изменением будет использование цикла repeat вместо while. Это вызвано тем, что с одной стороны, тем, что хотя бы 1 раз пользователь должен ввести число, т.е. условие можно проверять в конце цикла, а с другой мы можем избавиться от присвоения лишнего действия, а именно — присвоения заведомо ложного значения переменной b. Ну и еще одно дополнение — это второе условие выхода, а именно — ограничение на число попыток, которое мы установим при помощи константы MAXATTEMPTS:

const MAXATTEMPTS = 10;

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

Листинг 6.6. Функция GetAttempts

function GetAttempts(a: integer):integer; var b: integer; begin Result:=0; repeat inc(Result); // увеличиваем счетчик числа попыток write(#13+#10+’?:’); read(b); if (b>a) then begin write(‘Too much!’); continue; end; if (b

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

var level, score, attempt: integer; f: TextFile; s: string;

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

Наконец, напишем цикл для основного блока программы. Этот цикл должен быть выполнен хотя бы один раз и будет продолжать выполняться до тех пор, пока число попыток в последнем уровне было меньше максимально допустимого. В результате получаем цикл repeat со следующим условием:

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

repeat writeln(‘Level ‘+IntToStr(level)+’:’); writeln(‘From 0 to ‘+IntToStr(level*100)); attempt:=GetAttempts(random(level*100+1)); score:=score+(MAXATTEMPTS-attempt)*level; writeln(#10+’You current score is: ‘+IntToStr(score)); inc(level); until attempt>MAXATTEMPTS;

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

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

if not FileExists(‘record.txt’) then begin Rewrite(f); writeln(f,’0′); // первая строка содержит число-рекорд writeln(f,’None’); // а вторая — имя последнего победителя CloseFile(f); end;

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

Reset(f); readln(f, attempt); readln(f,s); writeln(#10+’BEST SCORE: ‘+IntToStr(attempt)+’ by ‘+s); CloseFile(f);

Ну и последнее, чего нам остается — это проверить, является ли новое значение выше рекорда, и если да — то записать новый рекорд в файл, не забыв спросить имя игрока:

Вот, собственно, и все. Полный код получившейся программы можно увидеть на листинге 6.7, или же в файле проекта в каталоге Demo\Part1\Ugadaika2.

Листинг 6.7. Программа угадай-ка, окончательный вариант

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

EndOfADay Routine

Description

(Please provide a description in your own words. It is illegal to use the wording from the Delphi Help.)

Technical Comments

(Known issues / Documentation clarifications / Things to be aware of)

Examples

(Please provide links to articles/source code that show how to use this item.)

See Also

(Please provide links to items specifically related to this item.)

User Comments/Tips

(Please leave your name with your comment.)

Урок №9. Создание собственных процедур и функций Delphi

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

Вообще, существует методика программирования «сверху вниз». Методика программирования «сверху вниз» разбивает задачу на несколько более простых, которые оформляются в виде подпрограмм. Те, в свою очередь, при необходимости также делятся до тех пор, пока стоящие перед программистом проблемы не достигнут приемлемого уровня сложности (то есть простоты!). Таким образом, эта методика программирования облегчает написание программ за счёт создания так называемого скелета, состоящего из описателей подпрограмм, которые в дальнейшем наполняются конкретными алгоритмами. Пустое описание подпрограммы иначе называется «заглушкой».

И процедуры , и функции позволяют добиться одинаковых результатов. Но разница всё же есть.

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

Функция Delphi также позволяет выполнить всё перечисленное, но дополнительно возвращает результат в присвоенном ей самой значении. То есть вызов функции может присутствовать в выражении справа от оператора присваивания. Таким образом, функция — более универсальный объект!

Описание подпрограммы состоит из ключевого слова procedure или function , за которым следует имя подпрограммы со списком параметров, заключённых в скобки. В случае функции далее ставится двоеточие и указывается тип возвращаемого значения. Обычная точка с запятой далее — обязательна! Сам код подпрограммы заключается в «логические скобки» begin/end . Для функции необходимо в коде присвоить переменной с именем функции или специальной зарезервированной переменной Result (предпочтительно) возвращаемое функцией значение. Примеры:

procedure Имя_процедуры( (*параметры*) );

begin
//Код процедуры;
end ;

function Имя_функции( (*параметры*) ): тип_результата;
begin
//Код функции;

Result := результат;
end ;

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

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

Теперь нужно ввести понятие локальных данных. Это данные — переменные, константы, подпрограммы, которые используются и существуют только в момент вызова данной подпрограммы. Они так же должны быть описаны в этой подпрограмме. Место их описания — между заголовком и началом логического блока — ключевым словом begin . Имена локальных данных могут совпадать с именами глобальных . В этом случае используется локальная переменная, причём её изменение не скажется на глобальной с тем же именем.
Совершенно аналогично локальным типам, переменным, константам могут быть введены и локальные процедуры и функции, которые могут быть описаны и использованы только внутри данной подпрограммы.

Теперь пример. Напишем программу суммирования двух чисел. Она будет состоять из Формы, на которой будет кнопка (компонент Button ), по нажатию на которую будет выполняться наша подпрограмма, и двух строк ввода (компоненты Edit ), куда будем вводить операнды. Начнём с процедуры .

var
Form1: TForm1;
A, B, Summa: Integer;
procedure Sum(A, B: Integer);

implementation

procedure TForm1.Button1Click(Sender: TObject);
begin
A:=StrToInt(Edit1.Text);
B:=StrToInt(Edit2.Text);
Sum(A, B);
Caption:=IntToStr(Summa);
end ;

procedure Sum(A, B: Integer);
begin
Summa:=A+B;
end ;

Есть особенности в использовании в качестве параметров больших по объёму структур данных, например, массивов, состоящих из нескольких тысяч (и больше) элементов. При передаче в подпрограмму данных большого объёма могут быть большие расходы ресурсов и времени системы. Поэтому используется передача не самих значений элементов (передача «по значению» , как в предыдущих примерах), а ссылки на имя переменной или константы (передача «по имени» ). Достигается это вставкой перед теми параметрами, которые мы хотим передать по имени, ключевого слова var .

Function Sum(A, B: Integer; var Arr: array [1..1000000] of Integer): Integer;

Eсли взглянуть на описание нашей подпрограммы и описание обработчика нажатия кнопки (это тоже подпрограмма!), который был создан Delphi, то видим, что перед именем обработчика (Button1Click) стоит TForm1 . Как мы знаем, в Delphi точкой разделяется объект и его атрибуты (свойства и методы). Таким образом, Delphi создаёт Button1Click как метод объекта Form1. Причём, буква T перед объектом говорит о том, что Button1Click не просто метод объекта, а метод класса объекта. Не будем этим пока заморачиваться, а просто будем поступать также . Описав свою процедуру или функцию как метод класса TForm1, мы получаем возможность использовать в ней объекты класса без указания его имени, что гораздо удобнее. То есть, если мы используем в нашей подпрограмме какие-либо компоненты, размещённые на Форме (например, Button1), то мы пишем

Button1.W >//Ширина кнопки
а не
Form1.Button1.W >

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

Описав подпрограмму как метод класса, её описание мы должны поместить туда же, куда их помещает Delphi — в описание класса TForm1. Смотрите сами, где находится описание процедуры Button1Click. Для этого , поставив курсор внутрь подпрограммы Button1Click, нажмите CTRL+Shift и кнопку управления курсором » Вверх » или » Вниз » одновременно. Произойдёт переход к описанию подпрограммы (чтобы вернуться обратно, повторите это действие ещё раз). Ставьте описание своей подпрограммы рядом, с новой строки. Обратите внимание, что TForm1 уже не пишется.

Рекурсия — важное и мощное свойство процедур и функций в Delphi. Рекурсия это возможность подпрограммы в процессе работы обращаться к самой себе. Без использования рекурсии приходилось бы применять циклы, а это усложняет чтение программы. Рекурсивный вызов подпрограммы сразу проясняет смысл происходящего. Естественно, приходится следить за тем, чтобы в подпрограмме обязательно было условие, при выполнении которого дальнейшая рекурсия прекращается, иначе подпрограмма зациклится.

Пример вычисления факториала

Вычисление факториала — классическая в программировании задача на использование рекурсии . Факториал числа N — результат перемножения всех чисел от 1 до N (обозначается N! ):

N! = 1*2* . *(N-1) *N = N* (N-1)!

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

Функции Delphi: описание, возможности, советы и рекомендации

Delphi — это проприетарная среда разработки (IDE) для Pascal в Windows. Она реализует объектно-ориентированную версию языка. Среда разработки базируется на графическом интерфейсе, связанного с редактором исходного кода функции Delphi. Язык программирования завоевал популярность благодаря простоте использования при разработке графических приложений и программ, связанных с базой данных.

Массивы — основа программирования

Borland Software Corporation в 1995 году выпустила преемника Turbo Pascal — Delphi, интегрированную среду разработки, использующую свой собственный диалект Object Pascal для облегчения приложений Windows. По сравнению с IDE, функции Delphi имели беспрецедентную поддержку баз данных, создавая многомерную среду, позволяющую программистам писать код быстрее и с меньшим количеством ошибок, чем когда-либо прежде.

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

Первоначально массив в Delphi-программе был статическим. Это означало, что его размер должен был быть известным во время написания кода.

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

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

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

Статистические и динамические массивы

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

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

  1. Поле размера обновляется.
  2. Новый (внутренний) статический массив функции Delphi 7 выделяется с новым размером.
  3. Элементы старого статического копируются в новый.
  4. Указатель статического изменяется на новый.

Если в текущей позиции внутреннего статического массива достаточно места для перераспределения, и существует одна переменная, ссылающаяся на массив, происходит только шаг № 1. Все это реализуется каждый раз, когда изменяют его длину.

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

Строковые операторы

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

Перед назначением данных String переменной требуется знать четыре строковых типа. Короткая строка функции Delphi — Shortstring. Это подсчитанный массив (ASCII) символов, содержащий до 255 знаков в строке. Первый байт этого массива хранит длину. Этот принцип функционирования был основным в Delphi 1 (16-битный Delphi) и создавал переменную с именем small, максимальная длина которой составляла 50 символов.

Когда присваивают значение переменной Short String, строка усекается. Особенно если она превышает максимальную длину этого типа.

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

  1. Целое число — это целые числа, например, 42 или -5.
  2. Одинарное или двойное — используются, как тип с запятыми, например, 3,3.

Операции могут быть применены к числовым переменным:

  • сложение;
  • вычитание;
  • умножение;
  • модуль — может быть применен только к целому числу;
  • char — используется, чтобы содержать один символ, например, m;
  • строка — используется, чтобы содержать предложения, например, Hello world;
  • логические значения — True и False.

Чтобы объединить 2 строки символов, используют оператор «+». Пример: Hello + world будет реализовано, как Hello world.

Переменные и константы

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

При использовании переменной, ее объявляют во всех файлах, где она используется. Только переменные, переданные в качестве параметра Delphi функции и процедуры, не объявляются в той, где они применяются. Для объявления используют ключевое слово var. Они могут быть объявлены в .DPR или в процедурах файлов .pas.

Компонент TDBGrid Delphi является одной из жемчужин VCL. Разработанный таким образом, чтобы позволить пользователю просматривать и редактировать данные в табличной сетке, он предоставляет различные способы настройки способа представления данных. Например, добавление цвета в сетки базы данных улучшит внешний вид и разграничит важность определенных строк или столбцов в БД.

Delphi файлы

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

Чертеж формы, содержащий свойства графических компонентов

Файл проекта — это сердце приложения, связывает все различные файлы, содержащие код (.pas) с .DPR с функцией даты Delphi

Исходный файл, содержащий код приложения

Файл проекта, связанный с .DPR

Файл ресурсов Windows

Таблица файлов, генерированных после компиляции.

Файл проектной группы.

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

Исходный файл пакета.

Файл опций проекта.

Файл ресурсов Windows, он может содержать значки, растровые изображения, звуки.

Функция Pos

Функция POS Delphi возвращает целое число, указывающее позицию первого вхождения одной строки в другую. Это создается следующим образом. Pos ищет первое полное вхождение указанной строки. Обычно предлагается в одинарных кавычках в источнике. Источником является некоторая переменная.

Если Pos находит строку, он возвращает позицию символа в Source, а первого символа в Str, как целочисленного значения, в противном случае функция Delphi возвращает 0. String и Source будут строками. Старомодная функция Pos — наиболее распространенный способ поиска и всегда расположена в начале.

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

Импорт библиотечных функций

Для импорта подпрограмм библиотеки (.DLL) присоединяют директиву в виде: externalstringConstant, по-окончанию заголовка функций и процедур, где string Constant — имя библиотечного файла в кавычках. Есть возможность импортировать подпрограмму с другим названием. Для этого указывают оригинальное имя во внешней директиве:

External stringConstant1, namestringConstant2.

Где первый string Constant указывает имя библиотечного файла, а второй является исходным именем подпрограммы. Следующий оператор выполняет импорт функции из user32.dll. Первоначальное имя функции — MessageBoxA. Вместо имени можно использовать номер, чтобы идентифицировать подпрограмму для импорта:

Где integerConstant индекс подпрограммы в экспортной таблицы.

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

Пример создания одномерного массива

Допустим, нужно сформировать 3 одномерных массива для 50 членов общества разработчиков программного обеспечения. 1-й массив — имена, 2-й — электронная почта, а 3-й — число загрузок.

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

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

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

Тип функции Delphi Member охватывает 3 поля: строковое значение Name, eMail и целое число Posts. В последствии того, как будет установлен тип записи, можно объявить переменную Member. Она не выделяет памяти для имен, eMail и Posts. Для того чтобы практически создать запись Member, объявляют ее переменную.

Использование компонентов OnMouseOver

Код для событий OnMouseMove создают с компонентом TDBGrid, чтобы можно было найти строки и столбцы DBGrid (ячейки) в месте наведения курсора мыши. Если он расположен над сеткой, то срабатывает обработчик события OnMouseMove. Тогда используют метод MoveBy компонента DataSet, чтобы установить отображаемую текущую запись.

Равнозначный код используют для того, чтобы продемонстрировать место, где находится курсор мыши, и поменять его, когда он расположен над строкой заголовка. Для правильной установке активной записи требуется «взломать» DBGrid и получить доступ к защищенному свойству Row. Строки свойств TCustomDBGrid компонента содержат ссылку на текущие активные строки.

Много компонентов обладают полезными свойствами и методами, отмеченными как невидимые или защищенные разработчиками Delphi. Доступ к таким элементам обеспечивается применением простой техники, называемой «защищенный взлом».

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

Скиннинг Delphi Applications

Эти компоненты изменяют внешний вид приложений, добавляя темы и оболочки. Это простой способ улучшить графический интерфейс пользователя (GUI). VCLSkin — легкий в использовании компонент для создания графического интерфейса приложения Delphi. VCLSkin создаст тему или обложку для него без каких-либо изменений исходного кода.

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

У скинов есть много объектов и эффектов для крутых приложений, таких как WinAmp и iTunes. Специальный редактор позволяет пользователю настраивать скины. SkinAdapter является компонентом DynamicSkinForm, который позволяет создавать скины приложений без изменения исходного кода.

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

Пакет разработки пользовательского интерфейса App Face — это решение для создания визуальных графических интерфейсов приложений, которые можно использовать в VC, VB.Net, Delphi, Visual Basic, C ++ Builder и Win32 SDK. Он включает в себя управление скинами, средство создания визуальных скинов, примеров исходного кода, а также технического руководство. Библиотека appface.dll, является компонентом ядра и может автоматически обработать все созданные окна в целевом приложении.

Преимущества среды программирования

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

Основания почему до сих пор используют Delphi:

  1. Четкий синтаксис, делающий код максимально читабельным.
  2. Механизм перетаскивания для реализации, позволяющий быстро создавать программное обеспечение GUI.
  3. Поддержка баз данных SQL.
  4. Поддерживает весь Windows API.
  5. Полно-объектно-ориентированное программирование.
  6. Совместим с C ++.
  7. Сильно адаптируемая среда VCL.
  8. Требуется минимальное обслуживание приложений.

Во время своего апогея, огромное сообщество, разработало массу высококачественного программного продукта в виде компонентов с процедурами и функциями Delphi, многие из которых полностью бесплатные и с открытым исходным кодом. Сегодня все это по-прежнему работает, только с одной проблемой — нехваткой опытных программистов на 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, сохранившийся от его предыдущих версий. При использовании в теле функции переменной с ее именем не забывайте, что существуют большие отличия в обработке этого имени — все зависит от того, где она расположена — в левой части оператора присвоения или же в любом другом месте текста функции. Если имя функции указано в левой части оператора присвоения, то предполагается, что назначается возвращаемое функцией значение. Во всех других случаях предполагается, что осуществляется рекурсивный вызов этой функции.

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

EndOfADay — Функция Delphi

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

Вообще, существует методика программирования «сверху вниз». Методика программирования «сверху вниз» разбивает задачу на несколько более простых, которые оформляются в виде подпрограмм. Те, в свою очередь, при необходимости также делятся до тех пор, пока стоящие перед программистом проблемы не достигнут приемлемого уровня сложности (то есть простоты!). Таким образом, эта методика программирования облегчает написание программ за счёт создания так называемого скелета, состоящего из описателей подпрограмм, которые в дальнейшем наполняются конкретными алгоритмами. Пустое описание подпрограммы иначе называется «заглушкой».

И процедуры, и функции позволяют добиться одинаковых результатов. Но разница всё же есть.

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

Функция Delphi также позволяет выполнить всё перечисленное, но дополнительно возвращает результат в присвоенном ей самой значении. То есть вызов функции может присутствовать в выражении справа от оператора присваивания. Таким образом, функция — более универсальный объект!

Описание подпрограммы состоит из ключевого слова procedure или function, за которым следует имя подпрограммы со списком параметров, заключённых в скобки. В случае функции далее ставится двоеточие и указывается тип возвращаемого значения. Обычная точка с запятой далее — обязательна! Сам код подпрограммы заключается в «логические скобки» begin/end. Для функции необходимо в коде присвоить переменной с именем функции или специальной зарезервированной переменной Result (предпочтительно) возвращаемое функцией значение. Примеры:

function Имя_функции(параметры): тип_результата;
begin
Код функции;
Result:= результат;
end;

procedure Имя_процедуры(параметры);
begin
Код процедуры;
end;

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

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

Теперь нужно ввести понятие локальных данных. Это данные — переменные, константы, подпрограммы, которые используются и существуют только в момент вызова данной подпрограммы. Они так же должны быть описаны в этой подпрограмме. Место их описания — между заголовком и началом логического блока — ключевым словом begin. Имена локальных данных могут совпадать с именами глобальных. В этом случае используется локальная переменная, причём её изменение не скажется на глобальной с тем же именем.
Совершенно аналогично локальным типам, переменным, константам могут быть введены и локальные процедуры и функции, которые могут быть описаны и использованы только внутри данной подпрограммы.

Теперь пример. Напишем программу суммирования двух чисел. Она будет состоять из Формы, на которой будет кнопка (компонент Button), по нажатию на которую будет выполняться наша подпрограмма, и двух строк ввода (компоненты Edit), куда будем вводить операнды. Начнём с процедуры.

var
Form1: TForm1;
A, B, Summa: Integer;
procedure Sum(A, B: Integer);

procedure TForm1.Button1Click(Sender: TObject);
begin
A:=StrToInt(Edit1.Text);
B:=StrToInt(Edit2.Text);
Sum(A, B);
Caption:=IntToStr(Summa);
end;

procedure Sum(A, B: Integer);
begin
Summa:=A+B;
end;

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

var
Form1: TForm1;
A, B, Summa: Integer;
function Sum(A, B: Integer): Integer;

procedure TForm1.Button1Click(Sender: TObject);
begin
A:=StrToInt(Edit1.Text);
B:=StrToInt(Edit2.Text);
Summa:=Sum(A, B); // На мой взгляд, сейчас более понятно, откуда что берётся
Caption:=IntToStr(Summa);
end;

function Sum(A, B: Integer): Integer;
begin
Result:=A+B;
end;

Есть особенности в использовании в качестве параметров больших по объёму структур данных, например, массивов, состоящих из нескольких тысяч (и больше) элементов. При передаче в подпрограмму данных большого объёма могут быть большие расходы ресурсов и времени системы. Поэтому используется передача не самих значений элементов (передача «по значению», как в предыдущих примерах), а ссылки на имя переменной или константы (передача «по имени»). Достигается это вставкой перед теми параметрами, которые мы хотим передать по имени, ключевого слова var.

function Sum(A, B: Integer; var Arr: array[1..1000000] of Integer): Integer;

Если взглянуть на описание нашей подпрограммы и описание обработчика нажатия кнопки (это тоже подпрограмма!), который был создан Delphi, то видим, что перед именем обработчика (Button1Click) стоит TForm1. Как мы знаем, в Delphi точкой разделяется объект и его атрибуты (свойства и методы). Таким образом, Delphi создаёт Button1Click как метод объекта Form1. Причём, буква T перед объектом говорит о том, что Button1Click не просто метод объекта, а метод класса объекта. Не будем этим пока заморачиваться, а просто будем поступать также. Описав свою процедуру или функцию как метод класса TForm1, мы получаем возможность использовать в ней объекты класса без указания его имени, что гораздо удобнее. То есть, если мы используем в нашей подпрограмме какие-либо компоненты, размещённые на Форме (например, Button1), то мы пишем

Button1.W >
а не
Form1.Button1.W >

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

Описав подпрограмму как метод класса, её описание мы должны поместить туда же, куда их помещает описание класса TForm1. Смотрите сами, где находится описание процедуры Button1Click. Для этого, поставив курсор внутрь подпрограммы Button1Click, нажмите CTRL+Shift и кнопку управления курсором «Вверх» или «Вниз» одновременно. Произойдёт переход к описанию подпрограммы (чтобы вернуться обратно, повторите это действие ещё раз). Ставьте описание своей подпрограммы рядом, с новой строки. Обратите внимание, что TForm1 уже не пишется.

Рекурсия — важное и мощное свойство процедур и функций в Delphi. Рекурсия это возможность подпрограммы в процессе работы обращаться к самой себе. Без использования рекурсии приходилось бы применять циклы, а это усложняет чтение программы. Рекурсивный вызов подпрограммы сразу проясняет смысл происходящего. Естественно, приходится следить за тем, чтобы в подпрограмме обязательно было условие, при выполнении которого дальнейшая рекурсия прекращается, иначе подпрограмма зациклится.

Пример. Вычисление факториала

Вычисление факториала — классическая в программировании задача на использование рекурсии. Факториал числа N — результат перемножения всех чисел от 1 до N (обозначается N!):

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

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

EndOfADay — Функция Delphi

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

Синтаксис функции: Рассмотрим подробнее на примере программы. Запускаем Delphi, создаем проект и кидаем кнопку и лабел на форму. Далее в редакторе кода находим слово Private.

После слова Private объявляем функцию: Сейчас нажимаем комбинацию клавиш Ctrl+Shift+C и Delphi автоматически создает загатовку: И между ключевыми словами begin и end пишем то, что будет делать наша функция, а функция будет делать простейшее — сложение переменных a и b, которые мы уже записали, когда объявляли функцию.

Тело функции: Если сейчас запустить программу, то ничего не произойдет, так как функция у нас нигде не вызывается, да и значение переменным a и b мы не указали.

Создаем событие OnClick на кнопке и пишем: Разберем строчку, где происходит суммирование. Пишем имя функции, потом в скобках значения для переменных a и b и результат присваиваем переменной i, которую потом выводим в лабел.

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

Ну вот и всё! Удачи!
Встретимся в следующем уроке!

Источник: www.thedelphi.ru
Автор: Савельев Александр
Опубликовано: 13 Июля 2012
Просмотров: 37648

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

Илон Маск рекомендует:  Создание wordpress шаблона продолжение
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL