Передача параметров по значению
• При передаче формальный параметр x подпрограммы p(x) получает значение фактического параметра.
X:=e; передать значение е, присвоить его х
Sq:=x*x выполнить тело функции
Return sq вернуть результат
- Любые изменения значения формального параметра, произошедшие во время выполнения подпрограммы, теряются, когда подпрограмма завершает свое выполнение.
• В паскале и с она рассматривается как основной метод передачи параметров.
Передача параметров по ссылке
• Формальный параметр превращается в синоним места размещения фактического параметра. Т.е подпрограмме становится доступным указатель на местоположение этого объекта.
С++:
Void sw(int *px, int *py){
Int z;
Z= *px; *px=*py; *py=z}
Px=&a;передача адреса а в рх
Py=&b
Z=*px;присваивание z начального значения a
*px=*py; присваивание a Значения переменной b
*py =z; присваивание b начального значения a, сохраненного в z
+ Высокая эффективность как времени, так и памяти. Не надо копировать значения фактических параметров, а затем отдельно обновлять их.
- Доступ к обрабатываемым параметрам замедляется, поскольку используется косвенная адресация.
- Могут возникнуть неумышленные и ошибочные изменения фактических параметров.
- Появляется возможность возникновения псевдонимов (алиасов) фактических параметров. Псевдонимы снижают читабельность и надежность программ, а также усложняют их проверку.
Передача параметров по значению-результату
• Фактические параметры, не имеющие места размещения, передаются по значению.
• Фактические параметры, имеющие место размещения обрабатываются так:
1. Этап copy-in. Вычисляются значения и места размещения фактических параметров. Значения присваивают формальные параметры.
2. Выполнение тела подпрограммы. Здесь обрабатываются формальные параметры.
3. Этап cory-out. После выполнения тела подпрограммы конечные значения формальных параметров копируются обратно в места размещения, вычисленные на этапе 1.
+ Доступ к обрабатываемым в подпрограмме параметрам ускоряется, поскольку в косвенной адресации нет необходимости.
+ Безопасность хранения фактических параметров повышается, т.к канал связи с ними открывается перед началом обработки в режиме приема и после окончания обработки в режиме записи. Во время выполнения тела подпрограммы канал закрыт.
- Необходимость хранить параметры в нескольких местах и тратить время на копирование их значений и адресов.
- Сохраняется проблема псевдонимов.
Параметр по результату
• Параметр, передаваемый по результату, используется только для передачи результатов вычисления назад в вызывающую программу.
С#:
Void report(out int a, out int b){a=29, b=57;}
Obj. report(out m, out m); <-одинаковые имена
• Если первым присваивается значение параметра а, то значение фактического параметра вызывающего модуля – 57;
• Если первым присваивается значение b, тогда значение будет 29
- Т.к порядок может задаваться реализацией, различные реализации языка будут генерировать разные результаты.
- Момент для вычисления адреса фактического параметра может определяться в начальной фазе вызова подпрограммы или при возвращении из нее- неопределенность должен снять разработчик реализации языка
60. Программный стек и его изменение.
Для лучшего понимания механизма обработки исключения необходимо подробнее рассмотреть процесс изменения программного стека во время выполнения программы.
Стек представляет собой область оперативной памяти компьютера, которая используется для размещения информации, связанной с вызовом функций, а также для хранения автоматических локальных переменных. Перед вызовом функции в стек заносится адрес возврата, кадр состояния (фрейм), содержащий значения регистров и позволяющий перед возвратом восстановить состояние вычислительного процесса и, при необходимости, значения параметров. После входа в программную секцию функции, со стека снимаются значения параметров и помещаются автоматические локальные переменные. Перед возвратом из функции со стека снимаются локальные переменные, кадр состояния и адрес возврата, затем в стек заносится возвращаемое функцией значение. По кадру состояния восстанавливаются регистры, после чего управление передается по адресу возврата. Таким образом, в процессе выполнения программы стек увеличивается и уменьшается.
Раскручиванием программного стека называется процесс удаления из него значений, в результате которого уничтожаются стековые фреймы вызванных функций.
Увеличение программного стека происходит в направлении уменьшения адресов выделенной физической памяти компьютера. Код программы, напротив, размещается в младших адресах. Далее следует область данных, где размещаются внешние и статические переменные и константы, а затем динамически распределяемая память («куча»). При использовании больших локальных массивов данных или при значительной глубине рекурсии возможно переполнение стека, т.е. разрастание его до других разделов памяти.
Стековые языки
◘◘◘◘◘◘◘→считывание\Происходит с одного конца стек. Если записать 1234,
◘◘◘◘◘◘◘←запись / то первый который можно будет считать это 4.
•Для переадресации параметров используется машинная модель стека.
•При использовании стека, в качестве основного канала передачи параметров между словами, элементы языка образуют фразы.
•Forth,C#,Java.
•Стековая –это переменная удовлетворяющие двум условиям: связывание с памятью осуществляется при обработке операторов объявления переменных типы переменных связываются статически.
61. Рекурсивный и итерационный методы решения задач. Виды рекурсий.
Описание объектов или вычисления в терминах самого себя. Обращение подпрограммы к самой себе.
1) Рекурсия всегда должна иметь условие прекращения. Т.е. есть ситуация, когда нового рекурсивного вызова больше не происходит и цепочка рекурсивных вызовов возвращается к исходной точке.
2) Вызов с другим значением параметра. Чтобы не произошло зацикливание рекурсивных вызовов, необходимо, чтобы внутренний вызов производился с модифицированным значением параметра. При этом желательно, чтобы модификация стремилось к состоянию прерывания рекурсии.
Виды рекурсий.
1) Линейная рекурсия – выполнение тела подпрограммы приводит не более чем к одному рекурсивному вызову. Существует линейная цепочка вызовов. Вычисление факториала.
2) Повторная рекурсия – разновидность линейной рекурсии, когда рекурсивный вызов внутри подпрограммы является последним оператором. Отсутствуют какие-либо предварительные, или отложенные вычисления. В этом случае все действия подпрограммы выполнены и управление передается в другой вызов, а внутреннее состояние можно забыть. В этом случае нет необходимости сохранять все предыдущие промежуточные значения и результатом вычислений является последний вызов.
3) Каскадная рекурсия – возникает, если при выполнении тела подпрограммы, рекурсивные вызовы могут возникнуть более одного раза. Древовидная схема вызовов.
4) Взаимная рекурсия – циклическая последовательность взаимных вызовов нескольких подпрограмм, когда одна подпрограмма производит обращение к другой, а та в свою очередь снова может обратиться к первой. Всегда может быть сведена к линейной.
5) Удаленная рекурсия – если в теле функции при рекурсивных вызовах в выражении являющихся фактическими параметрами, снова встречаются рекурсивный вызов этой функции.
Недостатки рекурсивного подхода:
Время выполнения не всегда меньше, чем другими способами. Опасные зацикливания. Всегда нужно предусматривать условия выхода. Сложность понимания. Передача множества параметров.
Циклы и рекурсия
• Повторение некоторой последовательности операторов – это мощное средство для сокращения длины программыи повышения эффективности вычислений.
• Итерация – способ многократного повторения последовательности операторов, реализуемый в виде цикла.
• Рекурсия – способ организации повторений, при котором последовательность операторов вызывает сама себя непосредственно либо с помощью других последовательностей.
• Рекурсия является естественной математической формой записи повторяющихся вычислений (на основе функций).
• Рекурсия считается главным средством поддержки повторений в функциональных языках.
• Тело цикла – группа многократно повторяющихся операторов. Этот набор определяет функциональные возможности цикла.
• Итерация – одно повторение тела цикла.
• Секция управления управляет количеством повторений тела. Размещена как перед телом, так и после тела цикла.
• Условие цикла - определение момента, когда следует закончить цикл.
В результате формируется условие продолжения, или условие завершения цикла.
• Различают циклы с предусловием и с постусловием.
Циклы:
• Операторы тела могут выполняться 0 или более раз.
• Операторы тела повторяются пока условие равно True.
• В теле должен быть оператор, влияющий на значение условия (для исключения бесконечного повторения)
Циклы со счетчиком
В составе секций управления есть переменная цикла, которая принимает дискретное количество значений и используется для подсчета количества повторений тела.
• Секций управления ограничивает количество значений переменной цикла, определяя ее начальное, конечное значение, а такде величину шага между соседними значениями. Начальное и конечное значение переменной, а также величину шага – параметры цикла.
• Условие проверяются перед выполнением тела. Если условие не выполняется в самом начале работы оператора, тело не будет выполнено ни разу.
• Величина шага постоянна.
• Циклы с повторением по данным
• Позволяют перебирать все элементы многоэлементной структуры, обращаясь к каждому из них по очереди.
• Востребованы в объектно-ориентированном программировании, где используются для создания итераторов.
• При каждом повторении цикла целая переменная х будет принимать значение, равное следующему элементу массива intArray. Размер массива определяет количество повторений тела цикла.
• Отличает от счетчика, что шаг всегда один, а не задается.
<Циклы в функциональных языках>
В чисто функциональных языках отсутствуют переменные, поэтому вместо итерации здесь используют рекурсию.
Циклы моделируются:
• Счетчик может быть параметром для функции, многократно выполняющей тело цикла.
• Тело определяется во вспомогательной функции, которая тоже посылается в функцию цикла как параметр.
• Т.о функция цикла принимает в качестве параметров тело вспомогательной функции и количество повторений.