Subroutine ( eng. subroutine ) - o parte numită sau altfel identificată a unui program de calculator care conține o descriere a unui set specific de acțiuni. O subrutină poate fi apelată de mai multe ori din diferite părți ale programului. În limbajele de programare, există mijloace sintactice speciale pentru proiectarea și utilizarea subrutinelor.
Subrutinele au apărut inițial ca un mijloc de optimizare a programelor în ceea ce privește cantitatea de memorie ocupată - au făcut posibilă să nu se repete blocuri identice de cod în program, ci să le descrie o dată și să le apeleze după cum este necesar. Până în prezent, această funcție a subrutinelor a devenit auxiliară, scopul lor principal este de a structura programul pentru a-l face mai ușor de înțeles și de întreținut.
Beneficiile împărțirii unui program în subrutine includ:
În cel mai simplu caz (în asamblatori ), o subrutină este o secvență de comenzi (operatori) separată de partea principală a programului și având o comandă specială pentru a ieși din subrutină la sfârșit. De obicei, o subrutină are și un nume prin care poate fi apelată, deși o serie de limbaje de programare permit și subrutine fără nume. În limbajele de nivel înalt, o descriere a subrutinei constă de obicei din cel puțin două părți: un „antet” și un „corp”. Antetul subrutinei descrie numele și eventual parametrii acestuia, adică conține informațiile necesare apelării subrutinei. Corpul este un set de instrucțiuni care vor fi executate ori de câte ori este apelată subrutina.
Un apel către o subrutină se face folosind o instrucțiune de apel care include numele subrutinei. În majoritatea limbajelor de programare moderne, comanda de invocare este pur și simplu numele subrutinei care este invocată, urmată opțional de parametrii actuali (vezi mai jos ).
În următorul exemplu Pascal, subprog este apelat de trei ori din programul principal:
program SubProgExample ; // Descrierea subprogramului subprog procedura subprog ; // Antetul care include numele subrutinei începe // începutul corpului subrutinei WriteLn ( 'Bye' ) ; sfârşitul ; // sfârşitul corpului subrutinei începe WriteLn ( 'Bună ziua' ) ; subprog ; // Primul apel la subprog ; // al 2-lea subprog apel ; // Încheierea celui de-al treilea apel .Rezultatul executării unui astfel de program va fi ieșirea șirului „Bună ziua” și a celor trei șiruri „Bye”.
Pentru a salva și a restabili contextul de execuție al procedurii de apelare, pentru a elimina efectele secundare asociate cu eventualele modificări nedorite ale registrelor mașinii utilizate, compilatorul generează secvențe speciale de comenzi pentru fiecare procedură, numite prolog și epilog al procedurii.
Unele limbaje de programare (de exemplu, Pascal, Ada, Modula-2) permit subrutine imbricate, adică plasarea subrutinelor în alte subrutine. Astfel de subrutine imbricate pot fi utilizate numai în subrutinele în care sunt declarate. În alte cazuri (de exemplu, în limbajul C), imbricarea subrutinelor nu este permisă. Imbricarea subrutinelor nu oferă avantaje fundamentale, dar poate fi convenabilă pentru o structurare mai logică a programului (dacă o subrutină este folosită doar într-o altă subrutină, este logic să o plasăm pe prima în a doua).
Subrutinele sunt adesea folosite pentru a efectua în mod repetat acțiuni stereotipe pe diferite date. Subrutina are de obicei acces la obiectele de date descrise în programul principal (cel puțin unele dintre ele), astfel încât pentru a transfera datele procesate în subrutină este suficient să le atribuiți, de exemplu, variabilelor globale. Dar acest mod nu este deosebit de convenabil și plin de erori.
Pentru a asigura transferul controlat al parametrilor în subrutină și returnarea rezultatelor din acesta, se utilizează mecanismul parametrilor . Parametrii sunt descriși în descrierea subrutinei (în antetul acesteia) și pot fi utilizați în cadrul procedurii în același mod ca și variabilele descrise în aceasta. Când este apelată o procedură, valorile fiecăruia dintre parametrii sunt specificate în comanda de apelare (de obicei după numele subrutinei apelate).
program SubProgExample2 ; // Descrierea procedurii subprogramului subprog subprog ( Linie : String ) ; // Antetul care include numele subrutinei începe // începutul corpului subrutinei WriteLn ( Linie ) ; sfârşitul ; // sfârşitul corpului subrutinei începe WriteLn ( 'Bună ziua' ) ; subprog ( „La revedere,” ) ; // Primul apel la subprog ( 'iubita mea' ) ; // Al doilea apel la subprog ( 'la revedere!' ) ; // Încheierea celui de-al treilea apel .În exemplul de mai sus, parametrul Linie al subrutinei subprog este setat la o valoare diferită în fiecare apel, astfel încât să fie afișate linii diferite în loc de aceeași.
Pentru a distinge parametrii unui subprogram, descriși în antetul și corpul său, de parametrii specificați atunci când subprogramul este apelat, se folosesc parametrii formali și actuali. Parametrii formali sunt specificați la declararea sau definirea unei subrutine, iar parametrii actuali sunt specificați direct atunci când este apelată. Deci, în ultimul exemplu, parametrul Line din antetul și corpul subprog este parametrul formal, iar șirul „La revedere” folosit în primul apel la această subrutină este parametrul real. Când este apelată o subrutină, parametrii efectivi specificați în comanda de apel devin valorile parametrilor formali corespunzători, ceea ce asigură transferul de date către subrutină.
Există mai multe moduri de a trece parametrii unei subrutine.
Un limbaj de programare poate oferi posibilitatea de a transmite parametrii subrutinelor fie numai prin valoare, fie prin valoare și prin referință, fie prin nume și valoare. În ultimele două cazuri, construcții sintactice separate sunt folosite pentru a distinge între modalitățile de transmitere a unui parametru (în Pascal, acesta este cuvântul cheie var când descrieți un parametru). De fapt, dacă limbajul conține conceptul de link (pointer), atunci puteți face fără a trece un parametru prin referință (poate fi întotdeauna modelat prin descrierea unui parametru de tip „referință”), dar această caracteristică este convenabilă, deoarece vă permite să lucrați cu o referință formală a parametrului fără dereferire și, de asemenea, crește fiabilitatea și securitatea programului.
Restricții naturale sunt impuse parametrilor trecuți prin referință: parametrul real substituit unui astfel de parametru atunci când este apelat trebuie să fie o variabilă (adică să aibă o adresă), iar în limbile puternic tipizate, trebuie să aibă și exact același tip de date.
Există două tipuri de subrutine utilizate în limbajele de programare de nivel înalt: proceduri și funcții .
În limbajele asemănătoare C , o subrutină este întotdeauna descrisă ca o funcție. Procedura este implementată în funcție de tipul void , adică are un tip „vid” și, în consecință, nu returnează nicio valoare.
Subrutinele care fac parte din clasele în limbaje de programare obiect sunt de obicei numite metode . Acest termen se referă la orice subprograme membre ale unei clase, atât funcții, cât și proceduri; atunci când se cere clarificare, se vorbește de metode-proceduri sau metodă-funcții .