Spring til indhold

Subrutine

Fra Wikipedia, den frie encyklopædi

En subrutine er en samling computerinstruktionssætinstruktioner, evt. i form af nogle linjer i et programmeringssprog. Subrutinen udfører en bestemt opgave, som man har brug for at få udført ved kald fra forskellige steder i et computerprogram. Et kald af subrutinen er enklere og kræver mindre lager end alternativet at gentage nøjagtigt de samme instruktioner, hver gang de skal benyttes. Kald af subrutiner kan også benyttes for at strukturere et program ved opdeling i mindre dele, således at det bliver mere overskueligt.

Subrutiner, der vurderes at være generelt anvendelige, kan på forskellig vis placeres i ”biblioteker””, så de let kan genbruges i andre programmer, enten ved at inkludere subrutinens kode under oversættelsen, eller ved at linke til rutinen.

Forskellige betegnelser

[redigér | rediger kildetekst]

Subrutiner betegnes i nogle programmeringssprog som funktioner eller procedurer. Inden for objektorienteret programmering benyttes betegnelser som metode eller service. Endelig kan man støde på betegnelsen underprogram. Forskellen på en metode og en procedure er, at en funktion returnerer en værdi knyttet til funktionens navn (funktionen kan direkte indgå i en tildeling/et assignment), mens en procedure ikke returnerer en sådan værdi. Til gengæld vil en procedure kunne (men behøver ikke) returnere adskillige resultater i sin parameterliste. I andre programmeringssprog skelnes der ikke strengt mellem funktioner og procedurer, evt. kan en procedure blot være en funktion med returværdi af typen void.

Man kan også udtrykke det således, at en funktion evalueres til en værdi, mens en procedure er en ny kommando. I begge tilfælde er der tale om en abstraktion, idet den der benytter et kald af en subrutine ikke behøver kende detaljerne i subrutinens kode. Og denne kode kan ændres, uden at det ødelægger noget for resten af systemet. Det er dog her en fornuftig regel, at en funktion ikke bør have sideeffekter (effekter for andre dele af systemet end den værdi der returneres). For en procedure bør data ind og ud kun ske via parameterlisten, så man kan se, hvad der røres ved. Ingen benyttelse af fælles, globale variable.

I nogle tilfælde vil man for at få en hurtige afvikling af programmet undgå kaldet, der altid medfører et ekstraarbejde (overhead), men i stedet gentage instruktionerne, der udgør kroppen på subrutine, i det færdige program. Dette kan foregå ved brug af en makro eller overlades til oversætteren.

Implementering

[redigér | rediger kildetekst]

Når en subrutine kaldes, skal computeren gemme adressen på den instruktion, der følger umiddelbart efter kaldet af subrutinen, således at computeren kan vende tilbage til dette sted. Dette sker typisk derved, at cpu'en lagrer denne adresse i et særligt register (som eksempel kan nævnes branch-and-link(-register)-instruktionen på System/360 fra IBM), eller i andre computere ved at adressen, der er instruktionstælleren plus længden af instruktionskaldet, pushes på computerens stak, hvor den senere kan hentes igen. Der findes normalt også en form for "return-from-subroutine" instruktion.

Private data og rekursion

[redigér | rediger kildetekst]

Hvis subrutinen er implementeret på en sådan måde, at den har variable, der er private for rutinen, og således at et nyt kald af rutinen fra rutinen selv medfører skabelsen af et nyt sæt private variable, kan man benytte rekursiv programmering. Dette implementeres hyppigt ved at afsætte (allokere) lagerplads til disse variable i en activation record eller stack frame oven på stakken (oven på den returadresse der er blevet lagt på stakken forinden). Derfor vil ethvert nyt kald føre til allokeringen af en ny activation record oven på en ny returadresse, og sammenblanding af variable undgås.

Selv om et programmeringssprog ikke giver muligheder for private/lokale variable (de oprindelige versioner af BASIC gjorde ikke dette), så kan man godt skrive rekursive programmer. Men det lægger en stor byrde på programmøren at holde rede på, hvilke data er gemt hvor.

Parameterlisten

[redigér | rediger kildetekst]

Når man definerer en subrutine i et højniveausprog, vil man angive en række formelle parametre (evt. slet ingen). Disse formelle parametre vil blive benyttet i programkoden for subrutinen. Når man skriver et kald af subrutinen, vil man skulle skrive de aktuelle parametre, som skal benyttes i netop dette tilfælde. Det kan være variable eller konstanter/litteraler. Parametrene kan forstås på forskellige måder, hvor ikke alle er tilgængelige i hvert programmeringssprog og betegnelserne og implementeringen varierer.

  • Value. Parametrens værdi overføres til rutinen, men uanset hvad der måtte ske med denne værdi inden for subrutinen, så vil ændringerne ikke føres tilbage til den oprindelige variabel.
  • Value-result. Der overføres (typisk) en pointer til en variabel i det kaldende program. Hvis variablen ændres inden for subrutinen, vil ændringen ske i variablen i det kaldende program. Data kan føres ind, ændres, og den nye værdi føres ud.
  • Result. Endelig kan man have en parameter, der kun tillader et resultat at føres ud af subrutinen.
  • I en subrutine, der benyttes i et remote procedure call er det lidt mere kompliceret og kan give uventede resultater, hvid den samme variabel benyttes i to resultatparametre i samme kald.

Kilder og henvisninger

[redigér | rediger kildetekst]
  • Programming Language Concepts and Paradigms, David A. Watt, 1990
  • Programming with Assembly Language, David E. Goldberg, Jacqueline A. Jones, Pat H. Sterbenz, 1988