Лекция 12. Подпрограммы (часть1) (1152914), страница 2
Текст из файла (страница 2)
«Информатика. Язык Питон»Фактические и формальные параметрыС помощью фактических и формальных параметров данныепередаются из программы в подпрограмму и обратно в программу.Формальные параметры – это параметры, которые используются приописании подпрограмм, а фактические параметры (или аргументы)– это значения, которые используются при вызове подпрограммы.В тот момент, когда осуществляется вызов подпрограммы,происходит замена: фактические параметры становятся значениямиформальных параметров – это и обеспечивает передачу данных изпрограммы в подпрограмму. При завершении подпрограммыпроисходит обратный процесс.Таким образом, в качестве формальных параметров могут бытьтолько имена переменных, а в качестве фактических параметров могутбыть константы, переменные, выражения и функции.ProcXY ( 3, x, y);ProcXY ( n, (1+x), abs(y) );y = FuncXY( 3, x);Параметры делятся по смыслу (классу) на входные, выходные иодновременно входные/выходные – по аналогии с основнойпрограммой.
Из блок-схемы легко понять к какому классу относятсяпараметры по их расположению в блоке подзадач:n, A-массив, k, B-массивПОДЗАДАЧАk, B-массив, Sum10Воробьева И.А. «Информатика. Язык Питон»Процедуры и функции сравнение.Напомним, что отличие подпрограммы общего типа (процедуры) отфункции состоит в том, что при вызове функция через свое имявозвращает в вызывающий блок значение, полученное в процессе еевыполнения, а процедура такого значения не возвращает. Имяпроцедуре требуется только для ее вызова, а имя функции необходимокак для ее вызова, так и для возвращения результата работыподпрограммы-функции (это фактически ссылка на переменную,хранящую результат работы функции).Подумайте.
Можно ли полностью сохранить функционал кода,используя только процедуры или только функции?Короткий ответ – «да», а примеры, показывающие, как легко можноподпрограмму общего типа преобразовать в функцию и наоборот, еслисинтаксически язык программирования позволяет использовать толькоодну из конструкций подпрограмм, мы покажем после болееподробного изучения способов передачи параметров и областейвидимости переменных в Python.8.2. Подпрограммы. Способы передачи параметров8.2.1 Общий подходФактические параметры передаются в подпрограмму путемкопирования в специальный раздел оперативной памяти – стек.Подпрограмма работает со стеком.
После завершения подпрограммы,стек освобождается и, при этом, необходимая информация переноситсяобратно в ОП. При такой организации важно как именно передаетсяинформация о параметрах. Способы передачи: по значению – в стек записывается собственно значение переменной, расположенной в ОП;11Воробьева И.А. «Информатика. Язык Питон» по ссылке – в стек записывается «адрес» ОП, указывающий местохранения переменной и тогда ее значение в процессе работы подпрограммы узнается опосредовано, через знание адреса.Более того, для фактических параметров, кроме уже известногосмыслового деления на входные, выходные и входные/выходные,принято также деление, показывающее допустимость модификациивнутри функции: параметр-значение; параметр-переменная.Покажем наглядно, чем отличаются способы передачи параметров.Таблица 8.1ОПЕРАТИВНАЯ ПАМЯТЬпо значениюa≡Addr_a00СТЕК00003073Addr_bb≡Addr_b00по ссылке05(по адресу)вызов подпрограммыпусть в подпрограммевыполняютсяоператоры:0003a=7;b=9;0009работаподпрограммы00Addr_b12Воробьева И.А.
«Информатика. Язык Питон»возврат в программу00003007очистка стекаAddr_b0009-Способы передачи особенно важно принимать в расчет при работес «большими» данными. Вспомним, как хранится в памяти статическиймассив.адреспервогоэлементамассива0-йэлементintegerадрес может занимать заведомо не более 8-ми байт (для 64разрядных машин)а сам массив будет занимать не менее 10*4=40 байт1-йэлементinteger9-йэлементintegerВ общем случае параметр-значение – в стек передаетсяполностью содержимое переменной. Как параметр-значение можнопередавать переменные, собственно числа, результаты выраженийили функций.
Однако если вы передаете массив из 10-ти целых какпараметр-значение, то вы копируете в стек все 40 байт. А для передачиматрицы размерности 100x100 вещественных чисел, придетсяперекопировать уже минимум 80 000 байт! Помимо того, чтоабсолютно бесполезно занимается место в стеке, еще и расходуетсявремя на выполнение никому не нужных операций копирования, делаякод неэффективным. Именно поэтомукатегорически нерекомендуется передавать по значению переменные большихобъемов2.2Python защищает от такого неразумного поступка, так как массивы, реализованные списками, в нем передаются поссылке в силу устройства языка, однако не все языки имеют подобную реализацию и это надо учитывать.13Воробьева И.А. «Информатика.
Язык Питон»Внутри подпрограммы параметр-значение может изменяться, ииспользоваться так же, как и обычная «переменная», но при этом послезавершения работы функции содержимое ее будет полностью утеряно.Приведем пример кода.k=10d=0def Value ( a): # пусть k=10; и вызов d=Value( k )Mid = a# Mid = 10, объявили переменную с инициализациейa = a+1# изменим значение a: a = 11Mid = a + 75 # тогда Mid = (11+75) = 86return Midd=Value( k ) # результат работы функции d=86print(‘d= ‘, d, ’k= ‘, k) # а k осталось прежним: k=10Параметр-переменная – в стек передается только адреспеременной.
Параметр-переменная может быть одновременно входной(передает данные в подпрограмму) и выходной (передает данные изподпрограммы), только выходной (заполняет переменную результатомработы подпрограммы) и по этой причине фактические параметрыпеременные не могут быть константами, выражениями илифункциями.Внутри подпрограммы параметр-переменная может считываться,изменяться, а после завершения работы функции содержимое ее будетсохранено для последующей работы.8.2.2. Как реализовать в Python передачу параметровНапоминание. В языке Python нет явно определяемых констант, зато есть понятиеизменяемой и неизменяемой переменной, что влияет на механизм работы с ними.Вспомним, что к неизменяемым переменным из тех, что мы уже знаем, относятсявсе простые типы: целые, вещественные и комплексные числа, строки и кортежи(неизменяемые массивы, tuple), а к изменяемым – списки (изменяемые массивы,list).14Воробьева И.А.
«Информатика. Язык Питон»Действует следующее правило, неизменяемые переменныепередаются только по значению (параметр-значение), а изменяемые– по ссылке (параметр-переменная).Возникает вопрос, как же тогда передать в качестве результата неодно, а два скалярных значения? Например, если мы хотим, чтобыподпрограмма считала число отрицательных элементов в массиве исумму его положительных элементов?!?Для этой цели в Python есть очень удобный механизм возврата черезоператор return не одного, а нескольких значений, причем типы ихмогут быть разными.def ИМЯ ФУНКЦИИ (<список формальных параметров>):< раздел описаний>< раздел операторов>result <значение1, значение2,…, значениеN> # механизм возвратанескольких значений функцииПример.k=0d=0.0st=’ПЕТЯ’def f1 (stroka):kol=0# количество символов вvol=0.0 # удельный вес слова в предложенииstroka = stroka+ ’+’ +‘МАША=ЛЮБОВЬ’ # изменим входное данноеkol= len(stroka)vol= len(‘ЛЮБОВЬ’)/kolreturn vol, kol, stroked, k, st =f1( st )print(‘d= ‘, d,’ k= ‘, k,’ st= ‘, st) d=0.375 k=16 st=ПЕТЯ+МАША=ЛЮБОВЬОбратите внимание:1.
В функции () использовано два выходных параметра (один входной-выходной ().,)и15Воробьева И.А. «Информатика. Язык Питон»2. Функцию () нельзя использовать, как «функцию в классическомопределении» – в выражениях и в качестве параметра другойподпрограммы. Ее можно использовать только как подпрограммуобщего типа, т.е. только в качестве самостоятельного оператораязыка.Можно дать следующую практическую рекомендацию по способамоформления и передачи параметров. Вернемся к блоку подзадачи вблок-схеме.
Пусть он выглядит следующим образом:n, A-массив, k, B-массивПОДЗАДАЧАB-массив, Sum, s, C-массивытип параметравходнойвыходнойимяпростойнеизменяемый тип(число, строка)изменяемый тип(массив, матрица)простойнеизменяемый типизменяемый типвходной-выходнойпростойнеизменяемый типизменяемый типТаблица 8.2.способ передачи ивозврата изфункциичерез списокпараметровчерез списокпараметровчерез оператор returnчерез списокпараметровчерез списокпараметроврезультат черезоператор returnчерез списокпараметров.