- •Тема №1 Типы данных, преобразование типов
- •Тема №2 Массивы, как параметры функций и процедур
- •Тема №з Условный оператор. Логические выражения
- •Тема №4 Функции и их использование
- •Тема №5 Оператор альтернативного выбора
- •Тема №6 Оператор цикла со счетчиком
- •Тема№7-8
- •Тема №9 Логические операторы и логические выражения. Тип boolean
- •Тема№10 Одномерные и двумерные массивы
- •Тема №11 Условный оператор
- •Тема№12 Процедуры. Глобальные и локальные переменные
- •Тема№13 Строковые переменные. Процедуры и функции для работы со строками
- •Тема№14 Двумерные массивы и вложенные циклы
- •Тема№15 Структура программы в языке Pascal
- •Тема№16 Операторы присваивания, ввода, вывода. Соответствие типов
- •Тема№17 Записи. Синтаксис описания записей
- •Тема№18 Сравнение массивов и записей. Работа с полями записей
- •Тема№19 Символьные переменные Операции и функции для работы с ними.
- •Тема №20 Арифметические выражения. Стандартные математические функции
- •Тема№21 Типизированные файлы. Процедуры и функции для работы с ними
- •Тема№22 Типы файлов. Процедуры и функции для работы с ними
- •Тема№23 Текстовые файлы. Процедуры и функции для работы с ними
- •Тема№24 Арифметические и логические операции и их приоритет
- •Тема№25 Область видимости переменных
- •Тема№ 26 Механизмы передачи параметров процедурам
- •Тема№ 27 Запись и чтение файлов. Открытие и закрытие файлов
- •Тема№28 Понятие алгоритма. Линейный, разветвляющийся, циклический алгоритмы.
- •Тема№29 Структурированные типы: массивы, строки, записи, файлы.
Тема №4 Функции и их использование
Всегда помните, что использование процедур и функций с локальными переменными составляет основу структурного программирования. Процедуры и функции являются строительными блоками программ на Турбо Паскале и составляют самое главное положительное качество данного языка. Вам следует знать несколько особенностей функций Турбо Паскаля, которые влияют на размер и скорость выполнения вашего кода.
Во-первых, Турбо Паскаль является стеково-ориентированным языком: все локальные переменные и параметры используют стек для промежуточного запоминания. При вызове функции адрес возврата вызвавшей процедуры также помещается в стек. Это позволяет программе осуществить возврат в точку, из которой был вызов. Когда функция возвращает управление, данный адрес и все локальные переменные и параметры должны быть удалены из стека. Процесс заталкивания данной информации в стек называется последовательностью вызова, а процесс выталкивания информации из стека последовательностью возврата. Эти последовательности требуют определенного времени и иногда довольно большого.
Чтобы понять, как вызов функции может замедлить вашу программу, рассмотрим два примера:
Версия 1 Версия 2
for x:=1 to 100 do for x:=1 to 100
t:=compute(x); t:=Abs(Sin(q)/100/3.1416);
function compute(q: integer): real;
var
t:real;
begin
compute:=Abs(Sin(q)/100/3.1416);
end;
Хотя каждый цикл выполняет одну и ту же функцию, версия 2 гораздо быстрее, так как использование непосредственного кода устраняет задержки, связанные с последовательностями вызова и возврата. Для понимания того, сколько времени тратится, рассмотрим следующий код на псевдоассемблере, который демонстрирует в теории последовательности вызова и возврата для функции compute:
; последовательность вызова
move A, x ; поместить значение х в аккумулятор
push A
call compute ; инструкция вызова помещает адрес
; возврата в стек
; последовательность возврата
; значение возврата функции должно быть помещено в
; регистр - мы используем В
move B, stack-1 ; доставить значение во временное t
return ; возврат к вызвавшей процедуре
; вызвавшая процедура затем выполняет следующие действия
Использование функции compute внутри цикла ведет к тому, что последовательности вызова и возврата будут выполнены 100 раз. Если вы хотите написать быстрый код, то использование данной функции внутри цикла - это не самый лучший подход.
Теперь вы можете подумать, что следует писать программы, которые состоят из нескольких больших процедур и которые, следовательно, будут работать быстрее. В большинстве случаев, однако, небольшие различия во времени выполнения не важны, а вот потеря структуры будет ощутимой. Но это другая проблема. Замена вызовов подпрограмм, которые используются различными процедурами, на непосредстевнные коды сделает вашу программу очень большой, так как один и тот же код будет дублироваться большее количество раз. Помните, что подпрограммы были выдуманы главным образом как средство повышения эффективности использования памяти. Положение таково, что убыстрение программы ведет к ее увеличению, а уменьшение программы ведет к ее замедлению. Использовать непосредственный код вместо вызовов функций следует только тогда, когда скорость имеет абсолютный приоритет. В противном случае рекомендуется повсеместное применение процедур и функций.