CINXE.COM
Ogled vira Podprogram - Wikipedija, prosta enciklopedija
<!DOCTYPE html> <html class="client-nojs vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-sticky-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-disabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-feature-night-mode-disabled skin-theme-clientpref-day vector-toc-not-available" lang="sl" dir="ltr"> <head> <meta charset="UTF-8"> <title>Ogled vira Podprogram - Wikipedija, prosta enciklopedija</title> <script>(function(){var className="client-js vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-sticky-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-disabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-feature-night-mode-disabled skin-theme-clientpref-day vector-toc-not-available";var cookie=document.cookie.match(/(?:^|; )slwikimwclientpreferences=([^;]+)/);if(cookie){cookie[1].split('%2C').forEach(function(pref){className=className.replace(new RegExp('(^| )'+pref.replace(/-clientpref-\w+$|[^\w-]+/g,'')+'-clientpref-\\w+( |$)'),'$1'+pref+'$2');});}document.documentElement.className=className;}());RLCONF={"wgBreakFrames":true,"wgSeparatorTransformTable":[",\t.",".\t,"],"wgDigitTransformTable":["",""], "wgDefaultDateFormat":"dmy full","wgMonthNames":["","januar","februar","marec","april","maj","junij","julij","avgust","september","oktober","november","december"],"wgRequestId":"e94af27c-5049-4cf8-8764-6f1165fc764f","wgCanonicalNamespace":"","wgCanonicalSpecialPageName":false,"wgNamespaceNumber":0,"wgPageName":"Podprogram","wgTitle":"Podprogram","wgCurRevisionId":6190887,"wgRevisionId":0,"wgArticleId":513110,"wgIsArticle":false,"wgIsRedirect":false,"wgAction":"edit","wgUserName":null,"wgUserGroups":["*"],"wgCategories":[],"wgPageViewLanguage":"sl","wgPageContentLanguage":"sl","wgPageContentModel":"wikitext","wgRelevantPageName":"Podprogram","wgRelevantArticleId":513110,"wgIsProbablyEditable":true,"wgRelevantPageIsProbablyEditable":true,"wgRestrictionEdit":[],"wgRestrictionMove":[],"wgNoticeProject":"wikipedia","wgCiteReferencePreviewsActive":true,"wgMediaViewerOnClick":true,"wgMediaViewerEnabledByDefault":true,"wgPopupsFlags":0,"wgVisualEditor":{"pageLanguageCode":"sl", "pageLanguageDir":"ltr","pageVariantFallbacks":"sl"},"wgMFDisplayWikibaseDescriptions":{"search":true,"watchlist":true,"tagline":true,"nearby":true},"wgWMESchemaEditAttemptStepOversample":false,"wgWMEPageLength":60000,"wgRelatedArticlesCompat":[],"wgEditSubmitButtonLabelPublish":true,"wgULSPosition":"interlanguage","wgULSisCompactLinksEnabled":false,"wgVector2022LanguageInHeader":true,"wgULSisLanguageSelectorEmpty":false,"wgCheckUserClientHintsHeadersJsApi":["brands","architecture","bitness","fullVersionList","mobile","model","platform","platformVersion"],"GEHomepageSuggestedEditsEnableTopics":true,"wgGETopicsMatchModeEnabled":false,"wgGEStructuredTaskRejectionReasonTextInputEnabled":false,"wgGELevelingUpEnabledForUser":false};RLSTATE={"ext.globalCssJs.user.styles":"ready","site.styles":"ready","user.styles":"ready","ext.globalCssJs.user":"ready","user":"ready","user.options":"loading","skins.vector.search.codex.styles":"ready","skins.vector.styles":"ready","skins.vector.icons":"ready" ,"ext.charinsert.styles":"ready","ext.wikimediamessages.styles":"ready","ext.visualEditor.desktopArticleTarget.noscript":"ready","ext.uls.interlanguage":"ready","ext.wikimediaBadges":"ready"};RLPAGEMODULES=["mediawiki.action.edit.collapsibleFooter","site","mediawiki.page.ready","skins.vector.js","ext.centralNotice.geoIP","ext.charinsert","ext.gadget.refToolbar","ext.gadget.CommonsDirekt","ext.gadget.switcher","ext.urlShortener.toolbar","ext.centralauth.centralautologin","ext.popups","ext.visualEditor.desktopArticleTarget.init","ext.visualEditor.targetLoader","ext.echo.centralauth","ext.eventLogging","ext.wikimediaEvents","ext.navigationTiming","ext.uls.interface","ext.cx.eventlogging.campaigns","ext.checkUser.clientHints","ext.growthExperiments.SuggestedEditSession","wikibase.sidebar.tracking"];</script> <script>(RLQ=window.RLQ||[]).push(function(){mw.loader.impl(function(){return["user.options@12s5i",function($,jQuery,require,module){mw.user.tokens.set({"patrolToken":"+\\","watchToken":"+\\","csrfToken":"+\\"}); }];});});</script> <link rel="stylesheet" href="/w/load.php?lang=sl&modules=ext.charinsert.styles%7Cext.uls.interlanguage%7Cext.visualEditor.desktopArticleTarget.noscript%7Cext.wikimediaBadges%7Cext.wikimediamessages.styles%7Cskins.vector.icons%2Cstyles%7Cskins.vector.search.codex.styles&only=styles&skin=vector-2022"> <script async="" src="/w/load.php?lang=sl&modules=startup&only=scripts&raw=1&skin=vector-2022"></script> <meta name="ResourceLoaderDynamicStyles" content=""> <link rel="stylesheet" href="/w/load.php?lang=sl&modules=site.styles&only=styles&skin=vector-2022"> <meta name="generator" content="MediaWiki 1.44.0-wmf.5"> <meta name="referrer" content="origin"> <meta name="referrer" content="origin-when-cross-origin"> <meta name="robots" content="noindex,nofollow,max-image-preview:standard"> <meta name="format-detection" content="telephone=no"> <meta name="viewport" content="width=1120"> <meta property="og:title" content="Ogled vira Podprogram - Wikipedija, prosta enciklopedija"> <meta property="og:type" content="website"> <link rel="alternate" media="only screen and (max-width: 640px)" href="//sl.m.wikipedia.org/wiki/Podprogram"> <link rel="alternate" type="application/x-wiki" title="Uredi" href="/w/index.php?title=Podprogram&action=edit"> <link rel="apple-touch-icon" href="/static/apple-touch/wikipedia.png"> <link rel="icon" href="/static/favicon/wikipedia.ico"> <link rel="search" type="application/opensearchdescription+xml" href="/w/rest.php/v1/search" title="Wikipedija (sl)"> <link rel="EditURI" type="application/rsd+xml" href="//sl.wikipedia.org/w/api.php?action=rsd"> <link rel="canonical" href="https://sl.wikipedia.org/wiki/Podprogram"> <link rel="license" href="https://creativecommons.org/licenses/by-sa/4.0/deed.sl"> <link rel="alternate" type="application/atom+xml" title="Atom-vir strani »Wikipedija«" href="/w/index.php?title=Posebno:ZadnjeSpremembe&feed=atom"> <link rel="dns-prefetch" href="//login.wikimedia.org"> </head> <body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject mw-editable page-Podprogram rootpage-Podprogram skin-vector-2022 action-edit"><a class="mw-jump-link" href="#bodyContent">Pojdi na vsebino</a> <div class="vector-header-container"> <header class="vector-header mw-header"> <div class="vector-header-start"> <nav class="vector-main-menu-landmark" aria-label="Projekt"> <div id="vector-main-menu-dropdown" class="vector-dropdown vector-main-menu-dropdown vector-button-flush-left vector-button-flush-right" > <input type="checkbox" id="vector-main-menu-dropdown-checkbox" role="button" aria-haspopup="true" data-event-name="ui.dropdown-vector-main-menu-dropdown" class="vector-dropdown-checkbox " aria-label="Glavni meni" > <label id="vector-main-menu-dropdown-label" for="vector-main-menu-dropdown-checkbox" class="vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet cdx-button--icon-only " aria-hidden="true" ><span class="vector-icon mw-ui-icon-menu mw-ui-icon-wikimedia-menu"></span> <span class="vector-dropdown-label-text">Glavni meni</span> </label> <div class="vector-dropdown-content"> <div id="vector-main-menu-unpinned-container" class="vector-unpinned-container"> <div id="vector-main-menu" class="vector-main-menu vector-pinnable-element"> <div class="vector-pinnable-header vector-main-menu-pinnable-header vector-pinnable-header-unpinned" data-feature-name="main-menu-pinned" data-pinnable-element-id="vector-main-menu" data-pinned-container-id="vector-main-menu-pinned-container" data-unpinned-container-id="vector-main-menu-unpinned-container" > <div class="vector-pinnable-header-label">Glavni meni</div> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-pin-button" data-event-name="pinnable-header.vector-main-menu.pin">prestavi v stransko letvico</button> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button" data-event-name="pinnable-header.vector-main-menu.unpin">skrij</button> </div> <div id="p-navigation" class="vector-menu mw-portlet mw-portlet-navigation" > <div class="vector-menu-heading"> Navigacija </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="n-mainpage" class="mw-list-item"><a href="/wiki/Glavna_stran" title="Obiščite glavno stran [z]" accesskey="z"><span>Glavna stran</span></a></li><li id="n-introduction" class="mw-list-item"><a href="/wiki/Pomo%C4%8D:Uvod"><span>Naučite se urejati</span></a></li><li id="n-Izbrani-članki" class="mw-list-item"><a href="/wiki/Wikipedija:Izbrani_%C4%8Dlanki"><span>Izbrani članki</span></a></li><li id="n-randompage" class="mw-list-item"><a href="/wiki/Posebno:Naklju%C4%8Dno" title="Naložite naključno stran [x]" accesskey="x"><span>Naključna stran</span></a></li><li id="n-recentchanges" class="mw-list-item"><a href="/wiki/Posebno:ZadnjeSpremembe" title="Seznam zadnjih sprememb Wikipedije [r]" accesskey="r"><span>Zadnje spremembe</span></a></li> </ul> </div> </div> <div id="p-obcestvo" class="vector-menu mw-portlet mw-portlet-obcestvo" > <div class="vector-menu-heading"> Skupnost </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="n-help" class="mw-list-item"><a href="/wiki/Pomo%C4%8D:Vsebina" title="Kraj, kjer lahko prejmete pomoč"><span>Pomoč</span></a></li><li id="n-Pod-lipo" class="mw-list-item"><a href="/wiki/Wikipedija:Pod_lipo"><span>Pod lipo</span></a></li><li id="n-portal" class="mw-list-item"><a href="/wiki/Wikipedija:Portal_skupnosti" title="O projektu, kaj lahko storite, kje lahko kaj najdete"><span>Portal skupnosti</span></a></li><li id="n-contact" class="mw-list-item"><a href="/wiki/Wikipedija:Stik_z_nami"><span>Stik z nami</span></a></li> </ul> </div> </div> </div> </div> </div> </div> </nav> <a href="/wiki/Glavna_stran" class="mw-logo"> <img class="mw-logo-icon" src="/static/images/icons/wikipedia.png" alt="" aria-hidden="true" height="50" width="50"> <span class="mw-logo-container skin-invert"> <img class="mw-logo-wordmark" alt="Wikipedija" src="/static/images/mobile/copyright/wikipedia-wordmark-sl.svg" style="width: 7.4375em; height: 1.375em;"> <img class="mw-logo-tagline" alt="prosta enciklopedija" src="/static/images/mobile/copyright/wikipedia-tagline-sl.svg" width="118" height="13" style="width: 7.375em; height: 0.8125em;"> </span> </a> </div> <div class="vector-header-end"> <div id="p-search" role="search" class="vector-search-box-vue vector-search-box-collapses vector-search-box-show-thumbnail vector-search-box-auto-expand-width vector-search-box"> <a href="/wiki/Posebno:Iskanje" class="cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet cdx-button--icon-only search-toggle" title="Preiščite viki [f]" accesskey="f"><span class="vector-icon mw-ui-icon-search mw-ui-icon-wikimedia-search"></span> <span>Iskanje</span> </a> <div class="vector-typeahead-search-container"> <div class="cdx-typeahead-search cdx-typeahead-search--show-thumbnail cdx-typeahead-search--auto-expand-width"> <form action="/w/index.php" id="searchform" class="cdx-search-input cdx-search-input--has-end-button"> <div id="simpleSearch" class="cdx-search-input__input-wrapper" data-search-loc="header-moved"> <div class="cdx-text-input cdx-text-input--has-start-icon"> <input class="cdx-text-input__input" type="search" name="search" placeholder="Iskanje v Wikipediji" aria-label="Iskanje v Wikipediji" autocapitalize="sentences" title="Preiščite viki [f]" accesskey="f" id="searchInput" > <span class="cdx-text-input__icon cdx-text-input__start-icon"></span> </div> <input type="hidden" name="title" value="Posebno:Iskanje"> </div> <button class="cdx-button cdx-search-input__end-button">Išči</button> </form> </div> </div> </div> <nav class="vector-user-links vector-user-links-wide" aria-label="Osebna orodja"> <div class="vector-user-links-main"> <div id="p-vector-user-menu-preferences" class="vector-menu mw-portlet emptyPortlet" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> </ul> </div> </div> <div id="p-vector-user-menu-userpage" class="vector-menu mw-portlet emptyPortlet" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> </ul> </div> </div> <nav class="vector-appearance-landmark" aria-label="Videz"> <div id="vector-appearance-dropdown" class="vector-dropdown " title="Change the appearance of the page's font size, width, and color" > <input type="checkbox" id="vector-appearance-dropdown-checkbox" role="button" aria-haspopup="true" data-event-name="ui.dropdown-vector-appearance-dropdown" class="vector-dropdown-checkbox " aria-label="Videz" > <label id="vector-appearance-dropdown-label" for="vector-appearance-dropdown-checkbox" class="vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet cdx-button--icon-only " aria-hidden="true" ><span class="vector-icon mw-ui-icon-appearance mw-ui-icon-wikimedia-appearance"></span> <span class="vector-dropdown-label-text">Videz</span> </label> <div class="vector-dropdown-content"> <div id="vector-appearance-unpinned-container" class="vector-unpinned-container"> </div> </div> </div> </nav> <div id="p-vector-user-menu-notifications" class="vector-menu mw-portlet emptyPortlet" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> </ul> </div> </div> <div id="p-vector-user-menu-overflow" class="vector-menu mw-portlet" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="pt-sitesupport-2" class="user-links-collapsible-item mw-list-item user-links-collapsible-item"><a data-mw="interface" href="//donate.wikimedia.org/wiki/Special:FundraiserRedirector?utm_source=donate&utm_medium=sidebar&utm_campaign=C13_sl.wikipedia.org&uselang=sl" class=""><span>Denarni prispevki</span></a> </li> <li id="pt-createaccount-2" class="user-links-collapsible-item mw-list-item user-links-collapsible-item"><a data-mw="interface" href="/w/index.php?title=Posebno:Registracija&returnto=Podprogram&returntoquery=action%3Dedit" title="Predlagamo vam, da si ustvarite račun in se prijavite, vendar to ni obvezno." class=""><span>Ustvari račun</span></a> </li> <li id="pt-login-2" class="user-links-collapsible-item mw-list-item user-links-collapsible-item"><a data-mw="interface" href="/w/index.php?title=Posebno:Prijava&returnto=Podprogram&returntoquery=action%3Dedit" title="Prijava je zaželena, vendar ni obvezna [o]" accesskey="o" class=""><span>Prijava</span></a> </li> </ul> </div> </div> </div> <div id="vector-user-links-dropdown" class="vector-dropdown vector-user-menu vector-button-flush-right vector-user-menu-logged-out" title="Več možnosti" > <input type="checkbox" id="vector-user-links-dropdown-checkbox" role="button" aria-haspopup="true" data-event-name="ui.dropdown-vector-user-links-dropdown" class="vector-dropdown-checkbox " aria-label="Osebna orodja" > <label id="vector-user-links-dropdown-label" for="vector-user-links-dropdown-checkbox" class="vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet cdx-button--icon-only " aria-hidden="true" ><span class="vector-icon mw-ui-icon-ellipsis mw-ui-icon-wikimedia-ellipsis"></span> <span class="vector-dropdown-label-text">Osebna orodja</span> </label> <div class="vector-dropdown-content"> <div id="p-personal" class="vector-menu mw-portlet mw-portlet-personal user-links-collapsible-item" title="Uporabniški meni" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="pt-sitesupport" class="user-links-collapsible-item mw-list-item"><a href="//donate.wikimedia.org/wiki/Special:FundraiserRedirector?utm_source=donate&utm_medium=sidebar&utm_campaign=C13_sl.wikipedia.org&uselang=sl"><span>Denarni prispevki</span></a></li><li id="pt-createaccount" class="user-links-collapsible-item mw-list-item"><a href="/w/index.php?title=Posebno:Registracija&returnto=Podprogram&returntoquery=action%3Dedit" title="Predlagamo vam, da si ustvarite račun in se prijavite, vendar to ni obvezno."><span class="vector-icon mw-ui-icon-userAdd mw-ui-icon-wikimedia-userAdd"></span> <span>Ustvari račun</span></a></li><li id="pt-login" class="user-links-collapsible-item mw-list-item"><a href="/w/index.php?title=Posebno:Prijava&returnto=Podprogram&returntoquery=action%3Dedit" title="Prijava je zaželena, vendar ni obvezna [o]" accesskey="o"><span class="vector-icon mw-ui-icon-logIn mw-ui-icon-wikimedia-logIn"></span> <span>Prijava</span></a></li> </ul> </div> </div> <div id="p-user-menu-anon-editor" class="vector-menu mw-portlet mw-portlet-user-menu-anon-editor" > <div class="vector-menu-heading"> Strani za neprijavljene urejevalce <a href="/wiki/Pomo%C4%8D:Uvod" aria-label="Več o urejanju"><span>več o tem</span></a> </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="pt-anoncontribs" class="mw-list-item"><a href="/wiki/Posebno:MojiPrispevki" title="Seznam urejanj s tega IP-naslova [y]" accesskey="y"><span>Prispevki</span></a></li><li id="pt-anontalk" class="mw-list-item"><a href="/wiki/Posebno:MojPogovor" title="Pogovor o urejanjih s tega IP-naslova [n]" accesskey="n"><span>Pogovorna stran</span></a></li> </ul> </div> </div> </div> </div> </nav> </div> </header> </div> <div class="mw-page-container"> <div class="mw-page-container-inner"> <div class="vector-sitenotice-container"> <div id="siteNotice"><!-- CentralNotice --></div> </div> <div class="vector-column-start"> <div class="vector-main-menu-container"> <div id="mw-navigation"> <nav id="mw-panel" class="vector-main-menu-landmark" aria-label="Projekt"> <div id="vector-main-menu-pinned-container" class="vector-pinned-container"> </div> </nav> </div> </div> </div> <div class="mw-content-container"> <main id="content" class="mw-body"> <header class="mw-body-header vector-page-titlebar"> <h1 id="firstHeading" class="firstHeading mw-first-heading">Ogled vira Podprogram</h1> <div id="p-lang-btn" class="vector-dropdown mw-portlet mw-portlet-lang" > <input type="checkbox" id="p-lang-btn-checkbox" role="button" aria-haspopup="true" data-event-name="ui.dropdown-p-lang-btn" class="vector-dropdown-checkbox mw-interlanguage-selector" aria-label="Ta članek obstaja samo v tem jeziku. Dodajte članke v drugih jezikih." > <label id="p-lang-btn-label" for="p-lang-btn-checkbox" class="vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet cdx-button--action-progressive mw-portlet-lang-heading-0" aria-hidden="true" ><span class="vector-icon mw-ui-icon-language-progressive mw-ui-icon-wikimedia-language-progressive"></span> <span class="vector-dropdown-label-text">Dodaj jezike</span> </label> <div class="vector-dropdown-content"> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> </ul> <div class="after-portlet after-portlet-lang"><span class="uls-after-portlet-link"></span></div> </div> </div> </div> </header> <div class="vector-page-toolbar"> <div class="vector-page-toolbar-container"> <div id="left-navigation"> <nav aria-label="Imenski prostori"> <div id="p-associated-pages" class="vector-menu vector-menu-tabs mw-portlet mw-portlet-associated-pages" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="ca-nstab-main" class="selected vector-tab-noicon mw-list-item"><a href="/wiki/Podprogram" title="Ogled vsebinske strani [c]" accesskey="c"><span>Stran</span></a></li><li id="ca-talk" class="new vector-tab-noicon mw-list-item"><a href="/w/index.php?title=Pogovor:Podprogram&action=edit&redlink=1" rel="discussion" class="new" title="Pogovor o vsebinski strani (stran ne obstaja) [t]" accesskey="t"><span>Pogovor</span></a></li> </ul> </div> </div> <div id="vector-variants-dropdown" class="vector-dropdown emptyPortlet" > <input type="checkbox" id="vector-variants-dropdown-checkbox" role="button" aria-haspopup="true" data-event-name="ui.dropdown-vector-variants-dropdown" class="vector-dropdown-checkbox " aria-label="Spremeni različico jezika" > <label id="vector-variants-dropdown-label" for="vector-variants-dropdown-checkbox" class="vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet" aria-hidden="true" ><span class="vector-dropdown-label-text">slovenščina</span> </label> <div class="vector-dropdown-content"> <div id="p-variants" class="vector-menu mw-portlet mw-portlet-variants emptyPortlet" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> </ul> </div> </div> </div> </div> </nav> </div> <div id="right-navigation" class="vector-collapsible"> <nav aria-label="Pogledi"> <div id="p-views" class="vector-menu vector-menu-tabs mw-portlet mw-portlet-views" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="ca-view" class="vector-tab-noicon mw-list-item"><a href="/wiki/Podprogram"><span>Preberi</span></a></li><li id="ca-ve-edit" class="vector-tab-noicon mw-list-item"><a href="/w/index.php?title=Podprogram&veaction=edit" title="Uredite to stran [v]" accesskey="v"><span>Uredi stran</span></a></li><li id="ca-edit" class="selected collapsible vector-tab-noicon mw-list-item"><a href="/w/index.php?title=Podprogram&action=edit" title="Uredi izvorno kodo te strani"><span>Uredi kodo</span></a></li><li id="ca-history" class="vector-tab-noicon mw-list-item"><a href="/w/index.php?title=Podprogram&action=history" title="Prejšnje redakcije te strani [h]" accesskey="h"><span>Zgodovina</span></a></li> </ul> </div> </div> </nav> <nav class="vector-page-tools-landmark" aria-label="Orodja strani"> <div id="vector-page-tools-dropdown" class="vector-dropdown vector-page-tools-dropdown" > <input type="checkbox" id="vector-page-tools-dropdown-checkbox" role="button" aria-haspopup="true" data-event-name="ui.dropdown-vector-page-tools-dropdown" class="vector-dropdown-checkbox " aria-label="Orodja" > <label id="vector-page-tools-dropdown-label" for="vector-page-tools-dropdown-checkbox" class="vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet" aria-hidden="true" ><span class="vector-dropdown-label-text">Orodja</span> </label> <div class="vector-dropdown-content"> <div id="vector-page-tools-unpinned-container" class="vector-unpinned-container"> <div id="vector-page-tools" class="vector-page-tools vector-pinnable-element"> <div class="vector-pinnable-header vector-page-tools-pinnable-header vector-pinnable-header-unpinned" data-feature-name="page-tools-pinned" data-pinnable-element-id="vector-page-tools" data-pinned-container-id="vector-page-tools-pinned-container" data-unpinned-container-id="vector-page-tools-unpinned-container" > <div class="vector-pinnable-header-label">Orodja</div> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-pin-button" data-event-name="pinnable-header.vector-page-tools.pin">prestavi v stransko letvico</button> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button" data-event-name="pinnable-header.vector-page-tools.unpin">skrij</button> </div> <div id="p-cactions" class="vector-menu mw-portlet mw-portlet-cactions emptyPortlet vector-has-collapsible-items" title="Več možnosti" > <div class="vector-menu-heading"> Dejanja </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="ca-more-view" class="vector-more-collapsible-item mw-list-item"><a href="/wiki/Podprogram"><span>Preberi</span></a></li><li id="ca-more-ve-edit" class="vector-more-collapsible-item mw-list-item"><a href="/w/index.php?title=Podprogram&veaction=edit" title="Uredite to stran [v]" accesskey="v"><span>Uredi stran</span></a></li><li id="ca-more-edit" class="selected collapsible vector-more-collapsible-item mw-list-item"><a href="/w/index.php?title=Podprogram&action=edit" title="Uredi izvorno kodo te strani [e]" accesskey="e"><span>Uredi kodo</span></a></li><li id="ca-more-history" class="vector-more-collapsible-item mw-list-item"><a href="/w/index.php?title=Podprogram&action=history"><span>Zgodovina</span></a></li> </ul> </div> </div> <div id="p-tb" class="vector-menu mw-portlet mw-portlet-tb" > <div class="vector-menu-heading"> Splošno </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="t-whatlinkshere" class="mw-list-item"><a href="/wiki/Posebno:KajSePovezujeSem/Podprogram" title="Seznam vseh strani, ki se povezujejo sem [j]" accesskey="j"><span>Kaj se povezuje sem</span></a></li><li id="t-recentchangeslinked" class="mw-list-item"><a href="/wiki/Posebno:RecentChangesLinked/Podprogram" rel="nofollow" title="Zadnje spremembe na straneh, s katerimi se povezuje ta stran [k]" accesskey="k"><span>Povezane spremembe</span></a></li><li id="t-specialpages" class="mw-list-item"><a href="/wiki/Posebno:PosebneStrani" title="Seznam vseh posebnih strani [q]" accesskey="q"><span>Posebne strani</span></a></li><li id="t-info" class="mw-list-item"><a href="/w/index.php?title=Podprogram&action=info" title="Več informacij o tej strani"><span>Podatki o strani</span></a></li><li id="t-urlshortener" class="mw-list-item"><a href="/w/index.php?title=Posebno:UrlShortener&url=https%3A%2F%2Fsl.wikipedia.org%2Fw%2Findex.php%3Ftitle%3DPodprogram%26action%3Dedit"><span>Pridobi skrajšani URL</span></a></li><li id="t-urlshortener-qrcode" class="mw-list-item"><a href="/w/index.php?title=Posebno:QrCode&url=https%3A%2F%2Fsl.wikipedia.org%2Fw%2Findex.php%3Ftitle%3DPodprogram%26action%3Dedit"><span>Prenesi kodo QR</span></a></li> </ul> </div> </div> <div id="p-wikibase-otherprojects" class="vector-menu mw-portlet mw-portlet-wikibase-otherprojects" > <div class="vector-menu-heading"> V drugih projektih </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="t-wikibase" class="wb-otherproject-link wb-otherproject-wikibase-dataitem mw-list-item"><a href="https://www.wikidata.org/wiki/Special:EntityPage/Q190686" title="Povezava na ustrezni predmet v podatkovni shrambi [g]" accesskey="g"><span>Predmet v Wikipodatkih</span></a></li> </ul> </div> </div> </div> </div> </div> </div> </nav> </div> </div> </div> <div class="vector-column-end"> <div class="vector-sticky-pinned-container"> <nav class="vector-page-tools-landmark" aria-label="Orodja strani"> <div id="vector-page-tools-pinned-container" class="vector-pinned-container"> </div> </nav> <nav class="vector-appearance-landmark" aria-label="Videz"> <div id="vector-appearance-pinned-container" class="vector-pinned-container"> <div id="vector-appearance" class="vector-appearance vector-pinnable-element"> <div class="vector-pinnable-header vector-appearance-pinnable-header vector-pinnable-header-pinned" data-feature-name="appearance-pinned" data-pinnable-element-id="vector-appearance" data-pinned-container-id="vector-appearance-pinned-container" data-unpinned-container-id="vector-appearance-unpinned-container" > <div class="vector-pinnable-header-label">Videz</div> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-pin-button" data-event-name="pinnable-header.vector-appearance.pin">prestavi v stransko letvico</button> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button" data-event-name="pinnable-header.vector-appearance.unpin">skrij</button> </div> </div> </div> </nav> </div> </div> <div id="bodyContent" class="vector-body" aria-labelledby="firstHeading" data-mw-ve-target-container> <div class="vector-body-before-content"> <div class="mw-indicators"> </div> </div> <div id="contentSub"><div id="mw-content-subtitle">← <a href="/wiki/Podprogram" title="Podprogram">Podprogram</a></div></div> <div id="mw-content-text" class="mw-body-content"><p>Za urejanje te strani nimate dovoljenja zaradi naslednjega razloga: </p> <div class="permissions-errors"><div class="mw-permissionerror-globalblocking-blockedtext-range"><b>Vaš IP-naslov je v razponu, ki je <a href="https://meta.wikimedia.org/wiki/Special:MyLanguage/Global_blocks" class="extiw" title="m:Special:MyLanguage/Global blocks">blokiran v vseh vikijih Fundacije Wikimedia</a>.</b> <p>Blokiranje je opravil_a uporabnik_ca <a href="/wiki/Uporabnik:Jon_Kolbert" title="Uporabnik:Jon Kolbert">Jon Kolbert</a>. Navedeni razlog: <i><a href="https://meta.wikimedia.org/wiki/Special:MyLanguage/NOP" class="extiw" title="m:Special:MyLanguage/NOP">Open proxy/Webhost</a>: See the <a href="https://meta.wikimedia.org/wiki/WM:OP/H" class="extiw" title="m:WM:OP/H">help page</a> if you are affected </i>. </p> <ul><li>Začetek blokiranja: 16:12, 27. avgust 2023</li> <li>Pretek blokiranja: 16:12, 27. avgust 2028</li></ul> <p>Vaš trenutni IP-naslov je 8.222.208.146. Blokirani razpon je 8.222.128.0/17. </p><p>Prosimo, da v vseh morebitnih poizvedbah vključite vse zgornje podrobnosti. Če menite, da ste bili blokirani po pomoti, lahko najdete dodatne informacije in navodila v globalnem pravilniku <a href="https://meta.wikimedia.org/wiki/Special:MyLanguage/No_open_proxies" class="extiw" title="m:Special:MyLanguage/No open proxies">Brez odprtih posredniških strežnikov</a>. </p> V nasprotnem primeru prosimo, da za razpravo o blokiranju <a href="https://meta.wikimedia.org/wiki/Steward_requests/Global" class="extiw" title="m:Steward requests/Global">objavite zahtevek za pregled v Meta-Wikiju</a>. Lahko tudi pošljete e-pošto v čakalno vrsto <a href="https://meta.wikimedia.org/wiki/Special:MyLanguage/Stewards" class="extiw" title="m:Special:MyLanguage/Stewards">upravnikov</a> <a href="https://meta.wikimedia.org/wiki/Special:MyLanguage/VRT" class="extiw" title="m:Special:MyLanguage/VRT">VRT</a> na <kbd>stewards@wikimedia.org</kbd>, vključno z vsemi zgornjimi podatki.</div></div><hr /> <p>Vsebino te strani si lahko ogledate in jo kopirate. </p><textarea readonly="" accesskey="," id="wpTextbox1" cols="80" rows="25" style="" class="mw-editfont-monospace" lang="sl" dir="ltr" name="wpTextbox1">{{short description|del računalniškega programa}} '''Podprogram'''<ref name="dis__2022" /><ref name="fran_2021" /><ref name="wikisl0" /><ref name="islovar" /> [pòtprográm] je v [[računalništvo|računalništvu]] zaporedje [[ukaz (računalništvo)|programskih ukazov]], ki izvaja določeno [[naloga (računalništvo)|nalogo]], zbrano kot [[enota]]. Ta enota se lahko potem rabi v programih kjerkoli se mora ta določena naloga izvesti. {{anchor|SUBROUTINE_DEFINITION}}Podprogrami so lahko določeni znotraj programov ali ločeno v [[knjižnica (računalništvo)|programskih knjižnicah]] in jih lahko uporabijo drugi programi. V različnih [[programski jezik|programskih jezikih]] se podprogrami lahko imenujejo '''pòdrutȋna''',<ref name="dis__2022" /><ref name="wikisl1" /> '''rutȋna''', '''fúnkcija''', [[metoda (računalništvo)|'''metóda''']] ali '''procedúra'''. Tehnično imajo ti izrazi različne definicije in izrazje se od jezika do jezika razlikuje. Včasih se rabi tudi še splošnejši, [[podpomenke in nadpomenke|krovni izraz]] '''klicljìva enôta''' (''callable unit'').<ref name="usea_2007" /> Ime ''podprogram'' nakazuje, da se takšna enota obnaša na skoraj enak način kot računalniški program, ki se rabi kot en korak v večjem programu ali drugem podprogramu. Podprogram se velikokrat sprogramira tako, da se lahko med izvajanjem programa požene večkrat in z več mest, vključno iz drugih podprogramov, in po ''klicu'', ko je naloga podprograma zaključena, preide nazaj (''se vrne'') k naslednjemu ukazu. Podporogram si je začetno zamislil [[John Mauchly]] med svojim delom na [[računalnik]]u [[ENIAC]]<ref name="dasg_2014" /> in ga predstavil na harvardskem simpoziju »Preparation of Problems for EDVAC-type Machines« januarja 1947.<ref name= "mauc_1947" /> Za formalno iznajdbo tega koncepta veljajo [[Maurice Vincent Wilkes]], [[David John Wheeler]] in [[Stanley Gill]]. Imenovali so ga ''zaprti podprogram'',<ref name="whee_1952" /><ref name="wilk_1951" /> v nasprotju z ''odprtim podprogramom'' ali [[makro (računalništvo)|makrojem]].<ref name="dain_2004" /> Tudi [[Alan Turing|Turing]] je že obravnaval podprograme v članku leta 1945 o konstrukciji in predlogih za stroj [[samodejni računalniški stroj|ACE]] britanskega [[Narodni fizikalni laboratorij|Narodnega fizikalnega laboratorija]] in je šel tako daleč, da je izumil koncept sklada povratnega naslova (''return address stack'').<ref name="turi_1945" /> Podprogrami so močno programsko orodje<ref name="knut_1997" /> in [[skladnja (računalništvo)|skladnja]] mnogih programskih jezikov vsebuje podporo za njihovo pisanje in uporabo. Razumna raba podprogramov, na primer prek pristopa [[strukturalno programiranje|strukturalnega programiranja]], bo velikokrat zelo omejila ceno razvoja in vzdrževanja velikega programa, ter povečala njegovo kakovost in zanesljivost.<ref name="dahl_1972" /> Podprogrami, velikokrat zbrani v knjižnicah, so pomemben mehanizem za deljenje in prodajo [[programska oprema|programske opreme]]. Disciplina [[objektno usmerjeno programiranje|objektno usmerjenega programiranja]] temelji na [[objekt (računalništvo)|objektih]] in metodah, ki so podprogrami, pripojeni tem objektom ali [[razred (računalništvo)|razredom]] objektov. Pri [[prevajalnik|prevajanju]] se metoda imenuje [[povezana koda]] (''threaded code''), izvršni program pa je v bistvu zaporedje podprogramskih klicev. == Glavni koncepti == Vsebina podprograma je njegovo telo, ki je del [[programska koda|programske kode]], in ta se pri klicu podprograma izvede. Podprogram se lahko napiše tako, da od klicočega programa pričakuje eno ali več podatkovnih vrednosti – da nadomesti njegove [[parameter (računalništvo)|parametre]] (postavke) ali formalne parametre. Klicoči program zagotovi dejanske vrednosti teh parametrov, ki se imenujejo [[argument (računalništvo)|argumenti]]. Različni pogramski jeziki lahko rabijo različne dogovore za prenosne argumente: {| class="wikitable" |- ! dogovor !! opis !! splošna raba |- | klic po vrednosti || Argument se ovrednoti in kopija vrednosti se prenese na podprogram || Privzeto v večini jezikov podobnih [[ALGOL]]u po različici [[ALGOL 60]], kot so [[paskal (programski jezik)|paskal]], [[Borland Delphi|Delphi]], [[Simula]], [[CPL (programski jezik)|CPL]], [[PL/M]], [[Modula]], [[Oberon (programski jezik)|Oberon]], [[Ada (programnski jezik)|Ada]] in mnogi drugi. [[programski jezik C|C]], [[C++]], [[programski jezik java|java]] (sklici na objekte in polja se tudi prenašajo po vrednosti) |- | klic po sklicevanju || Sklicevanje na argument, tipično je prenesen njegov naslov || Izbirno v večini jezikov podobnih ALGOLu pa različici ALGOL 60, kot so [[ALGOL 68]], paskal, Delphi, Simula, CPL, PL/M, Modula, Oberon, Ada in mnogi drugi. C++, [[Fortran]], [[PL/I]] |- | klic po rezultatu || Vrednost parametra se kopira nazaj na argument pri vračanju iz podprograma || Ada – parametri OUT |- | klic po vrednosti-rezultatu || Vrednost parametra se kopira nazaj na vhod podprograma in spet pri vračanju || ALGOL, [[Swift (programski jezik)|Swift]] – parametri in-out |- | klic po imenu || Kot makro – nadomesti parametre z neovrednotenim izrazom argumenta, nato ovrednoti argument v kontekstu klicočega vsakokrat, ko ga klicani podprogram uporabi. || ALGOL, [[Scala (programski jezik)|Scala]] |- | klic po konstantni vrednosti || Podobno kot klic po vrednosti, razen, da se parameter obravnava kot konstanta || PL/I – parametri NONASSIGNABLE, Ada – parametri IN |} Podprogramski klic ima lahko tudi [[stranski učinek (računalništvo)|stranskje učinke]], ko je na primer spreminjanje [[podatkovna struktura|podatkovnih struktur]] v [[notranji pomnilnik|računalniškem pomnilniku]], branje ali pisanje na [[zunanja naprava|zunanjo napravo]], tvorjenje [[datoteka|datoteke]], zaustavljanje programa ali stroja ali celo zakasnitev izvrševanja programa za določen čas. Podprogram s stranskimi učinku lahko vrne različne rezultate vsakič, ko je klican, tudi, če je klican z enakimi argumenti. Zgled je [[generator psevdonaključnih števil|podprogram za naključna števila]], ki je na voljo v mnogih jezikih, in, ki pri vsakem klicu vrne različno psevdonaključno število. Široka raba podprogramov s stranskimi učinki je značilna za [[imperativno programiranje|imperativne]] jezike. Podprogramu so lahko sprogramirani tako, da lahko za izvedbo naloge [[rekurzija (računalništvo)|rekurzivno kličejo sami sebe]] na enem ali več mestih. Ta metoda omogoča neposredno implementacijo funkcij, ki so definirane z [[matematična indukcija|matematično indukcijo]] in rekurzivnimi [[algoritem|algoritmi]] [[deli in vladaj (računalništvo)|deli in vladaj]]. Podprogram, katerega namen je izračunati [[funkcija z Booleovo vrednostjo|funkcijo z Booleovo vrednostjo]], to je odgovor na vprašanje z da ali ne, se včasih imenuje [[predikat]]. V jezikih [[logično programiranje|logičnega programiranja]] se vsi podprogrami imenujejo predikati, ker prvenstveno določajo uspeh ali neuspeh. Podprogram, ki ne vrača nobene vrednosti ali vrača ničelno vrednost, se včasih imenuje procedura. Procedure po navadi spreminjajo svoje argumente in so bistveni del [[proceduralno programiranje|proceduralnega programiranja]]. == Funkcije == ''Funkcija'' je podprogram, ki vrne vrednost.<ref name="wils_2001" /> Glavni namen funkcij je razbiti zapletene izračune v smiselne kose in jih poimenovati.<ref name="stro_2013" /> Podprogram lahko vrne izračunano vrednost klicočemu (njegovo [[stavek za vrnitev|povratno vrednost]]), ali pa da različne vrednosti rezultatov ali izhodne parametre. Splošna raba podprogramov je res implementacija [[funkcija (matematika)|funkcij]] v katerih je namen podprograma zgolj izračun enega ali več rezultatov, katerih vrednosti so v celoti določene z argumenti, podanimi podprogramu. Taka zgleda sta na primer izračun [[logaritem|logaritma]] števila ali [[determinanta]] [[matrika|matrike]]. V nekaterih jezikih je skladnja za podprogram, ki vrača vrednost, dejansko enaka skladnji za podprogram, ki ne vrača vrednosti, razen za odsotnost na primer stavka RETURNS. V nekaterih jezikih lahko podprogram dinamično izbere ali vrne vrednost ali je ne vrne, kar je odvisno od njegovih argumentov. == Podpora jezikov == [[Visokonivojski programski jezik]]i po navadi vsebujejo določene konstrukte za: * razmejitev dela programa (telesa), ki tvori podprogram * dodelitev [[identifikator]]ja (imena) podprogramu * označitev imen in [[podatkovni tip|podatkovnih tipov]] njegovih parametrov in povratnih vrednosti * zagotovitev zasebnega [[doseg (računalništvo)|imenskega dosega]] njegovih [[začasna sprmenljivka|začasnih spremenljivk]] * istovetnost spremenljivk zunaj podprograma, ki so v njem dosegljive * klicanje podprograma * zagotovitev vrednosti njegovih parametrov * glavni program, ki naj vsebuje njegov naslov * podprogram, ki naj vsebuje naslov naslednjega ukaza za klic funkcije v glavnem programu * označitev povratnih vrednosti iz notranjosti njegovega telesa * [[stavek za vrnitev|vračanje]] h klicočemu programu * razmestitev vrednosti, ki jih vrne klic * [[upravljanje z izjemami]], ki se srečajo med klicem * pakiranje podprogramov v [[modularno programiranje|modul]], [[knjižnica (računalništvo)|knjižnico]], [[objekt (računalništvo)|objekt]] ali [[razred (računalništvo)|razred]] Nekateri programski jeziki, kot so [[paskal (programski jezik)|paskal]], [[Fortran]], [[programski jezik Ada|Ada]] in mnoga [[narečje (računalništvo)|narečja]] [[BASIC]]a, razlikujejo med funkcijami ali funkcijskimi podprogrami, ki zagotavljajo eksplicitno povratno vrednost klicočemu programu, in podprogrami ali procedurami, ki te vrednosti ne zagotavljajo. V teh jezikih so klici funkcij normalno vgrajeni v [[izraz (računalništvo)|izraze]] – na primer funkcija <code>sqrt</code> se lahko kliče kot <code>y = z + sqrt(x)</code>. Klici podprogramov se lahko obnašajo skladenjsko kot [[stavek (računalništvo)|stavki]] – prodprogram <code>print</code> se lahko kliče kot <code>if x > 0 then print(x)</code> ali pa jih eksplicitno kličejo stavki, kot na primer <code>CALL</code> ali <code>GOSUB</code> – na primer <code>call print(x)</code>). Drugi jeziki, kot sta [[programski jezik C|C]] in [[lisp (programski jezik)|lisp]], med funkcijami in podprogrami ne razlikujejo. V jeziki strogega [[funkcionalno programiranje|funkcionalnega programiranja]], kot je [[Haskell]], so lahko podprogrami brez [[stranski učinek (računalništvo)|stranskih učinkov]], kar pomeni, da se raznolična notranja stanja programa ne bodo spremenila. Funkcije bodo vedno vrnile enak rezultat, če se kličejo večkrat z enakimi argumenti. Takšni jeziki tipično podpirajo le funkcije, ker so podprogrami, ki ne vračajo vrednosti, neuporabni vse dokler ne povzročijo stranskega učinka. V programskih jezikih, kot so [[programski jezik C|C]], [[C++]] in [[programski jezik C sharp|C#]], se podprogrami lahko imenujejo preprosto funkcije, kar pa se ne sme zamenjevati s pojmoma funkcije v matematiki ali funkcionalnim programiranjem, ki sta različna koncepta. [[Prevajalnik]] jezika bo po navadi prevedel klice podprogramov in povratne vrednosti v strojne ukaze glede na dobro definiran [[dogovor o klicanju]], tako da se lahko podprogrami prevedejo ločeno od programov, ki jih kličejo. Zaporedja ukazov, ki odgovarja klicnim in povratnim stavkom, se imenuje [[uvod in sklepna beseda funkcije|uvod in sklepna beseda]] podprograma. V zelo zgodnjih [[zbirnik]]ih je bila podpora podprogramov omejena. Podprogrami eksplicitno niso bili ločeni drug od drugega ali od glavnega programa, in res se je lahko izvorna koda pomešala s tisto iz drugih programov. Nekateri zbirniki so ponujali preddefinirane [[makro (računalništvo)|makroje]] za tvorjenje zaporedij klicev in vračanj. Do 1960-ih so imeli zbirniki po navadi razvitejšo podporo tako za vrinjene kot za ločeno zbrane podprograme, ki se jih je dalo povezati skupaj. Eden od prvih programskih jezikov, ki je podpiral uporabniško napisane podprograme, je bil [[Fortran#FORTRAN_II|FORTRAN II]]. Prevajalnik za IBM FORTRAN II je izšel leta 1958. Tudi [[ALGOL 58]] in drugi zgodnji programski jeziki so podpirali proceduralno programiranje. == Prednosti == Prednosti razbitja programa na podprograme so: * [[dekompozicija (računalništvo)|dekompozicija]] zapletenih programskih nalog v preprostejše korake – to je eden od dveh glavnih orodij [[strukturalno programiranje|strukturalnega programiranja]] poleg podatkovnih tipov * zmanjšanje [[podvojena koda|podvojitev kode]] znotraj programa * usposobitev [[ponovna raba kode|ponovne rabe kode]] prek večkratnih programov * ločitev velike programske naloge med različne programerje ali različne stopnje projekta * [[skrivanje informacij|skrivanje podrobnosti izvedb]] od uporabnikov podprograma * izboljšanje berljivosti kode z zamenjevanjem bloka kode s klicem funkcije, kjer opisno ime funkcije služi za opis bloka kode.<ref name="mart_2009" /> Zaradi tega je klicna koda zgoščena in berljiva, četudi funkcija ni namenjena ponovni rabi. * izboljšanje [[sledljivost]]i – večina jezikov ponuja načine za dosego sledi klica, kar vsebuje imena vključenih podprogramov in mogoče še več informacij, kot so imena dototek in številke vrstic. Če se koda ne bi razstavila v podprograme, bi bilo [[razhroščevanje]] zelo oteženo. == Slabosti == V primerjavi z rabo vrinjene kode klicanje podprograma v klicnem mehanizmu vsiljuje nekaj [[režija (računalništvo)|računalniške režije]]. Podprogram tipično zahteva standardno [[vzdrževanje (računalništvo)|vzdrževalno]] kodo – tako pri vhodu in pri izhodu iz funkcije (uvod in sklepna beseda funkcije), kar po navadi [[procesorski register|registre za splošni namen]] in povratni naslov ohranja v najmanjšem obsegu. == Zgodovina == Zamisel podprograma je bila uresničena po tem, ko so računski stroji nekaj časa že obstajali. Ukazi aritmetičnih in pogojnih skokov so bili načrtovani v naprej in so se relativno malo spremenili, posebni ukazi za podprogramske klice pa so se skozi leta zelo spremenili. Najzgodnejši računalniki in [[mikroprocesor]]ji, kot sta na primer [[Manchester Baby]] in [[RCA 1802]], niso imeli enega ukaza za podprogramski klic. Podprogrami so se lahko izvedli, vendar so zahtevali programerje, ki so rabili klicno zaporedje – niz ukazov pri vsakem [[klicno mesto|klicnem mestu]]. Podprogrami so bili izvedeni v računalniku [[Z4 (računalnik)|Z4]] [[Konrad Zuse|Konrada Zuseja]] leta 1945. Leta 1945 je [[Alan Turing]] rabil izraz »skriti« (''bury'') in »ne skriti« (''unbury'') v smislu klicanja in vračanja iz podprogramov.<ref name="turi_1946" /><ref name="carp_1977" /> Januarja 1947 je [[John William Mauchly]] predstavil splošne opombe na Simpoziju o digitalnih računskih strojih velikega obsega pod skupnim pokroviteljstvom Univerze Harvard in Urada za oborožitev [[Vojna mornarica Združenih držav Amerike|VM ZDA]]. Tu je razpravljal o zaporednih in vzporednih operacijah ter predlagal: :: ...ni treba, da je zgradba stroja sploh zapletena. Ker so na voljo vse logične značilnosti, nujne za ta podprogram, je možno razviti kodni ukaz za umestitev podprogramov v pomnilnik na mesta, znana stroju, in na tak način, da se lahko preprosto kličejo v uporabo.{{paragraph break}}Z drugimi besedami, podprogram A za deljenje, podprogram B za kompleksno množenje in podprogram C za ovrednotenje standardne napake se lahko označijo kot zaporedje števil, in tako naprej skozi seznam podprogramov, potrebnih za določeni problem. ... Vsi ti podprogrami bodo potem shranjeni v stroju, in vse kar je treba narediti, je izdelati kratek sklic nanje s številom, kakor so naznačeni v kodiranju.<ref name="mauc_1947" /> [[Kathleen Antonelli|Kay McNulty]] je tesno sodelovala z Johnom Mauchlyjem v skupini razvoja računalnika [[ENIAC]] in razvila zamisel za podprograme zanj, ko ga je programirala med 2. svetovno vojno.<ref name="isaa_2014" /> Ona in drugi programerji računalnika ENIAC so uporabljali podprograme za pomoč pri izračunavanju trajektorij izstrelkov.<ref name="isaa_2014" /> [[Herman Heine Goldstine|Goldstine]] in [[John von Neumann|von Neumann]] sta napisala članek, datiran 16. avgusta 1948, kjer sta obravnavala rabo podprogramov.<ref name="gold_1947" /> Nekateri zelo zgodnji računalniki in mikroprocesorji, kot so [[IBM 1620]], [[Intel 4004]] in [[Intel 8008]], ter [[mikrokrmilnik]]i [[mikrokrmilnik PIC|PIC]] so imeli enoukazni podprogramski klic, ki je uporabljal dodeljeni strojni sklad za hranjenje povratnih naslovov – takšna [[strojna oprema računalnika|strojna oprema]] podpira le nekaj nivojev gnezdenja podprogramov, lahko pa podpira rekurzivne podprograme. Stroji pred sredino 1960-ih, kot so bili [[UNIVAC I]], [[PDP-1]] in [[IBM 1130]], so tipično rabili [[dogovor o klicanju]], ki je shranil števec ukazov v prvo pomnilniško lokacijo klicanega podprograma. To je omogočalo poljubno globoke nivoje gnezdenja podprogramov, ni pa podpiralo rekurzivnih podprogramov. [[PDP-11]] (1970) je bil eden prvih računalnikov z ukazom podprogramskega klica prek nakopičevalnega skladovnega pomnilnika – ta gradnik podpira tako poljubno globoko gnezdenje podprogramov kot tudi rekurzivne podprograme.<ref name="stee_1977" /> == Podprogramske knjižnice == Tudi s tako nerodnim pristopom so se podprogrami izkazali za zelo uporabne. Kot prvo so omogočili rabo iste kode v mnogih različnih programih. Poleg tega je bil v zgodnjih računalnikih pomnilnik zelo redek vir, tako da so programi omogočili prihranke velikosti programov. Mnogi zgodnji računalniki so vnašali programske ukaze v pomnilnik z [[luknjani trak|luknjanega traku]]. Vsak podprogram se je potem lahko pridobil z ločenim kosom traku, naloženim ali povezanim pred ali za glavnim programom (ali »glavno vrstico« (''mainline'')),<ref name="fran_1983" /> isti trak s podprogramom pa se je lahko uporabil pri mnogih različnih programih. Podobni pristop se je uporabil v računalnikih, ki so za svoj glavni vnos rabili [[luknjana kartica|luknjane kartice]]. Ime ''podprogramska knjižnica'' je izvirno pomenila [[knjižnica (računalništvo)|knjižnico]], v dobesednem smislu, saj so v njej hranili indeksirano zbirko trakov ali paketov kartic za skupno rabo. == Vračanje s posrednim skokom == Da so odstranili potrebo po [[samospreminjajoča se koda|samospreminjajoči se kodi]], so oblikovalci računalnikov zagotovili ukaz za ''[[posredni prehod|posredni skok]]'', kjer je bil operand, namesto, da je bil [[stavek za vrnitev|povratni naslov]] sam, lokacija spremenljivke ali [[procesorski register]], ki je vseboval povratni naslov. Na teh računalnikih je klicoči program, namesto spreminjanja povratnega skoka podprograma, hranil povratni naslov v spremenljivki, tako da, ko se je podprogram končal, je izvršil posredni skok, ki je usmerila izvršitev na lokacijo, dano s preddefinirano spremenljivko. == Skok do podprograma == Druga prednost je bil ukaz za ''skok do podprograma'', ki je kombiniral hranjenje povratnega naslova s klicočim skokom in tako zelo minimiziral režijo. V družini [[osrednji računalnik|osrednjih računalnikov]] [[IBM System/360]] bi ukaza za prehod BAL ali BALR, oblikovana za klicanje podprogramov, na primer shranila povratni naslov v procesorski register, naveden v ukazu, z dogovorjenim registrom 14. Za vračanje je moral podprogram le izvršiti ukaz za posredni prehod (BR) prek tega registra. Če je podprogram ta register potreboval za kakšen drug namen, kot na primer za klicanje drugega programa, je shranil vsebino registra v zasebno lokacijo pomnilnika ali v registrski [[sklad (računalništvo)|sklad]]. V sistemih, kot je na primer vrsta 16-bitnih [[miniračunalnik]]ov [[HP 2100]], bi ukaz JSB izvedel podobno nalogo s tem, da je bil povratni naslov shranjen v pomnilniški lokaciji, ki je bila tarča prehoda. Izvršitev podprograma se je dejansko začela na naslednji pomnilniški lokaciji. V [[zbirni jezik|zbirnem jeziku]] HP 2100 bi se na primer zapisalo: ... JSB MYSUB (klic podprograma MYSUB.) BB ... (vračanje sem, ko je MYSUB končan.) za klic podprograma z imenom MYSUB iz glavnega programa. Koda za podprogram bi bila: MYSUB NOP (hranjenje povratnega naslova za MYSUB.) AA ... (začetek telesa MYSUB.) ... JMP MYSUB,I (vračanje na klicoči program.) Ukaz JSB je postavil naslov ukaza NEXT (namreč BB) v lokacijo, navedeno kot njegov operand (namreč MYSUB), in potem prešel na lokacijo NEXT (namreč AA = MYSUB + 1). Podprogram se je lahko potem vrnil v glavni pogram s izvršitvijo posrednega skoka JMP MYSUB, I, ki je prehajal na lokacijo, shranjeno na lokaciji MYSUB. Prevajalniki za Fortran in druge jezike so lahko preprosto uporabili te ukaze, ko so bili na voljo. Ta pristop je podpiral večkratne nivoje klicev – ker pa so imeli povratni naslov, parametri in povratne vrednosti podprograma vseeno dodeljene stalne pomnilniške lokacije, to ni omogočalo rekurzivnih klicev. Sicer je bila podobna metoda rabljena v programu za [[preglednica|preglednice]] [[Lotus 1-2-3]] v zgodnjih 1980-ih za odkrivanje odvisnosti ponovnih izračunavanj v preglednici. Lokacija je bila rezervirana v vsaki celici za hranjenje ''povratnega'' naslova. Ker [[krožno sklicevanje|krožna sklicevanja]] za naravni vrstni red ponovnega izračunavanja niso dovoljena, je to omogočalo sprehod po drevesu brez rezerviranja prostora za sklad v pomnilniku, ki je bil zelo omejen na majhnih računalnikih, kot je mikroračunalnik [[IBM PC]]. == Klicni sklad == Večina modernihi zvedb podprogramskih klicev rabi [[klicni sklad]], posebno vrsto [[podatkovna struktura|podatkovne strukture]] [[sklad (računalništvo)|sklada]], za izvajanje podprogramskih klicev in vračanj. Vsak podprogramski klic tvori nov vpis, imenovan ''[[okvir sklada]]'' (''stack frame''), na vrhu sklada. Ko se podprogram vrača, se njegov okvir sklada s sklada pobriše, njegov prostor pa se lahko uporabi za drugi podprogramske klice. Vsak okvir sklada vsebuje ''zasebne podatke'' odgovarjajočega klica, kar tipično vključujed parametre in notranje spremenljivke podprograma, ter povratni naslov. Klicno zaporedje se lahko izvede z zaporedjem navadnih ukazov – ta pristop se še vedno rabi v arhitekturah [[RISC]] in [[VLIW]], vendar ima mnogo tradicionalnih strojev, oblikovanih od poznih 1960-ih, za ta namen vključene posebne ukaze. Klicni sklad se po navadi izvede kot soseedno območje pomnilnika. Ali bo dno sklada najnižji ali najvišji naslov znotraj tega območja, je poljubna izbira zasnove, tako da lahko sklad raste naprej ali nazaj v pomnilniku. Mnogo arhitektur rabi drugo možnost. Nekatere zasnove, še posebej izvedbe jezika [[Forth (programski jezik)|Forth]], rabijo dva ločena sklada, enega v glavnem za nadzorne informacije, kot so povratni naslovi in števci zank, drugega pa za podatke. Prvi je bil ali je delal kot klicni sklad in je bil le posredno dostopen programerju prek drugih jezikovnih konstruktov, drugi pa je bil bolj neposredno dostopen. Ko so prvič uvedli podprogramske klice na podlagi sklada, je bila pomembna vzpodbuda prihranek dragocenega pomnilnika. S takšno shemo prevajalniku za zasebne podatke (parametre, povratne naslove in krajevne spremenljivke) vsakega podprograma ni bilo treba rezervirati ločenega prostora v pomnilniku. V vsakem trenutku sklad vsebuje le zasebne podatke klicev, ki so trenutno ''dejavni'' – tisti, ki so bili klicani, pa se še niso vrnili. Zaradi načinov po katerih so bili programi zbrani iz knjižnic, je bilo (in še vedno je) običajno najti programe, ki so vključevali tisoče podprogramov, od katerih je samo nekaj dejavnih ob poljubnem danem trenutku. Za takšne programe je lahko mehanizem klicnega sklada prihranil pomembno količino pomnilnika. Na mehanizem klicnega sklada se res lahko gleda kot na najzgodnejšo in najpreprostejšo metodo [[čiščenje pomnilnika|samodejnega upravljanja s pomnilnikom]]. Druga prednost metode klicnega sklada je ta, da omogoča [[rekurzija (računalništvo)|rekurzivne]] podprogramske klice, ker vsak od vgnezdenih klicev istega poprograma dobi ločen primerek svojih zasebnih podatkov. === Zakasnjeno skladanje === Ena od slabosti mehanizma klicnega sklada je povečana cena podprogramskega klica in njemu ustreznega vračanja. Dodatni strošek vključuje povečevanje in zmanjševanje kazalca sklada in, v nekaterih arhitekturah, preverjanje [[prekoračitev sklada|prekoračitve sklada]], in dostopanje do krajevnih spremenljivk in parametrov z naslovi, relativnimi okvirjem, namesto absolutnih naslovov. Strošek se lahko uresniči v povečanem času izvajanja, povečani kompleksnosti procesorja ali oboje. Ta režija je najočitnejša in neprijetna v ''listnih podprogramih'' ali ''listnih funkcijah'', ki se vračajo brez, da bi sami tvorili kakšne podpogramske klice.<ref name="infocenter" /><ref name="microsoft0" /><ref name="microsoft1" /> Za zmanjšanje te režije mnogi moderni prevajalniki poskušajo zakasniti rabo klicnega sklada vse dokler res ni potreben. Klic podprograma ''P'' lahko na primer shrani njegov povratni naslov in parametre v določenih procesorskih registrih in s preprostim skokom prenese nadzor telesu podprograma. Če se podprogram ''P'' vrne brez, da bi klical druge podprograme, klicni sklad sploh ni rabljen. Če mora ''P'' klicati drug podprogram ''Q'', bo potem rabil klicni sklad za hranjenje vsebine kateregakoli registra (na primer povratnega naslova), ki bo potreben potem, ko se ''Q'' vrne. == Zgledi == === C in C++ === V programskih jezikih [[programski jezik C|C]] in [[C++]] se podprogrami imenujejo ''funkcije'', (še naprej razvrščeni kot ''funkcije članov'', ko so povezani z [[razred (računalništvo)|razredom]], ali ''proste funkcije,''<ref name="stackover" /> kadar niso). Ta dva jezika rabita posebno [[rezervirana beseda|ključno besedo]] <code>void</code> za naznačitev funkcije, ki ne vrača nobene vrednosti. Upoštevati je treba, da imajo lahko funkcije C/C++ stranske učinke, vključno s spreminjanjem poljubnih spremenljivk, katerih naslovi se prenašajo kot parametri. Zgledi so: <syntaxhighlight lang="c"> void funkcija1() { /* poljubna koda */ } </syntaxhighlight> ali <syntaxhighlight lang="c"> void funkcija1(void) { /* poljubna koda */ } </syntaxhighlight> Funkcija ne vrača vrednosti in se mora klicati kot samostojna funkcija, na primer <code>funkcija1();</code>. Funkcija je tudi brez argumentov, kar je pri njeni dodelitvi (definiciji) naznačeno kot <code>funkcija1()</code> ali eksplicitno kot <code>funkcija1(void)</code>. Pri klicanju funkcije ključne besede <code>void</code> za argumente ni treba rabiti in se kliče brez, na primer kar <code>funkcija1();</code>. <syntaxhighlight lang="c"> int funkcija2() { return 5; } </syntaxhighlight> Ta funkcija vrača rezultat (celo število 5) in klic je lahko del izraza, na primer <code>x + funkcija2()</code>. <syntaxhighlight lang="c"> char funkcija3(int stevilo) { char izbira[] = {'N', 'P', 'T', 'S', 'Č', 'P', 'S'}; return izbira[stevilo]; } </syntaxhighlight> Ta funkcija spremeni število med 0 in 6 v začetno črko odgovarjajočega dneva v tednu – 0 v 'N', 1 v 'P', ..., 6 v 'S'. Rezultat njenega klica se lahko dodeli spremenljivki, na primer <code>st_dneva = funkcija3(stevilo);</code>. <syntaxhighlight lang="c"> void funkcija4(int *kazalec_na_spremenljivko) { (*kazalec_na_spremenljivko)++; } </syntaxhighlight> Ta funkcija ne vrača vrednosti, vendar spreminja spremenljivko, katere naslov se prenaša kot parameter – kliče se kot <code>funkcija4(&spremenljivka_za_vecanje);</code>. === MS Small Basic === <syntaxhighlight lang="vbnet"> zgled() ' klic podprograma Sub zgled ' začetek podprograma TextWindow.WriteLine("To je zgled podprograma v jeziku MS Small Basic.") ' vsebina podpograma EndSub ' konec podprograma </syntaxhighlight> V zgornjem zgledu <code>zgled()</code> kliče podprogram.<ref name="microsoft2" /> V jeziku [[Microsoft Small Basic|MS Small Basic]] se mora za opredelitev dejanskega podprograma uporabiti ključna beseda <code>Sub</code>, čemur sledi ime podprograma <code>Sub zgled</code>. Po vsebini podprograma mora slediti ukaz za njegov konec <code>EndSub</code>. === Visual Basic 6 === V jeziku [[Visual Basic 6]] se podprogrami imenujejo ''funkcije'' ali ''sub-i'' (ali ''metode'', ko so povezane z razredom). Visual Basic 6 rabi različne izraze, imenovane ''types'', za opredelitev tega kar je preneseno kot parameter. Privzeto je neoznačena spremenljivka registrirana kot [[označena unija|spremenljivi tip]] in se lahko prenaša kot ''ByRef'' (privzeto) ali kot ''ByVal''. Kadar je funkcija ali sub označena (deklarirana), dobi označba javno (''public''), zasebno (''private'') ali prijateljsko (''friend''), kar določa ali se lahko dostopa zunaj modula ali projekta, kjer je bila označena. * po vrednosti [ByVal] – način prenašanja vrednosti argumenta k podprogramu s prenašanjem kopije vrednosti, namesto prenašanja naslova. Zaradi tega dejanske vrednosti spremenljivke podprogram, ki mu je bila vrednost prenesena, ne more spremeniti. * po sklicevanju [ByRef] – način prenašanja vrednosti argumenta k podprogramu s prenašanjem naslova spremenljivke, namesto prenašanja kopije njene vrednosti. To omogoča, da lahko podprogram dostopa do dejanske spremenljivke. Zaradi tega lahko podprogram, ki mu je bila vrednost prenesena, spremeni dejansko vrednost spremenljivke. Če ni drugače navedeno, se argumenti prenašajo po sklicevanju. * Public (izbirno) – nakazuje, da je funkcijski podprogram dostopen vsem drugim podprogramom v vseh modulih. Če se rabi v modulu, ki vsebuje izbiro Private, podprogram ni na voljo zunaj projekta. * Private (izbirno) – nakazuje, da je funkcijski podprogram dostopen le drugim podprogramom v modulu, kjer je označen. * Friend (izbirno) – se rabi le v razrednem modulu. Nakazuje, da je funkcijski podprogram viden skozi celotni projekt in neviden nadzorniku primerka objekta. <syntaxhighlight lang="vbnet"> Private Function funkcija1() ' poljubna koda End Function </syntaxhighlight> Funkcija ne vrača vrednosti in se mora klicati kot samostojna funkcija, na primer <code>funkcija1</code>. <syntaxhighlight lang="vbnet"> Private Function funkcija2() as Integer funkcija2 = 5 End Function </syntaxhighlight> Ta funkcija vrača rezultat (celo število 5) in klic je lahko del izraza, na primer <code>x + funkcija2()</code>. <syntaxhighlight lang="vbnet"> Private Function funkcija3(ByVal intValue as Integer) as String Dim polje_znakov(6) as String polje_znako = Array("P", "T", "S", "Č", "P", "S", "N") funkcija3 = polje_znakov(intValue) End Function </syntaxhighlight> Ta funkcija pretvori število med 0 in 6 v začetno črko odgovarjajočega dneva v tednu – 0 v 'P', 1 v 'T', ..., 6 v N 'S'. Rezultat njenega klica se lahko dodeli spremenljivki, na primer <code>st_dneva = funkcija3(stevilo)</code>. <syntaxhighlight lang="vbnet"> Private Function funkcija4(ByRef intValue as Integer) intValue = intValue + 1 End Function </syntaxhighlight> Ta funkcija ne vrača vrednosti, vendar spreminja spremenljivko, katere naslov se prenaša kot parameter – kliče se kot "<code>funkcija4(spremenljivka_za_vecanje)</code>". === PL/I === V jeziku [[PL/I]] klicani podprogram lahko prenaša ''[[podatkovni opisovalnik|opisnik]]'' (''deskriptor''), ki zagotalja informacije o argumentu, kot so na primer dolžine znakovnih nizov (stringov) in meje polj. To podprogramu omogoča širšo splošnost in izločanje potrebe programerju, da takšne informacije prenaša. Privzeto PL/I prenaša argumente po sklicevanju. (Trivialni) podprogram za spreminjanje predznaka vsakega elementa dvorazsežnega polja bi izgledal kot: <pre> spremeni_znak: procedure(polje); declare polje (*,*) float; polje = -polje; end spremeni_znak; </pre> To se lahko kliče z različnimi polji, kot sledi: <pre> /* prvo polje ima velikost od -5 do +10 in od 3 do 9 */ declare polje1 (-5:10, 3:9) float; /* drugo polje ima velikost od 1 do 16 in od 1 do 16 */ declare polje2 (16,16) float; call spremeni_znak(polje1); call spremeni_znak(polje2); </pre> === Python === V jeziku [[Python (programski jezik)|Python]] se za opredelitev funkcije rabi ključna beseda <code>def</code>. Stavek, ki tvori telo funkcije, se mora nadaljevati ali v isti vrstici ali pa se začeti v drugi vrstici in biti zamaknjen.<ref name="python" /> Naslednji zgled programa izpiše [[Pozdravljen, svet|»Pozdravljen, svet!«]], čemur sledi »Wikipedija« v naslednji vrstici: <syntaxhighlight lang="python"> def preprosta_funkcija(): print('Pozdravljen, svet!') print('Wikipedija') preprosta_funkcija() </syntaxhighlight> == Krajevne spremenljivke, rekurzija in ponovno vstopanje == Podprogram je lahko uporaben za rabo določene količine ''pomožnega'' prostora, [[navidezni pomnilnik|pomnilnika]], ki se rabi med njegovim izvrševanjem tega podprograma za držanje vmesnih rezultatov. Spremenljivke, shranjene v tem pomožnem prostoru, se imenujejo ''krajevne spremenljivke'', pomožni prostor pa se imenuje ''aktivacijski zapis''. Aktivacijski zapis ima tipični [[stavek za vrnitev|povratni naslov]], ki mu pove kam nazaj mora vrniti nadzor, ko se podprogram konča. Podprogram ima lahko poljubni število in naravo klicnih mest. Če je podprta rekurzija, lahko podprogram celo kliče samega sebe, kar povzroči, da se njegova izvršitev začasno odloži medtem ko se pojavi druga ''vgnezdena'' izvršitev istega podprograma. [[Rekurzija]] je uporabno sredstvo za poenostavitev nekaterij zapletenih algoritmov in zlom zapletenih problemov. Rekurzivni jeziki v splošnem pri vsakem klicu zagotavljajo novo kopijo krajevnih spremenljivk. Če programer želi, da vrednosti krajevnih spremenljivk med klici ostajajo enake, se v nekaterih jezikih lahko označijo kot ''statične'', lahko pa se rabijo globalne vrednosti ali skupna območja. Tu je zgled rekurzivnega podprograma v C/C++ za iskanje [[Fibonaccijevo število|Fibonaccijevih števil]]: <syntaxhighlight lang="c"> int fib(int n) { if (n <= 1) { return n; } return fib(n - 1) + fib(n - 2); } </syntaxhighlight> Zgodnji jeziki, kot je [[Fortran]], v začetku niso podpirali rekurzije, ker so bile spremenljivke dodeljene statično, kot tudi lokacija za povratni naslov. Večina računalnikov pred poznimi 1960-imi, ko je na primer [[PDP-8]], niso imeli podpore za strojne [[register sklada|skladovne registre]]. Sodobni jeziki po [[ALGOL]]u, kot sta [[PL/I]] in [[programski jezik C|C]] skoraj vedno rabijo sklad, po navadi podprt z najsodobnejšimi računalniškimi [[arhitektura nabora ukazov|nabori ukazov]] za zagotovitev svežih aktivacijskih zapisov za vsako izvršitev podprograma. Na ta način je vgnezdena izvršitev prosta za spreminjanje svojih krajevnih spremenljivk brez skrbi za vpliv na druge odložene izvršitve v poteku. Ker se vgnezdeni klici kopičijo, se tvori struktura [[klicni sklad|klicnega sklada]], ki se sestoji iz enega aktivacijskega zapisa za vsak odložen podprogram. Dejansko je ta skladovna struktura navidezno vseprisotna, aktivacijski zapisi pa se zato v splošnem imenujejo ''[[okvir sklada|okvirji skladov]]''. Nekateri jeziki, kot so [[paskal (programski jezik)|paskal]], PL/I in [[Ada (programski jezik)|Ada]], tudi podpirajo [[vgnezdena funkcija|vgnezdene podpograme]], ki so podprogrami klicljivi le znotraj [[obseg (računalništvo)|obsega]] zunanjega (starševskega) podprograma. Notranji podprogrami imajo dostop do krajevnih spremenljivk zunanjega podprograma, ki jih je klical. To se doseže s hranitvijo dodatnih pomenskih informacij znotraj aktivacijskega zapisa, kar se imenuje ''zaslon'' (''display''). če se podprogram lahko pravilno izvrši tudi kadar je že v teku druga izvršitev istega podprograma, se tak podprogram imenuje [[ponovna izvedljivost (računalništvo)|ponovno izvedljiv]] (''reentrant''). Rekurzivni podprogrami morajo biti ponovno izvedljivi. Ponovno izvedljivi podprogrami so uporabni tudi v razmerah [[nit (računalništvo)|mnogonitnosti]], ker lahko mnogokratne niti kličejo isti podprogram brez bojazni pred medsebojnim motenjem. V [[sistem obdelave transakcij|sistemu obdelave transakcij]] [[IBM]] [[CICS]] je bila ''delno ponovno izvedljivost'' rahlo manj omejevalna, vendar podobna zahteva za aplikacijske programe, ki jih je delilo več niti. V mnogonitnem okolju v splošnem obstaja več kot en sklad. Okolje, ki v celoti podpira [[soprogram]]e ali [[zakasnjeni izračun|zakasnjeno izračunavanje]], lahko za hranjenje svojih aktivacijskih zapisov namesto skladov rabi druge podatkovne strukture. == Preobremenjevanje == V [[močna in šibka tipizacija|močno tipiziranih jezikih]] je včasih zaželeno, da obstaja več funkcij z enakim imenom, vendar delujočih na različnih podatkovnih tipih ali z različnimi profili parametrov. Funkcija za [[kvadratni koren]] je lahko na primer opredeljena tako, da deluje nad realnimi števili, kompleksnimi vrednostmi ali matrikami. Algoritem je v vsakem primeru drugačen in tudi povratni rezultat je lahko različen. Z zapisom treh ločenih funkcij z enakim imenom si programerju ni treba zapomniti različnih imen za vsak podatkovni tip. Če se naprej lahko opredeli podtip za realna števila, da se ločijo pozitivna od negativnih realna števila, se za realna števila lahko napišeta dve funkciji , ena, ki vrača realno število, kadar je paramater pozitiven, in druga, ki vrača kompleksno vrednost, kadar je negativen. V [[objektno usmerjeno programiranje|objektno usmerjenem programiranju]] kadar lahko niz funkcij z enakim imenom sprejme različne profile parametrov ali parametre različnih tipov, je vsaka od njih [[preobremenjevanje funkcij|preobremenjena]]. Sledi zgled preobremenjevanja podprograma v [[C++]]: <syntaxhighlight lang="cpp"> #include <iostream> double povrsina(double h, double w) { return h * w; } double povrsina(double r) { return r * r * 3.14; } int main() { double povrsina_pravokotnika = povrsina(3, 4); double povrsina_kroga = povrsina(5); std::cout << "Površina pravokotnika je " << povrsina_pravokotnika << std::endl; std::cout << "Površina kroga je " << povrsina_kroga << std::endl; } </syntaxhighlight> V tej kodi sta dve funkciji z enakim imenom <code>povrsina()</code>, vendar imata različne parametre. C preobremnjevanja funkcij neposredno ne podpira. V drugem zgledu lahko podprogram zgradi [[objekt (računalništvo)|objekt]], ki bo sprejel smeri, in sledil svoji poti tem točkam na zaslonu. Obstaja preobilo paramatrov, ki se lahko prenesejo konstruktorju (barva sledi, začetni koordinati x in y, hitrost sledi). Če bi programer želel, da lahko konstruktor sprejme le en parameter barve, potem lahko pokliče drugi konstruktor, ki sprejme le barvo, kar izmenoma kliče konstruktor z vsemi parametri, prenesenimi v množici ''privzeti vrednosti'' za vse druge parametre (X in Y bosta v splošnem usredinjena na zaslonu ali pa postavljena v izhodišču, hitrost pa bo nastavljena na drugo vrednost glede na programerjevo izbiro). PL/I ima atribut <code>GENERIC</code> za označitev rodovnega imena za množico vnosnih sklicevanj, klicanih z različnimi tipi argumentov. Na primer: <pre> DECLARE gen_name GENERIC( name WHEN(FIXED BINARY), flame WHEN(FLOAT), pathname OTHERWISE ); </pre> Pri vsakem vnosu se lahko navedejo mnogovrstne opredelitve argumentov. Klic na »gen_name« bo klical podprogram »name«, kadar je argument tipa FIXED BINARY, »flame« kadar je tipa FLOAT in tako naprej. Če se argument ne ujema z nobeno izbiro, bo klican podprogram »pathname«. == Zaprtja == {{glavni|zaprtje (računalništvo)}} ''[[zaprtje (računalništvo)|Zaprtje]]'' (''closure'') je podprogram skupaj z vrednostmi nekaterih njegovih spremenljivk, zaobjetimi z okoljem v katerem je nastal. Zaprtja so bila pomembni gradnik programskega jezika [[lisp (programski jezik)|lisp]], ki ga je v poznih 1950-ih uvedel [[John McCarthy|John McCarthy]]. Odvisno od izvedbe lahko zaprtja služijo kot mehanizem za stranske učinke. == Dogovori == Za kodiranje podprogramov so razvili veliko število dogovorov. Glede na njihovo ime je mnogo razvijalcev prisvojilo pristop v katerem mora biti ime podprograma [[glagol]], kadar naredi določeno nalogo, [[pridevnik]], kadar naredi kakšno poizvedovanje, in [[samostalnik]], kadar se rabi kot zamenjava za spremenljivke. Nekateri programerji predlagajo, da naj podprogram izvede le eno nalogo, in, če podpogram izvaja več kot eno nalogo, naj se deli v druge podprograme. Sklepajo, da so podprogrami ključne komponente v [[vzdrževanje programske opreme|vzdrževanju kode]], njihova vloga v programu pa mora ostajati jasna. Zagovorniki [[modularno programiranje|modularnega programiranja]] (modularizacije kode) se zavzemajo, da mora biti vsak podprogram najmanj odvisen od dugih delov kode. Raba [[globalna spremenljivka|globalnih spremenljivk]] za zagovornike tega vidika v splošnem velja za nespametno, ker dodaja tesno sklopitev med podprogramom in temi globalnimi spremenljivkami. Če takšna sklopitev ni potrebna, je njihov predlog [[preoblikovanje kode|preoblikovanje]] podprogramov, da lahko namesto njih sprejemajo prenesene [[parameter (računalništvo)|parametre]]. Vendar lahko povečevanje števila parametrov, prenesenih v podprograme, vpliva na berljivost kode. == Povratne kode == Poleg njegovega ''glavnega'' ali ''normalnega'' učinka mora podprogram klicočemu programu sporočiti o ''izjemnih'' pogojih, ki so se med njegovim izvajanjem mogoče pojavili. V nekaterih jezikih in programskih standardih se to velikokrat naredi prek ''[[koda napake|povratne kode]]'', celoštevilske vrednosti, ki jo podprogram postavi na kakšno standardno lokacijo in, ki zakodira normalne ali izjemne pogoje. V družini [[IBM System/360]], kjer je bila od podprograma zahtevana povratna koda, je bila povratna vrednost pogosto oblikovana kot mnogokratnik števila 4, tako da se je lahko uporabila kot neposredni indeks [[razvejitvena tabela|razvejitvene razpredelnice]] v razvejitveno razpredelnico, ki se pogosto nahaja takoj za ukazom za klicanje zaradi izogibanja dodatnim pogojnim testom, in s tem izboljšanjem učinkovitosti. V zbirnem jeziku družine IBM System/360 se na primer lahko zapiše: BAL 14, SUBRTN01 skok na podprogram, shranitev povratnega naslova v R14 B TABLE(15) uporaba povratne vrednosti v registru 15 na indeks razvejitvene razpredelnice, * vejitev na odgovarjajoči vejitveni ukaz. TABLE B OK povratna koda =00 V REDU } B BAD povratna koda =04 nepravilni vnos } razvejitvena razpredelnica B ERROR povratna koda =08 nepredvideni pogoj } == Optimizacija podprogramskih klicev == Pri klicanju podprogramov obstaja velika režija izvajalnega časa, vključno s prenašanjem argumentov, vejitvijo do podprograma in vejitvijo nazaj na klicočega. Režija pogosto vključuje hranjenje in obnavljanje določenih procesorskih registrov, dodeljevanje in ponovno vračanje pomnilnika klicnega okvirja. V nekaterih jezikih vsak programski klic vsebuje tudi samodejno testiranje povratne kode podprograma ali [[upravljanje z izjemami]], ki se lahko pojavijo. Pomembni vir režije v objektno usmerjenih jezikih je intenzivna raba [[dinamična dodelitev|dinamičnega dodeljevanja]] za klice metod. {{glej tudi|čista funkcija}} Za podprogramske klice obstaja nekaj navidezno očitnih optimizacij, ki se ne morejo uporabiti, če imajo podprogrami stranske učinke. V izrazu <code>(f(x)-1)/(f(x)+1)</code> se mora na primer funkcija <code>f(x)</code> klicati dvakrat, ker dva klica lahko vrneta različna rezultata. Poleg tega mora biti vrednost <code>x</code> pred drugim klicem dostavljena ponovno, saj jo je lahko prvi klic spremenil. Določanje ali ima lahko podprogram stranske učinke je zelo težko – po [[Riceov izrek|Riceovem izreku]] celo [[neodločljivi problem|neodločljivo]]. Čeprav so takšne optimizacije varne v čisto funkcionalnih programskih jezikih, prevajalniki tipičnega [[imperativno programiranje|imperativnega programiranja]] morajo po navadi dopuščati najslabše. === Vrivanje === Metoda za izločitev te režije je ''[[vrinjena razširitev]]'' (''inline expansion'') ali ''vrivanje'' (''inlining'') telesa podprograma k vsakemu [[klicno mesto|klicnemu mestu]], namesto vejitve k podprogramu in nazaj. Tako ne samo, da se izogne klicni režiji, ampak omogoča prevajalniku učinkovitejšo [[optimizacija programa|optimizacijo]] ''telesa'' podprograma z upoštevanjem konteksta in argumentov klica. Vstavljeno telo lahko prevajalnik optimira. Vrivanje pa bo po navadi povečalo velikost kode, razen če program ne vsebuje le en podprogramski klic. == Trop v priljubljenih medijih == Izraz »podprogram« se je od 1990-ih na televiziji in v filmih [[trop (jezikoslovje)|rabil]] neštetokrat. Včasih lahko poljubni element zgodbe, ki vsebuje [[računalniško programiranje]] ali [[varnostni heker|vdiranje]], postavljen v sedanjost in včasih v daljno prihodnost, obudi ta koncept – velikokrat pa ni pravilno rabljen. == Glej tudi == * [[funkcija (matematika)]] * [[metoda (računalništvo)]] * [[vgrajena funkcija]] * [[strategija vrednotenja]] * [[modularno programiranje]] * [[transkluzija]] * [[preobremenjevanje operatorjev]] * [[zaščitena procedura]] * [[funkcionalno programiranje]] * [[ukazno-poizvedovalno ločevanje]] (CQS) * [[soprogram]] (korutina) * [[dogodek (računalništvo)]] * [[nesočasni klic podprograma]] == Sklici == {{sklici|4|refs= <ref name="carp_1977">{{sktxt|Carpenter|Doran|1977}}.</ref> <ref name="dahl_1972">{{sktxt|Dahl|Dijkstra|Hoare|1972}}.</ref> <ref name="dain_2004">{{sktxt|Dainith|2004}}.</ref> <ref name="dasg_2014">{{sktxt|Dasgupta|2014|pp=155–}}.</ref> <ref name="dis__2022">{{navedi splet|title= subroutine|work= Računalniški slovarček – Odsek za inteligentne sisteme, [[Institut "Jožef Stefan"]]|date= 2022|url= https://dis-slovarcek.ijs.si/detail/10211/|accessdate= 18. februarja 2022}}</ref> <ref name="fran_1983">{{sktxt|Frank|1983|pp=195}}.</ref> <ref name="fran_2021">{{navedi splet|title= podprogram|work= [[Fran (jezikovni portal)|Fran]], [[Inštitut za slovenski jezik Frana Ramovša]], [[Znanstvenoraziskovalni center Slovenske akademije znanosti in umetnosti|ZRC SAZU]]|date= 2021|url= https://fran.si/iskanje?View=1&Query=podprogram|accessdate= 18. februarja 2022}}</ref> <ref name="gold_1947">{{sktxt|Goldstine|von Neumann|1947|pp=163}}.</ref> <ref name="infocenter">{{navedi splet|url= http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka13785.html|title= ARM Information Center|publisher= Infocenter.arm.com|access-date= 29. septembra 2013|language= en}}</ref> <ref name="isaa_2014">{{sktxt|Isaacson|2014}}.</ref> <ref name="islovar">{{navedi splet|title= podprogram|work= Islovar, [[Slovensko društvo Informatika]]|date= 2020|url= http://www.islovar.org/islovar|accessdate= 25. februarja 2022}}.</ref> <ref name="knut_1997">{{sktxt|Knuth|1997}}.</ref> <ref name="mart_2009">{{sktxt|Martin|2009|pp=[https://books.google.si/books?id=_i6bDeoCQzsC&pg=PA39&dq=descriptive+function+name 39]}}.</ref> <ref name="mauc_1947">{{sktxt|Mauchly|1947}}.</ref> <ref name="microsoft0">{{navedi splet|title= x64 stack usage|url= https://docs.microsoft.com/en-us/cpp/build/stack-usage|website= Microsoft Docs|publisher= Microsoft|date= 3. avgust 2021|access-date= 5. avgusta 2019|language= en}}</ref> <ref name="microsoft1">{{navedi splet|url= http://msdn.microsoft.com/en-us/library/67fa79wz%28v=VS.90%29.aspx|title= Function Types|publisher= Msdn.microsoft.com|date= 16. november 2012|access-date= 29. septembra 2013|language= en}}</ref> <ref name="microsoft2">{{navedi splet|url= http://www.smallbasic.com/|title= Microsoft Small Basic|website= www.smallbasic.com|accessdate= 23. februarja 2022|language= en}}</ref> <ref name="python">{{navedi splet|url= https://docs.python.org/3.9/tutorial/controlflow.html#defining-functions|title= 4. More Control Flow Tools — Python 3.9.7 documentation|accessdate= 23. februarja 2023|language= en}}</ref> <ref name="stackover">{{navedi splet|title= what is meant by a free function|url= https://stackoverflow.com/questions/4861914/what-is-the-meaning-of-the-term-free-function-in-c|publisher= [[Stack Overflow|stackoverflow]]|date= 1. februar 2011|accessdate= 23. februarja 2022|language= en}}</ref> <ref name="stee_1977">{{sktxt|Steele|1977}}.</ref> <ref name="stro_2013">{{sktxt|Stroustrup|2013|pp=307}}.</ref> <ref name="turi_1945">{{sktxt|Turing|1945}}.</ref> <ref name="turi_1946">{{sktxt|Turing|1946}}.</ref> <ref name="whee_1952">{{sktxt|Wheeler|1952|pp=235}}.</ref> <ref name="wikisl0">{{navedi splet|title=podprogram|work= [[Wikislovar]]|url= https://en.wiktionary.org/wiki/podprogram|accessdate= 23. februarja 2022|language= en}}</ref> <ref name="wikisl1">{{navedi splet|title=subroutine|work= Wikislovar|url= https://en.wiktionary.org/wiki/subroutine|accessdate= 23. februarja 2022|language= en}}</ref> <ref name="wilk_1951">{{sktxt|Wilkes|Wheeler|Gill|1951|pp= 45, 80–91, 100}}.</ref> <ref name="wils_2001">{{sktxt|Wilson|Clark|2001|pp=140}}.</ref> <ref name="usea_2007">{{navedi splet|author= U.S. Election Assistance Commission|title= Definitions of Words with Special Meanings|work= [[Voluntary Voting System Guidelines]]|date= 2007|url= http://www.eac.gov/vvsg/glossary.aspx|access-date= 14. januarja 2013|author-link= Election Assistance Commission|url-status= dead|archive-url= https://web.archive.org/web/20121208084203/http://www.eac.gov/vvsg/glossary.aspx|archive-date= 8. decembra 2012}}</ref> }} == Viri == {{refbegin|4}} * {{navedi revijo|last1= Carpenter|first1= Brian Edward|authorlink1= Brian Edward Carpenter|last2= Doran|first2= Robert William|authorlink2= Robert William Doran|title= The other Turing machine|journal= [[The Computer Journal]]|date= 1. januar 1977|orig-year= oktober 1975|volume= 20|issue= 3|pages= 269–279|doi= 10.1093/comjnl/20.3.269|doi-access= free}} (11 strani) * {{navedi knjigo|last1= Dahl|first1= Ole-Johan|authorlink1= Ole-Johan Dahl|last2= Dijkstra|first2= Edsger Wybe|authorlink2= Edsger Wybe Dijkstra|last3= Hoare|first3= Charles Antony Richard|authorlink3= Tony Hoare|title= Structured Programming|date= 1972|publisher= Academic Press|isbn= 0-12-200550-3}} * {{navedi enciklopedijo|last1= Dainith|first1= John |title= "open subroutine." A Dictionary of Computing|date= 2004|url= http://www.encyclopedia.com/doc/1O11-opensubroutine.html|encyclopedia= Encyclopedia.com|access-date= 14. januarja 2013}} * {{navedi knjigo|last1= Dasgupta|first1= Subrata|title= It Began with Babbage: The Genesis of Computer Science|date= 7. januar 2014|url= https://books.google.com/books?id=tXBVAgAAQBAJ&pg=PT155|publisher= Oxford University Press|isbn= 978-0-19-930943-6|pages= 155–}} * {{navedi knjigo|last1= Frank|first1= Thomas S.|title= Introduction to the PDP-11 and Its Assembly Language|date= 1983|url= https://books.google.com/books?id=YN4mAAAAMAAJ|series= Prentice-Hall software series|publisher= Prentice-Hall|page= 195|isbn= 9780134917047|access-date = 6. julija 2016|quote= Našemu zbirniškemu uradniku smo lahko dobavili kopije izvorne kode za vse naše uporabne podprograme in mu nato po predstavitvi glavnega programa za zbirnik povedali katere podprograme bo glavni program klical [...]}} * {{navedi poročilo|last1= Goldstine|first1= Herman Heine|last2= von Neumann|first2= John|authorlink2= John von Neumann|date= 1947|title= Planning and coding of problems for an electronic computing instrument|url= |publisher= [[Inštitut za višji študij]]|page= 163|oclc= 26239859}} * {{navedi splet|last1= Isaacson|first1= Walter|title= Walter Isaacson on the Women of ENIAC|date= 18. september 2014|website= Fortune|language= en|url= http://fortune.com/2014/09/18/walter-isaacson-the-women-of-eniac/|archive-url= https://web.archive.org/web/20181212003245/http://fortune.com/2014/09/18/walter-isaacson-the-women-of-eniac/|archive-date= 12. decembra 2018|access-date= 14. decembra 2018}} * {{navedi knjigo|last1= Knuth|first1= Donald Ervin|authorlink1= Donald Knuth|title= The Art of Computer Programming, Volume I: Fundamental Algorithms|date= 1997|publisher= Addison-Wesley|isbn= 0-201-89683-4}} * {{navedi knjigo|last1= Martin|first1= Robert Cecil|authorlink1= Robert Cecil Martin|title= Clean Code: A Handbook of Agile Software Craftsmanship|date= 2009|publisher= Pearson Education|isbn= 0-13-235088-2|cobiss= 1215739|url= https://books.google.si/books?id=_i6bDeoCQzsC}} * {{citat|last1= Mauchly|first1= John William|authorlink1= John William Mauchly|chapter= Preparation of Problems for EDVAC-type Machines|date= 1947|editor-last1=Randell|editor-first1= Brian|title= The Origins of Digital Computers|publisher= Springer|publication-date= 1982}} * {{citat|last1= Steele|first1= Guy Lewis|authorlink1= Guy Lewis Steele starejši|title= Debunking the "Expensive Procedure Call" Myth; or, Procedure call implementations considered harmful"|journal= [[AI Memo]]|date= oktober 1977|volume= |issue= 443|pages= §»C. Why Procedure Calls Have a Bad Reputation«|publisher= Laboratorij za umetno inteligenco, [[Tehnološki inštitut Massachusettsa|MIT]]|url= http://dspace.mit.edu/bitstream/handle/1721.1/5753/AIM-443.pdf?sequence=2}} * {{navedi knjigo|last1= Stroustrup|first1= Bjarne|authorlink1= Bjarne Stroustrup|title= The C++ Programming Language, Fourth Edition|date= 2013|publisher= Addison-Wesley|page= 307|isbn= 978-0-321-56384-2}} * {{citat|last1= Turing|first1= Alan Mathinson|authorlink1= Alan Turing|title= Report by Dr. A.M. Turing on proposals for the development of an Automatic Computing Engine (ACE): Submitted to the Executive Committee of the NPL in February 1946|date= 1945}}, ponatisnjeno v {{navedi knjigo|editor-last1= Copeland|editor-first1= Brian Jack|editor-link1= Jack Copeland|title= Alan Turing's Automatic Computing Engine|location= Oxford|publisher= Oxford University Press|publication-date= 2005|isbn= 0-19-856593-3|date= 2005|url-access= registracija|url= https://archive.org/details/alanturingsautom0000unse|page= 383}} * {{citat|last1= Turing|first1= Alan Mathinson|authorlink1= |title= Proposals for Development in the Mathematics Division of an Automatic Computing Engine (ACE)|date= 19. marec 1946|orig-year= 1945}} (NB. Predstavljeno 19. marca 1946 pred izvršnim odborom britanskega Narodnega fizikalnega laboratorija.) * {{navedi konferenco|last1= Wheeler|first1= David John|authorlink1= David John Wheeler|chapter= The use of sub-routines in programmes|doi= 10.1145/609784.609816|title= Proceedings of the 1952 ACM national meeting (Pittsburgh) on - ACM '52|date= 1952|pages= 235|chapter-url= http://www.laputan.org/pub/papers/wheeler.pdf}} * {{navedi knjigo|last1= Wilkes|first1= Maurice Vincent|authorlink1= Maurice Vincent Wilkes|last2= Wheeler|first2= David John|authorlink2= |last3= Gill|first3= Stanley|authorlink3= Stanley Gill|title= The Preparation of Programs for an Electronic Digital Computer|date= 1951|oclc= 641145988|url= https://archive.org/details/programsforelect00wilk/page/80/mode/2up?q=library|location= |publisher= Addison-Wesley|page= 45, 80–91, 100|isbn= }} * {{navedi knjigo|last1= Wilson|first1= Leslie Blackett|authorlink1= Leslie Blackett Wilson|last2= Clark|first2= Robert George|title= Comparative Programming Languages|url= https://archive.org/details/comparativeprogr0000wils_i0w2|date= 2001|edition= 3|publisher= Addison-Wesley|page= [https://archive.org/details/comparativeprogr0000wils_i0w2/page/140 140]|isbn= 0-201-71012-9}} {{refend}} {{normativna kontrola}} [[Kategorija:Izvorna koda]] [[Kategorija:Holizem]] [[Kategorija:Programski konstrukti]] [[Kategorija:Podprogrami| ]] </textarea><div class="templatesUsed"><div class="mw-templatesUsedExplanation"><p>Predloge, uporabljene na tej strani: </p></div><ul> <li><a href="/wiki/Predloga:Anchor" class="mw-redirect" title="Predloga:Anchor">Predloga:Anchor</a> (<a href="/w/index.php?title=Predloga:Anchor&action=edit" class="mw-redirect" title="Predloga:Anchor">uredi</a>) </li><li><a href="/wiki/Predloga:Citat" title="Predloga:Citat">Predloga:Citat</a> (<a href="/w/index.php?title=Predloga:Citat&action=edit" title="Predloga:Citat">uredi</a>) </li><li><a href="/wiki/Predloga:First_word" class="mw-redirect" title="Predloga:First word">Predloga:First word</a> (<a href="/w/index.php?title=Predloga:First_word&action=edit" class="mw-redirect" title="Predloga:First word">uredi</a>) </li><li><a href="/wiki/Predloga:Glavni" title="Predloga:Glavni">Predloga:Glavni</a> (<a href="/w/index.php?title=Predloga:Glavni&action=edit" title="Predloga:Glavni">uredi</a>) </li><li><a href="/wiki/Predloga:Glej_tudi" title="Predloga:Glej tudi">Predloga:Glej tudi</a> (<a href="/w/index.php?title=Predloga:Glej_tudi&action=edit" title="Predloga:Glej tudi">uredi</a>) </li><li><a href="/wiki/Predloga:Kratki_opis" title="Predloga:Kratki opis">Predloga:Kratki opis</a> (<a href="/w/index.php?title=Predloga:Kratki_opis&action=edit" title="Predloga:Kratki opis">uredi</a>) </li><li><a href="/wiki/Predloga:Main_other" title="Predloga:Main other">Predloga:Main other</a> (<a href="/w/index.php?title=Predloga:Main_other&action=edit" title="Predloga:Main other">izvorno besedilo</a>) (zaščitena)</li><li><a href="/wiki/Predloga:Navedi_enciklopedijo" title="Predloga:Navedi enciklopedijo">Predloga:Navedi enciklopedijo</a> (<a href="/w/index.php?title=Predloga:Navedi_enciklopedijo&action=edit" title="Predloga:Navedi enciklopedijo">uredi</a>) </li><li><a href="/wiki/Predloga:Navedi_knjigo" title="Predloga:Navedi knjigo">Predloga:Navedi knjigo</a> (<a href="/w/index.php?title=Predloga:Navedi_knjigo&action=edit" title="Predloga:Navedi knjigo">izvorno besedilo</a>) (zaščitena)</li><li><a href="/wiki/Predloga:Navedi_konferenco" title="Predloga:Navedi konferenco">Predloga:Navedi konferenco</a> (<a href="/w/index.php?title=Predloga:Navedi_konferenco&action=edit" title="Predloga:Navedi konferenco">uredi</a>) </li><li><a href="/wiki/Predloga:Navedi_poro%C4%8Dilo" title="Predloga:Navedi poročilo">Predloga:Navedi poročilo</a> (<a href="/w/index.php?title=Predloga:Navedi_poro%C4%8Dilo&action=edit" title="Predloga:Navedi poročilo">uredi</a>) </li><li><a href="/wiki/Predloga:Navedi_revijo" title="Predloga:Navedi revijo">Predloga:Navedi revijo</a> (<a href="/w/index.php?title=Predloga:Navedi_revijo&action=edit" title="Predloga:Navedi revijo">uredi</a>) </li><li><a href="/wiki/Predloga:Navedi_splet" title="Predloga:Navedi splet">Predloga:Navedi splet</a> (<a href="/w/index.php?title=Predloga:Navedi_splet&action=edit" title="Predloga:Navedi splet">izvorno besedilo</a>) (zaščitena)</li><li><a href="/wiki/Predloga:Normativna_kontrola" title="Predloga:Normativna kontrola">Predloga:Normativna kontrola</a> (<a href="/w/index.php?title=Predloga:Normativna_kontrola&action=edit" title="Predloga:Normativna kontrola">izvorno besedilo</a>) (zaščitena)</li><li><a href="/wiki/Predloga:Pagetype" title="Predloga:Pagetype">Predloga:Pagetype</a> (<a href="/w/index.php?title=Predloga:Pagetype&action=edit" title="Predloga:Pagetype">uredi</a>) </li><li><a href="/wiki/Predloga:Paragraph_break" title="Predloga:Paragraph break">Predloga:Paragraph break</a> (<a href="/w/index.php?title=Predloga:Paragraph_break&action=edit" title="Predloga:Paragraph break">izvorno besedilo</a>) (zaščitena)</li><li><a href="/wiki/Predloga:Prva_beseda" title="Predloga:Prva beseda">Predloga:Prva beseda</a> (<a href="/w/index.php?title=Predloga:Prva_beseda&action=edit" title="Predloga:Prva beseda">uredi</a>) </li><li><a href="/wiki/Predloga:Refbegin" title="Predloga:Refbegin">Predloga:Refbegin</a> (<a href="/w/index.php?title=Predloga:Refbegin&action=edit" title="Predloga:Refbegin">uredi</a>) </li><li><a href="/wiki/Predloga:Refbegin/styles.css" title="Predloga:Refbegin/styles.css">Predloga:Refbegin/styles.css</a> (<a href="/w/index.php?title=Predloga:Refbegin/styles.css&action=edit" title="Predloga:Refbegin/styles.css">uredi</a>) </li><li><a href="/wiki/Predloga:Refend" title="Predloga:Refend">Predloga:Refend</a> (<a href="/w/index.php?title=Predloga:Refend&action=edit" title="Predloga:Refend">uredi</a>) </li><li><a href="/wiki/Predloga:SDcat" title="Predloga:SDcat">Predloga:SDcat</a> (<a href="/w/index.php?title=Predloga:SDcat&action=edit" title="Predloga:SDcat">uredi</a>) </li><li><a href="/w/index.php?title=Predloga:SHORTDESC:del_ra%C4%8Dunalni%C5%A1kega_programa&action=edit&redlink=1" class="new" title="Predloga:SHORTDESC:del računalniškega programa (stran ne obstaja)">Predloga:SHORTDESC:del računalniškega programa</a> (<a href="/w/index.php?title=Predloga:SHORTDESC:del_ra%C4%8Dunalni%C5%A1kega_programa&action=edit" class="new" title="Predloga:SHORTDESC:del računalniškega programa (stran ne obstaja)">uredi</a>) </li><li><a href="/wiki/Predloga:Short_description" class="mw-redirect" title="Predloga:Short description">Predloga:Short description</a> (<a href="/w/index.php?title=Predloga:Short_description&action=edit" class="mw-redirect" title="Predloga:Short description">uredi</a>) </li><li><a href="/wiki/Predloga:Short_description/lowercasecheck" title="Predloga:Short description/lowercasecheck">Predloga:Short description/lowercasecheck</a> (<a href="/w/index.php?title=Predloga:Short_description/lowercasecheck&action=edit" title="Predloga:Short description/lowercasecheck">uredi</a>) </li><li><a href="/wiki/Predloga:Sidro" title="Predloga:Sidro">Predloga:Sidro</a> (<a href="/w/index.php?title=Predloga:Sidro&action=edit" title="Predloga:Sidro">uredi</a>) </li><li><a href="/wiki/Predloga:Sklici" title="Predloga:Sklici">Predloga:Sklici</a> (<a href="/w/index.php?title=Predloga:Sklici&action=edit" title="Predloga:Sklici">izvorno besedilo</a>) (zaščitena)</li><li><a href="/wiki/Predloga:Sktxt" title="Predloga:Sktxt">Predloga:Sktxt</a> (<a href="/w/index.php?title=Predloga:Sktxt&action=edit" title="Predloga:Sktxt">uredi</a>) </li><li><a href="/wiki/Predloga:Testcases_other" title="Predloga:Testcases other">Predloga:Testcases other</a> (<a href="/w/index.php?title=Predloga:Testcases_other&action=edit" title="Predloga:Testcases other">uredi</a>) </li><li><a href="/wiki/Predloga:Trim" title="Predloga:Trim">Predloga:Trim</a> (<a href="/w/index.php?title=Predloga:Trim&action=edit" title="Predloga:Trim">uredi</a>) </li><li><a href="/wiki/Modul:Anchor" title="Modul:Anchor">Modul:Anchor</a> (<a href="/w/index.php?title=Modul:Anchor&action=edit" title="Modul:Anchor">uredi</a>) </li><li><a href="/wiki/Modul:Arguments" title="Modul:Arguments">Modul:Arguments</a> (<a href="/w/index.php?title=Modul:Arguments&action=edit" title="Modul:Arguments">uredi</a>) </li><li><a href="/wiki/Modul:Authority_control" title="Modul:Authority control">Modul:Authority control</a> (<a href="/w/index.php?title=Modul:Authority_control&action=edit" title="Modul:Authority control">izvorno besedilo</a>) (zaščitena)</li><li><a href="/wiki/Modul:Check_for_unknown_parameters" title="Modul:Check for unknown parameters">Modul:Check for unknown parameters</a> (<a href="/w/index.php?title=Modul:Check_for_unknown_parameters&action=edit" title="Modul:Check for unknown parameters">izvorno besedilo</a>) (zaščitena)</li><li><a href="/wiki/Modul:Citation/CS1" title="Modul:Citation/CS1">Modul:Citation/CS1</a> (<a href="/w/index.php?title=Modul:Citation/CS1&action=edit" title="Modul:Citation/CS1">izvorno besedilo</a>) (delno zaščitena)</li><li><a href="/wiki/Modul:Citation/CS1/COinS" title="Modul:Citation/CS1/COinS">Modul:Citation/CS1/COinS</a> (<a href="/w/index.php?title=Modul:Citation/CS1/COinS&action=edit" title="Modul:Citation/CS1/COinS">uredi</a>) </li><li><a href="/wiki/Modul:Citation/CS1/Configuration" title="Modul:Citation/CS1/Configuration">Modul:Citation/CS1/Configuration</a> (<a href="/w/index.php?title=Modul:Citation/CS1/Configuration&action=edit" title="Modul:Citation/CS1/Configuration">uredi</a>) </li><li><a href="/wiki/Modul:Citation/CS1/Date_validation" title="Modul:Citation/CS1/Date validation">Modul:Citation/CS1/Date validation</a> (<a href="/w/index.php?title=Modul:Citation/CS1/Date_validation&action=edit" title="Modul:Citation/CS1/Date validation">uredi</a>) </li><li><a href="/wiki/Modul:Citation/CS1/Identifiers" title="Modul:Citation/CS1/Identifiers">Modul:Citation/CS1/Identifiers</a> (<a href="/w/index.php?title=Modul:Citation/CS1/Identifiers&action=edit" title="Modul:Citation/CS1/Identifiers">uredi</a>) </li><li><a href="/wiki/Modul:Citation/CS1/Utilities" title="Modul:Citation/CS1/Utilities">Modul:Citation/CS1/Utilities</a> (<a href="/w/index.php?title=Modul:Citation/CS1/Utilities&action=edit" title="Modul:Citation/CS1/Utilities">uredi</a>) </li><li><a href="/wiki/Modul:Citation/CS1/Whitelist" title="Modul:Citation/CS1/Whitelist">Modul:Citation/CS1/Whitelist</a> (<a href="/w/index.php?title=Modul:Citation/CS1/Whitelist&action=edit" title="Modul:Citation/CS1/Whitelist">uredi</a>) </li><li><a href="/wiki/Modul:Citation/CS1/styles.css" title="Modul:Citation/CS1/styles.css">Modul:Citation/CS1/styles.css</a> (<a href="/w/index.php?title=Modul:Citation/CS1/styles.css&action=edit" title="Modul:Citation/CS1/styles.css">uredi</a>) </li><li><a href="/wiki/Modul:EditAtWikidata" title="Modul:EditAtWikidata">Modul:EditAtWikidata</a> (<a href="/w/index.php?title=Modul:EditAtWikidata&action=edit" title="Modul:EditAtWikidata">uredi</a>) </li><li><a href="/wiki/Modul:Format_link" title="Modul:Format link">Modul:Format link</a> (<a href="/w/index.php?title=Modul:Format_link&action=edit" title="Modul:Format link">uredi</a>) </li><li><a href="/wiki/Modul:Hatnote" title="Modul:Hatnote">Modul:Hatnote</a> (<a href="/w/index.php?title=Modul:Hatnote&action=edit" title="Modul:Hatnote">uredi</a>) </li><li><a href="/wiki/Modul:Hatnote/styles.css" title="Modul:Hatnote/styles.css">Modul:Hatnote/styles.css</a> (<a href="/w/index.php?title=Modul:Hatnote/styles.css&action=edit" title="Modul:Hatnote/styles.css">uredi</a>) </li><li><a href="/wiki/Modul:Hatnote_list" title="Modul:Hatnote list">Modul:Hatnote list</a> (<a href="/w/index.php?title=Modul:Hatnote_list&action=edit" title="Modul:Hatnote list">uredi</a>) </li><li><a href="/wiki/Modul:Labelled_list_hatnote" title="Modul:Labelled list hatnote">Modul:Labelled list hatnote</a> (<a href="/w/index.php?title=Modul:Labelled_list_hatnote&action=edit" title="Modul:Labelled list hatnote">uredi</a>) </li><li><a href="/wiki/Modul:Namespace_detect" title="Modul:Namespace detect">Modul:Namespace detect</a> (<a href="/w/index.php?title=Modul:Namespace_detect&action=edit" title="Modul:Namespace detect">uredi</a>) </li><li><a href="/wiki/Modul:Namespace_detect/config" title="Modul:Namespace detect/config">Modul:Namespace detect/config</a> (<a href="/w/index.php?title=Modul:Namespace_detect/config&action=edit" title="Modul:Namespace detect/config">uredi</a>) </li><li><a href="/wiki/Modul:Namespace_detect/data" title="Modul:Namespace detect/data">Modul:Namespace detect/data</a> (<a href="/w/index.php?title=Modul:Namespace_detect/data&action=edit" title="Modul:Namespace detect/data">uredi</a>) </li><li><a href="/wiki/Modul:Navbar" title="Modul:Navbar">Modul:Navbar</a> (<a href="/w/index.php?title=Modul:Navbar&action=edit" title="Modul:Navbar">izvorno besedilo</a>) (zaščitena)</li><li><a href="/wiki/Modul:Navbar/configuration" title="Modul:Navbar/configuration">Modul:Navbar/configuration</a> (<a href="/w/index.php?title=Modul:Navbar/configuration&action=edit" title="Modul:Navbar/configuration">uredi</a>) </li><li><a href="/wiki/Modul:Navbox" title="Modul:Navbox">Modul:Navbox</a> (<a href="/w/index.php?title=Modul:Navbox&action=edit" title="Modul:Navbox">uredi</a>) </li><li><a href="/wiki/Modul:Niz" title="Modul:Niz">Modul:Niz</a> (<a href="/w/index.php?title=Modul:Niz&action=edit" title="Modul:Niz">uredi</a>) </li><li><a href="/wiki/Modul:No_globals" title="Modul:No globals">Modul:No globals</a> (<a href="/w/index.php?title=Modul:No_globals&action=edit" title="Modul:No globals">izvorno besedilo</a>) (zaščitena)</li><li><a href="/wiki/Modul:Pagetype" title="Modul:Pagetype">Modul:Pagetype</a> (<a href="/w/index.php?title=Modul:Pagetype&action=edit" title="Modul:Pagetype">izvorno besedilo</a>) (zaščitena)</li><li><a href="/wiki/Modul:Pagetype/config" title="Modul:Pagetype/config">Modul:Pagetype/config</a> (<a href="/w/index.php?title=Modul:Pagetype/config&action=edit" title="Modul:Pagetype/config">izvorno besedilo</a>) (zaščitena)</li><li><a href="/wiki/Modul:ResolveEntityId" title="Modul:ResolveEntityId">Modul:ResolveEntityId</a> (<a href="/w/index.php?title=Modul:ResolveEntityId&action=edit" title="Modul:ResolveEntityId">uredi</a>) </li><li><a href="/wiki/Modul:SDcat" title="Modul:SDcat">Modul:SDcat</a> (<a href="/w/index.php?title=Modul:SDcat&action=edit" title="Modul:SDcat">uredi</a>) </li><li><a href="/wiki/Modul:TableTools" title="Modul:TableTools">Modul:TableTools</a> (<a href="/w/index.php?title=Modul:TableTools&action=edit" title="Modul:TableTools">uredi</a>) </li><li><a href="/wiki/Modul:Yesno" title="Modul:Yesno">Modul:Yesno</a> (<a href="/w/index.php?title=Modul:Yesno&action=edit" title="Modul:Yesno">uredi</a>) </li></ul></div><p id="mw-returnto">Vrnitev na <a href="/wiki/Podprogram" title="Podprogram">Podprogram</a>.</p> <!--esi <esi:include src="/esitest-fa8a495983347898/content" /> --><noscript><img src="https://login.wikimedia.org/wiki/Special:CentralAutoLogin/start?type=1x1&useformat=desktop" alt="" width="1" height="1" style="border: none; position: absolute;"></noscript> <div class="printfooter" data-nosnippet="">Pridobljeno iz »<a dir="ltr" href="https://sl.wikipedia.org/wiki/Podprogram">https://sl.wikipedia.org/wiki/Podprogram</a>«</div></div> <div id="catlinks" class="catlinks catlinks-allhidden" data-mw="interface"></div> </div> </main> </div> <div class="mw-footer-container"> <footer id="footer" class="mw-footer" > <ul id="footer-info"> </ul> <ul id="footer-places"> <li id="footer-places-privacy"><a href="https://foundation.wikimedia.org/wiki/Special:MyLanguage/Policy:Privacy_policy">Pravilnik o zasebnosti</a></li> <li id="footer-places-about"><a href="/wiki/Wikipedija:O_Wikipediji">O Wikipediji</a></li> <li id="footer-places-disclaimers"><a href="/wiki/Wikipedija:Splo%C5%A1na_zavrnitev_odgovornosti">Zavrnitve odgovornosti</a></li> <li id="footer-places-wm-codeofconduct"><a href="https://foundation.wikimedia.org/wiki/Special:MyLanguage/Policy:Universal_Code_of_Conduct">Kodeks ravnanja</a></li> <li id="footer-places-developers"><a href="https://developer.wikimedia.org">Razvijalci</a></li> <li id="footer-places-statslink"><a href="https://stats.wikimedia.org/#/sl.wikipedia.org">Statistika</a></li> <li id="footer-places-cookiestatement"><a href="https://foundation.wikimedia.org/wiki/Special:MyLanguage/Policy:Cookie_statement">O piškotkih</a></li> <li id="footer-places-mobileview"><a href="//sl.m.wikipedia.org/w/index.php?title=Podprogram&action=edit&mobileaction=toggle_view_mobile" class="noprint stopMobileRedirectToggle">Mobilni prikaz</a></li> </ul> <ul id="footer-icons" class="noprint"> <li id="footer-copyrightico"><a href="https://wikimediafoundation.org/" class="cdx-button cdx-button--fake-button cdx-button--size-large cdx-button--fake-button--enabled"><img src="/static/images/footer/wikimedia-button.svg" width="84" height="29" alt="Wikimedia Foundation" loading="lazy"></a></li> <li id="footer-poweredbyico"><a href="https://www.mediawiki.org/" class="cdx-button cdx-button--fake-button cdx-button--size-large cdx-button--fake-button--enabled"><img src="/w/resources/assets/poweredby_mediawiki.svg" alt="Powered by MediaWiki" width="88" height="31" loading="lazy"></a></li> </ul> </footer> </div> </div> </div> <div class="vector-settings" id="p-dock-bottom"> <ul></ul> </div><script>(RLQ=window.RLQ||[]).push(function(){mw.config.set({"wgHostname":"mw-web.codfw.main-5857dfdcd6-27db2","wgBackendResponseTime":319,"wgPageParseReport":{"limitreport":{"cputime":"0.005","walltime":"0.007","ppvisitednodes":{"value":17,"limit":1000000},"postexpandincludesize":{"value":773,"limit":2097152},"templateargumentsize":{"value":0,"limit":2097152},"expansiondepth":{"value":2,"limit":100},"expensivefunctioncount":{"value":0,"limit":500},"unstrip-depth":{"value":0,"limit":20},"unstrip-size":{"value":0,"limit":5000000},"entityaccesscount":{"value":0,"limit":400},"timingprofile":["100.00% 0.000 1 -total"]},"cachereport":{"origin":"mw-web.codfw.main-5857dfdcd6-27db2","timestamp":"20241203051551","ttl":2592000,"transientcontent":false}}});});</script> </body> </html>