Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[9]

Оператор перебора и цикл с предусловием слабо эквивалентны, то есть для каждого конкретного условия будет достаточно легко перейти от одного типа цикла к другому, а общее преобразование куда сложнее. Из for в while можно построить автоматическое преобразование, которое будет неэффективным, а из while в for это вообще осуществить невозможно. Несмотря на столь очевидную связь, подобные мысли о взаимозаменяемости for и while концептуально категорически недопустимы. Эти циклы соответствуют абсолютно разным подходам к реализации вычислений: немедленные (for) и т.н. отложенные (while) вычисления. В качестве другого примера отложенных вычислений можно привести уже изученную нами функцию xrange ().

Лекция седьмая

4.2 Понятие подпрограммы

В наше время существуют два принципиально разных подхода к реализации подпрограмм:

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

2.Функция - это имеющая имя часть программы, которая при вызове получает некоторые параметры и в соответствии с ними возвращает своё значение, не меняя окружение. Это определение куда ближе к математическому понятию функции.

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

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


чисто функциональных языках (Лисп, МЛ, КЛОС) функции не нужно (хотя и можно) иметь имя.

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

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

defubecool(boy):

uprintyboy,isucool

А так используется:

ЪесооК Python)

Вот так определяется функция:

defulogn(n,x)

ureturnulog(х)/log(n)

а так используется:

print logn(20,x)+sin(x)

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

return <значение>

Можно возвращать и несколько значений, перечисляя их через запятую

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

def powers(х):

return х*х,х*х*х,х*х*х*х X=powers(2) X2,X3,X4=powers(3)

В первом случае в X загружается целиком весь кортеж, во втором же

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

Питон позволяет пользоваться подпрограммами, меняющими свою сущность от запуска к запуску. Например, вот так: def br(a): if (а):

return (+str(a)+) else:

print "Error in br("+a+)

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


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

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

Рассмотрев оператор def, мы затронули один важный момент, без разбора которого было бы немыслимо идти дальше.

4.3 Область действия имен переменных

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

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

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



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13]