Основы алгоритмизации и программирования. Часть третья. Структурированные типы данных. Асламова В.С - 15 стр.

UptoLike

29
. . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . .
A:=B(I)+3.5
end;
function B;
var D:integer;
begin . . . . . . . . ….. . . . . . . . . . . . . . . . . . . .
B:=A(D)-1.8
end; ……………………………………
В языке Турбо Паскаль нет никаких ограничений на рекурсивные
вызовы подпрограмм, необходимо только хорошо понимать, что каждый
очередной рекурсивный вызов приводит к образованию новой копии
локальных объектов подпрограмм и все эти копии, соответствующие цепочке
активизированных и не завершённых рекурсивных вызовов, существуют
независимо друг от друга.
Более
подробно предварительное описание подпрограммы мы
рассмотрим позже.
Распределение памяти для локальных
переменных при рекурсии
Зачастую внесение рекурсивности в программы придаёт им
изящность. Но всегда он жезаставляетпрограммы расходовать больше
памяти. Дело в том, что каждыйотложенныйвызов функции и процедуры
это свой набор значений всех локальных переменных этой функции,
размещённой в стеке. Если будет, например, 100 рекурсивных вызовов
функций, то в памяти должны разместится
100 наборов локальных
переменных этой функции.
Рассмотрим это поподробнее.
Все глобальные переменные (те которые описаны во внешнем блоке
программы) и все типизированные константы размещаются в одном сегменте
данных, который не может превышать объём 65536 байт или 64 кБ.
Локальные переменные размещаются в памяти динамически. После
завершения выполнения подпрограммы память, отведённая для её локальных
переменных, освобождается.
В некоторый момент выполнения программ в памяти может
присутствовать несколько групп локальных переменных, которые
соответствуют цепочке вызванных и не завершённых подпрограмм. В случае
очередного вызова новая область памяти связывается с последней группой в
30
цепочке. При завершении подпрограммы её локальные переменные
удаляются из хвоста цепочки. Этот принцип отведения и
освобождения
памяти соответствует понятию стека.
Стеком является структура магазинного типа LIFO (Last In First
Out), т.е. локальные переменные помещаются в стек один за другим и
выбираются из стека в обратной последовательности.
Турбо Паскаль ограничивает объём стековой памяти одним
сегментом. Поэтому в случае слишком длинной цепочки вызова, что
случается в результате ошибок в рекурсивных
подпрограммах, сегмент стека
может переполниться, что повлечёт аварийное прекращение выполнения
программы.
В Турбо Паскале директива $М служит для задания максимального
размера стека. Минимально допустимый размер стека 1024 байт,
максимальный65536 байт, по умолчанию размер стека = 16384 байта.
Директива $M должна быть указана в начале программы. В этой директиве 3
целочисленных параметра:
1–ый задаёт максимальный размер
стека,
2–ой и 3–ий задают минимальный и максимальный размеры
динамической памяти (кучи - Heapsize), примеры:
{$M 10240, 0, 200000}
{$M 1024, 0,0}
{$M 16384, 1024, 65000}
Второй параметр носит ограничительный характер и устанавливает
тот объём памяти, при отсутствии которого программа вообще не может
работать. Если он равен 0, то программа будет запущенна в любом случае.
Третий параметр носит рекомендательный характер. Иными словами,
размер
динамической памяти будет определяться перед началом работы
программы, исходя из реального наличия свободной оперативной памяти, но
не будет превышать указанный в этом параметре объём.
По умолчанию устанавливается директива:
{$M 16384, 0,655360},
т.е. под стек выделяется 16 Кбайт, под динамическую памятьвся свободная
оперативная память, доступная операционной системе.
Можно установить, кроме директивы, обсуждаемые размеры
с
помощью альтернативы Options/Memory Sizes в интегрированной среде или
          . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . .   цепочке. При завершении подпрограммы её локальные переменные
          A:=B(I)+3.5                                                            удаляются из хвоста цепочки. Этот принцип отведения и освобождения
        end;                                                                     памяти соответствует понятию стека.
        function B;
        var D:integer;                                                                 Стеком – является структура магазинного типа LIFO (Last In First
        begin . . . . . . . . .. . . . . . . . . . . . . . . . . . . .           Out), т.е. локальные переменные помещаются в стек один за другим и
          B:=A(D)-1.8                                                            выбираются из стека в обратной последовательности.
        end;                                                                           Турбо Паскаль ограничивает объём стековой памяти одним
        В языке Турбо Паскаль нет никаких ограничений на рекурсивные             сегментом. Поэтому в случае слишком длинной цепочки вызова, что
вызовы подпрограмм, необходимо только хорошо понимать, что каждый                случается в результате ошибок в рекурсивных подпрограммах, сегмент стека
очередной рекурсивный вызов приводит к образованию новой копии                   может переполниться, что повлечёт аварийное прекращение выполнения
локальных объектов подпрограмм и все эти копии, соответствующие цепочке          программы.
активизированных и не завершённых рекурсивных вызовов, существуют                      В Турбо Паскале директива $М служит для задания максимального
независимо друг от друга.                                                        размера стека. Минимально допустимый размер стека 1024 байт,
          Более подробно предварительное описание подпрограммы мы                максимальный – 65536 байт, по умолчанию размер стека = 16384 байта.
рассмотрим позже.                                                                Директива $M должна быть указана в начале программы. В этой директиве 3
                                                                                 целочисленных параметра:
               Распределение памяти для локальных                                      1–ый задаёт максимальный размер стека,
                  переменных при рекурсии                                              2–ой и 3–ий задают минимальный и максимальный размеры
                                                                                 динамической памяти (кучи - Heapsize), примеры:
      Зачастую внесение рекурсивности в программы придаёт им
изящность. Но всегда он же “заставляет” программы расходовать больше                    {$M 10240, 0, 200000}
памяти. Дело в том, что каждый “отложенный” вызов функции и процедуры                   {$M 1024, 0,0}
– это свой набор значений всех локальных переменных этой функции,                       {$M 16384, 1024, 65000}
размещённой в стеке. Если будет, например, 100 рекурсивных вызовов                      Второй параметр носит ограничительный характер и устанавливает
функций, то в памяти должны разместится 100 наборов локальных                    тот объём памяти, при отсутствии которого программа вообще не может
переменных этой функции.                                                         работать. Если он равен 0, то программа будет запущенна в любом случае.
      Рассмотрим это поподробнее.                                                       Третий параметр носит рекомендательный характер. Иными словами,
      Все глобальные переменные (те которые описаны во внешнем блоке             размер динамической памяти будет определяться перед началом работы
программы) и все типизированные константы размещаются в одном сегменте           программы, исходя из реального наличия свободной оперативной памяти, но
данных, который не может превышать объём 65536 байт или 64 кБ.                   не будет превышать указанный в этом параметре объём.
      Локальные переменные размещаются в памяти динамически. После                      По умолчанию устанавливается директива:
завершения выполнения подпрограммы память, отведённая для её локальных                                       {$M 16384, 0,655360},
переменных, освобождается.                                                       т.е. под стек выделяется 16 Кбайт, под динамическую память – вся свободная
      В некоторый момент выполнения программ в памяти может                      оперативная память, доступная операционной системе.
присутствовать несколько групп локальных переменных, которые                            Можно установить, кроме директивы, обсуждаемые размеры с
соответствуют цепочке вызванных и не завершённых подпрограмм. В случае           помощью альтернативы Options/Memory Sizes в интегрированной среде или
очередного вызова новая область памяти связывается с последней группой в
                                     29                                                                             30