У програмирању, потпрограм је низ програмских инструкција које обављају одређени задатак, упаковане као јединица. Ова јединица се затим може користити у програмима кад год треба извести тај конкретан задатак. Потпрограми се могу дефинисати у оквиру програма, или одвојено у библиотекама, које се могу искористити у разноврсним програмима. У различитим програмским језицима, потпрограм се може назвати: процедура, функција, рутина, метод или потпрограм. Генерички термин позивна јединица се понекад користи.
Као што само име потпрограма сугерише, потпрограм се понаша на исти начин као и рачунарски програм који се користи као један корак ширег програма или другог потпрограма. Потпрограм је често кодиран тако да може стартовати (позвати) неколико пута и са више места у току једног извршења програма, и из других потпрограма, а затим се преспоји назад (повратак) на следеће инструкције након позива чим је задатак потпрограма завршен. Морис Вилкис, Дејвид Вилер, а Стенли Гил су задужени за проналазак овог концепта, који су назвали затворени потпрограм, насупрот отвореном потпрограму или макроу.
Потпрограми су моћан програмски алат, и синтакса многих програмских језика укључује подршку за писање и коришћење. Разумно коришћење потпрограма (на пример, кроз структурирано програмирање приступа) често значајно смањи трошкове развоја и одржавања великог програма, док је повећан квалитет и поузданост. Потпрограми, често прикупљени у библиотекама, представљају важан механизам за дељење и трговање софтвера. Дисциплина објектно-оријентисано програмирање је базирана на објектима и методама (који су потпрограмима везани за ове објекте или класе објеката).
У поступку комбиновања метод назван третирани код, извршни програм је у основи низ подрутинских позива.
Основни појмови Садржај једног потпрограма је његово тело, које је део програмског кода који се извршава када се потпрограм зове или призива.
Потпрограм може бити написан тако да очекује да ће добити једну или више вредности података из позивајућег програма (његове параметре или формалних параметара). Расписивање програм пружа стварне вредности за ове параметре, који се зову аргументи. Различити програмски језици могу користити различите конвенције за доношење аргумената
Конвенција Опис Заједничка употреба Позив по вредности Аргумент је оцењен и копија вредности је прослеђена
потпрограму Уобичајено већина Алгол језика после Алгол 60, попут Паскала, Делфија, Симула, CPL, PL/M, Modula, Oberon, Ada, и многих других. Позив по референци Позивање на аргументе, обично се преноси његова адресаИзбор код већине Algol језика после Algol 60, попут Algol 68, Pascal, Delphi, Simula, CPL, PL/M, Modula, Oberon, Ada, и многих других. C (структуре и низови), C++, Fortran, PL/I Позив по резултату Параметар вредност је копиран назад у аргумент на повратку из потпрограма Ada OUT параметри Позив по вредности-резултату Параметар вредност је копиран назад на улазу у потпрограм и опет у повратку Algol Позив по имену Као макро - мења параметре са безвредним аргументима израза Algol, Scala Позив по константној вредности Као позив по вредности само што се тај параметар посматра као константа PL/I NONASSIGNABLE параметри, Ada IN параметри Подрутина може вратити израчунате вредности на својој колер (његове повратне вредности), или да обезбеди разне резултате вредности или излазне параметре. Заиста, уобичајена употреба потпрограма је да спроведе математичке функције, у којима је сврха потпрограма само да израчуна један или више резултата чије вредности се у потпуности одређују параметрима у потпрограма. (Примери могу укључити израчунавању логаритам броја или детерминанте матрице.)
Потпрограм позива може имати нежељене ефекте као што су мењање структуре података у меморији рачунара, читајући или пишући на периферне уређаје, креирање датотеке, заустављање програма или машине, или чак одлагање извршења програма за одређено време. Потпрограм са споредним ефектима може да врати различите резултате сваки пут када се зове, чак и ако то се зове са истим аргументима. Пример је случајна функција број, доступан на многим језицима, да врати различите псеудо случајне бројеве сваки пут када се зове. Широка употреба потпрограма са нежељеним ефектима је карактеристична за императивне програмске језике.
Потпрограм може бити кодиран тако да може да се позове рекурзивно, на једном или више места, да изврши свој задатак. Овај метод омогућава директну примену функција дефинисаних математичким индукцијама и рекурзивним подели па владај алгоритмима.
Потпрограм чија је сврха да се израчуна једна вредност функције (то јест да одговорите на питање да/не) се понекад назива предикат. У логици програмских језика, често све потпрограме зову предикатима, јер су пре свега одређују успех или неуспех. На пример, било који тип функције је рутина, али не и главна.
Језичка подршка Програмски језици високог нивоа обично укључују специфичне конструкције: ограничавање део програма (тела) који сачињава потпрограм додељивање идентификатора (име) потпрограму навођење имена и типова података параметара и вредности за повратак лично именовање простора за привремене променљиве идентификацију променљиве изван потпрограма који су доступни у њему позивање потпрограма додељивање вредности параметрима навођење повратних вредности из свог тела повратан на позивајући програм располагање вредностима враћеним позивом решавање свих изузетака са којима се срећу током позива паковање потпрограма у модуле, библиотеке, објекте, класе, итд.
Неки програмски језици, као што су Pascal, Fortran, Ada и многи дијалекти Basic, разликују функције или функције потпрограма, који пружају изричиту повратну вредност у позивајући програм, и потпрограма или процедуре, које не. У тим језицима, функције позиви су обично уграђени у изразима (на пример sqrt може бити позвана са y = z + sqrt(x)). Функција се понаша исто синтаксички као изјава (на пример print процедура може бити позвана са if x > 0 then print(x) или се експлицитно позива као CALL или GOSUB (на пример call print(x) Други језици као што су C и Lisp, не праве разлику између функција и потпрограма.
У строго функционалним програмским језицима као што су Haskell, потпрограм може имати никакве нежељених ефеката, што значи да се различити интерни делови програма неће променити. Функције ће увек вратити исти резултат ако више пута зовете са истим аргументима. Такви језици обично подржавају само функције, јер потпрограми које не враћају вредност немају користи, осим ако они могу изазвати споредне ефекте.
У програмским језицима као што су С, С++ и С #, Потпрограми такође могу једноставно да се називају функције, не треба мешати са математичким функцијама или функционалним програмирањем, који су различити концепти.
Преводилац језика ће обично превести процедуру позива и повратак у упутства машине у складу са добро дефинисаном позивном конвенцијом (конгресом), тако се да потпрограми могу превести одвојено од програма који их позивају. Наставне секвенце које одговарају позиву и повратним изјавама називају се поступни увод и епилог.
Предности Предности раздвајања програма у потпрограме укључују: Разбијање комплексног задатка програмирања у једноставније кораке: ово је један од два главна алата структурног програмирања, заједно са структурама података Смањење дупликата кода у оквиру програма Омогућава поновну употребу кода преко више програма Подела великог програмерског задатка различитим програмерима, или различитим фазама пројекта Скривање детаља имплементације од корисника потпрограма Побољшање следљивости (то јест већина језика нуди начине да се дође до трага позива који укључује имена укључених потпрограма, а можда чак и до више информација попут имена датотека и бројева линија); без разлагања кода у потпрограме, отклањање грешака било би немогуће.
Недостаци Позивајући се на потпрограм (насупрот коришћењу in-line кода) намеће нека рачунарска преоптерећења у позивном механизму.
Потпрограм обично захтева стандардан административни код - како на улазу тако и на излазу функције (функција увода и епилога - обично штеди опште регистре сврхе и враћа адресу као минимум).
Историја Идеја о потпрограма је почела да функционише након што су рачунарске машине постојале већ неко време. Аритметичке и условне инструкције раста планиране су унапред и да промениле су се релативно мало; али посебна упутства се користе за процедурне позиве су се веома много променила током година. Најранији рачунари и микропроцесори, као што је Експериментална машина мањег обима и RCA 1802( Small-Scale Experimental Machine и RCA 1802,), није имала ниједну инструкцију потпрограмског позива. Потпрограми су могли бити реализовани, али је потребно да програмери користе позивне секвенце - низ инструкција - на свакој локацији позива. Неки врло стари рачунари и микропроцесори, као што су IBM 1620, Intel 8008, и PIC, имају једну инструкцију потпрограмског позива који користи наменски хардверско складиште за чување повратне адресе - овакав хардвер подржава само неколико нивоа угњеждених потпрограма, али може да подржи рекурзивне потпрограме. Машине пре средине 1960-их - као што је UNIVAC I, PDP-1, и IBM 1130 - обично користе позивну конвенцију која је сачувала бројач са упутством у првој меморијској локацији под називом потпрограма. Ово омогућава произвољно дубоке нивое угњеждене потпрограме, али не подржава рекурзивне потпрограме. PDP-11 (1970) је један од првих рачунара са потпрограмском позивном инструкцијом са складиштењем; Ова функција подржава произвољно дубоко угњеждене потпрограме и подржава рекурзивне потпрограме.
Језичка подршка У раним монтажама, подршка потпрограма била је ограничена. Потпрограми нису експлицитно одвојени једни од других или од главног програма, и заиста изворни код једног потпрограма може се смењивати са оним другим кодом потпрограма. Неки монтери ће понудити предефинисане макрое за генерисање позива и враћање секвенце. До 1960-их, монтери су обично имали много софистициранију подршку и за спојене и одвојене окупљене потпрограме који би могли бити повезани заједно.
Потпрограмске библиотеке Чак и са овим незграпним приступом, потпрограми су се показали веома корисним. Због једне ствари су дозволили исти код који се користи у многим различитим програмима. Меморија је била врло оскудан ресурс на старим рачунарима, а Потпрограми дозвољавају значајне уштеде у величини програма.
У многим старим рачунарима, упутства програма су ушла у меморију од папирне траке. Сваки потпрограм је тада могао бити обезбеђен посебним комадом траке, утоварен или спојен пре или после главног програма; а иста потпрограм трака би тада могла да се користи од стране многих различитих програма. Сличан приступ је коришћен у рачунарима чији је главни улаз кроз бушене картице. Име потпрограм библиотека је првобитно значило библиотеку, у дословном смислу, која чува индексиране колекције таквих трака или картица за колективно коришћење.
Повратак индиректним скоком Да бисте уклонили потребу за само-модификацију кода, рачунарски дизајнери су најзад обезбедили посредну скок инструкцију, чији операнд је, уместо да буде повратна адреса, био локација на променљиве или процесор регистар који садржи повратну адресу.
На тим рачунарима, уместо мењања повратног скока потпрограма, позивни програм би сачувао повратне адресе у променљивој, тако да када се потпрограм заврши, изврши индиректан скок - непосредно извршење на локацији коју је дао унапред дефинисаном променљивом.
Скок на потпрограм Други напредак је био скок у потпрограмски инструкцију, који је комбиновао уштеду повратне адресе са позивним скока, чиме се значајно минимизира преоптерећење.