Subrutină

Versiunea actuală a paginii nu a fost încă revizuită de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 16 octombrie 2017; verificările necesită 19 modificări .

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.

Scopul 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.

Beneficii

Beneficiile împărțirii unui program în subrutine includ:

Mecanismul subrutinelor, descrierea și apelul lor

Î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).

Parametrii subprogramului

Atribuirea parametrilor

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.

Parametri formali și actuali

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ă.

Cum se transmit parametrii unei subrutine

Există mai multe moduri de a trece parametrii unei subrutine.

  • Transmiterea parametrilor după valoare. Parametrului formal i se atribuie valoarea parametrului actual. În acest caz, parametrul formal va conține o copie a valorii prezente în cel actual, iar orice efect care se face în interiorul subrutinei asupra parametrilor formali nu este reflectat în parametrii actuali. Deci, dacă o variabilă este utilizată ca parametru real și valoarea parametrului formal corespunzător este modificată în interiorul subrutinei, atunci parametrul actual va rămâne neschimbat.
int func1(int x) { x=x+2; întoarce x; }
  • Transmiterea parametrilor prin referință. Parametrul real în sine poate fi plasat în parametrul formal (de obicei, acest lucru este implementat prin plasarea unei referințe la parametrul real în parametrul formal). În acest caz, orice modificare a parametrului formal din subrutină va fi reflectată în parametrul actual - ambii parametri în timpul apelării subrutinei sunt aceiași. Parametrii transmiși prin referință fac posibilă nu numai trecerea parametrilor în interiorul subrutinei, ci și returnarea valorilor calculate la punctul de apel. Pentru a face acest lucru, parametrului din interiorul subrutinei i se atribuie pur și simplu valoarea dorită, iar la întoarcerea din subrutină, variabilei utilizate ca parametru real i se atribuie acea valoare.
void func2(int &x) { x=x+2; }
  • Transmiterea parametrilor după nume. O expresie arbitrară poate fi plasată într-un parametru formal. În acest caz, calculul acestei expresii va avea loc în interiorul subrutinei în momentul în care este necesară valoarea acesteia. Dacă această valoare apare de mai multe ori, atunci va fi calculată și de mai multe ori. Parametrii trecuți după nume fac posibilă scrierea de subrutine destul de versatile. Această metodă de transmitere a parametrilor este utilizată, de exemplu, în limbile Algol sau Algol 68 .
  • Transmiterea parametrilor pe stivă. Acesta este de fapt un fel de parametru care trece prin valoare „cu acţionare manuală”, în acest caz nu există conceptul de parametri formali şi reali. Toți parametrii se află pe stivă, iar tipurile, numărul și ordinea lor nu sunt controlate de compilator. Această abordare este implementată în limba Forth .

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.

Tipuri de subrutine

Există două tipuri de subrutine utilizate în limbajele de programare de nivel înalt: proceduri și funcții .

  • O funcție  este o subrutină de un tip special, care, pe lângă primirea parametrilor, efectuarea acțiunilor și transmiterea rezultatelor muncii prin parametri, are încă o caracteristică - trebuie să returneze întotdeauna un rezultat. Un apel de funcție este, din punctul de vedere al limbajului de programare, o expresie; poate fi folosit în alte expresii sau ca partea dreaptă a unei sarcini.
  • O procedură este o parte independentă denumită a unui program care, după ce a fost descrisă o dată, poate fi apelată în mod repetat după nume din părțile ulterioare ale programului pentru a efectua anumite acțiuni.

Î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 .

Vezi și