Обучающий курс. 12. Функции и процедуры в Delphi. Математические вычисления. Случайные числаИсточник: delphi
Сегодня мы поговорим о процедурах и функциях в Delphi. Что такое процедура? Это маленькая программа, выполняющая операции с указанными данными. Различают собственно процедуры и функции. Их основное отличие - процедура просто совершает какие-либо операции, а функция обязательно выдаёт какой-либо результат в результате своей работы. Существует огромное количество стандартных процедур и функций. Подпрограммы (так называют процедуры и функции) можно писать и самостоятельно, но об этом речь пойдёт позже. Сейчас нам нужно научиться работать с готовыми функциями. Общие сведения о подпрограммахФактически, подпрограмма - это такая же полноценная программа, просто работает она не отдельно, не сама по себе, а включена в другую программу. Вызов подпрограммВызываются подпрограммы по имени. Если подпрограмме требуется передать какие-либо параметры, то они указываются в скобках после имени подпрограммы через запятую. Если входные параметры отсутствуют, достаточно просто написать имя подпрограммы, либо оставить скобки пустыми. В случае, если работа происходит с функцией, результат можно "сохранить" в какой-то переменной, просто "присвоив" этой переменной функцию. Обратите внимание: работа с функциями происходит как с обычными переменными, просто их значения вычисляются "на лету". Функции математических вычисленийЭти функции работают с числовыми данными. Как правило, входным параметром является какое-то число, а выходным - результат вычисления. Практически везде аргумент является либо целым числом (Integer), либо вещественным (Real). Возвращаемое значение - тоже число. Рассмотрим некоторые из этих функций: Abs(x) - модуль (абсолютное значение) указанного числа x. Пример: Abs(-5) = 5. Sin(x) - синус числа x. Здесь x - угол в радианах (не в градусах!). Пример: Sin(Pi/2) = 1. Cos(x) - косинус числа x. Аналогично, x - радианы. Пример: Cos(Pi) = -1. Exp(x) - экспонента, ex (e в степени x). Ln(x) - натуральный логарифм числа x. Пример: Ln(Exp(2)) = 2. Sqr(x) - квадрат числа x (x2). Пример: Sqr(5) = 25. Sqrt(x) - квадратный корень числа x. Пример: Sqrt(64) = 8. Int(x) - целая часть числа x. Пример: Int(1.234) = 1. Frac(x) - дробная часть числа x. Пример: Frac(1.234) = 0.234. Round(x) - округление аргумента до ближайшего целого числа. Пример: Round(1.234) = 1. Trunc(x) - целая часть вещественного числа x. Пример: Trunc(1.234) = 1. Pred(x) - предыдущее значение x (например, для x = 2 это 1). Succ(x) - следующее значение x (для x = 2 это 3). Odd(x) - проверка аргумента на нечётность. Функция возвращает значение True, если аргумент является нечётным числом и False - если чётным. Пример: Odd(5) = True. Предсказываю вопрос: в чём отличие Int() от Trunc()? А отличие в том, что Int() возвращает число вещественного типа, а Trunc() - целочисленного. Это лишь часть всех доступных функций. На самом деле их гораздо больше. Но помимо функций есть ещё процедуры. Процедуры работы с числамиПоскольку процедуры в результате работы не выдают никакого значения, процедуры работы с числами просто изменяют переданные им параметры-переменные. Inc(x) - увеличение аргумента на единицу. Фактически, это то же самое, что x:=x+1. Тем не менее, рекомендуется использовать именно эту функцию, так как работает она быстрее. Inc(x,n) - увеличение аргумента на число n. Эквивалентно записи x:=x+n. На самом деле, это не две разные процедуры - просто параметр n является необязательным. Да, бывают необязательные параметры, которые можно указать, а можно и не указывать. Если они отсутствуют, то просто берётся какое-то значение по умолчанию. В данном случае n по умолчанию имеет значение 1. Dec(x,n) - уменьшение аргумента на n единиц. Точно также, как и в Inc, параметр n является необязательным. Эквивалентно записи x:=x-n. В документации необязательные параметры обычно заключают в квадратные скобки, т.е. обычно пишут Inc(x , [n]). Обратите внимание: это лишь условное обозначение, которое создано с целью узнавания, что параметр необязательный. В программном коде никаких скобок нет и быть не может. Не хватает стандартных математических функций? Существует дополнительный модуль с именем Math, в котором содержится большое число математических функций. Например, если нужно посчитать гиперболический арксеканс числа, то мучаться и описывать способ его вычисления вручную не придётся - есть готовая функция ArcSecH(). Всё, теперь в Вашем распоряжении большое количество математических функций. Пример комбинирования функцийРаз уж речь пошла о математических функциях, пусть пример будет на них и основан. Допустим, у нас есть такая сравнительно сложная функция: Нам нужно создать программу, которая бы вычисляла значение этой функции по заданным числам x и y. Рассмотрим поэтапно элементы функции: var f,x,y: Real; Как возвести число в степень?Почему я останавливаюсь на таких вопросах? Просто они очень часто возникают у новичков и не каждый может догадаться, как выполнить требуемую операцию. Способ 1. Xy можно преобразовать к виду eln(x)⋅y. Тогда возведение в степень можно записать так: := Exp( y * Ln(x) ); Способ 2. В модуле Math есть функция для возведения в степень - Power. У функции 2 аргумента - основание и показатель степени. Запись, соответственно, следующая :=Power(x,y); Случайные числаЗачем нужны случайные числа? Как правило, чтобы проверить результаты какого-то эксперимента при различных условиях. На основе случайных чисел можно вычислять различные вероятности. Во всех языках программирования есть возможность использовать случайные числа. В Pascal (и Delphi соответственно) случайные числа генерируются функцией Random. Функция принимает один параметр, да и тот необязательный... Этот параметр позволяет указать границу диапазона, из которого будет выбрано случайное число. Итак: Random([Range: Integer]). Если Range указан, то число выбирается из диапазона 0 <= X < Range (X - само случайное число, которое будет получено). Обратите внимание, что сама граница в диапазон не включается, т.е. Random(10) никогда не выдаст число 10, хотя 0 - запросто. Если диапазон не указан, то он считается равным единице, т.е. 0 <= X < 1. Пример. Создадим форму с кнопкой, но пусть кнопка каждую секунду изменяет своё положение. Воспользуемся таймером (TTimer, вкладка System палитры компонент). Interval оставим без изменения (1 сек.), а вот в обработчике запрограммируем произвольное изменение положения кнопки на форме. Разберёмся, что нам нужно: procedure TForm1.Timer1Timer(Sender: TObject); Запускаем программу и наблюдаем... Кнопка действительно прыгает с места на место. Но есть один крайне неприятный момент: запустите программу несколько раз и понаблюдайте за точками, в которые попадает кнопка. Вы сразу заметите, что каждый раз кнопка перемещается по одним и тем же точкам. Отчего это происходит? Дело в том, что числа, выдаваемые функцией Random() на самом деле не являются случайными - они псевдослучайны, т.е. наблюдается повторение. К счастью, решение есть - специальная процедура Randomize() инициализирует генератор случайных чисел, который выдаёт действительно случайные числа. Вызвать эту процедуру нужно всего один раз за время работы программы - обычно это делается при запуске (например, в событии OnCreate формы). Процедура не принимает никаких параметров. Вернёмся к нашему примеру: procedure TForm1.FormCreate(Sender: TObject); Теперь кнопка будет прыгать совершенно по разным точкам при каждом запуске программы. Кстати, можно дописать скобки к названию процедуры - от этого работа не изменится: Randomize; = Randomize(); А запись немного красивее (на мой взгляд). Дополнительные возможности редактора кода В редакторе кода есть одна очень хорошая вещь - после того, как написано имя процедуры или функции и открыта скобка, появляется подсказка со всеми параметрами, которые подпрограмма принимает. Более того, там же указаны и типы данных всех параметров. Попробуйте, к примеру, набрать Inc( и подождать секунду - появится подсказка: Как и было отмечено выше, второй параметр является необязательным и он заключен в квадратные скобки. Такие подсказки позволяют моментально узнать, что подпрограмма требует на вход. При этом не придётся открывать модуль, где находится функция, либо искать её описание в документации или справочной системе. Если функции или процедуре входные параметры не нужны, подсказка всё равно появится и сообщит об этом:
Если после набора имени и скобки подсказка не появилась, то и при компиляции программы скорее всего возникнет ошибка. Причиной, по которой компилятор не смог найти указанную функцию или процедуру, может быть ошибка при наборе имени, либо модуль, в котором описана подпрограмма, не подключен. Строка с ошибкой выделилась, а внизу появился её номер (28) и описание - Undeclared identifier (неописанный идентификатор). ЗаключениеВ этом уроке охвачено сразу несколько тем - знакомство с процедурами и функциями, обзор математических функций и процедур, модуль Math, работа со случайными числами, а также удобства редактора кода и выделение ошибок при компиляции. |