Funktion (programmering)
- For alternative betydninger, se Funktion. (Se også artikler, som begynder med Funktion)
Inden for programmering er en funktion (underprogram, subrutine, procedure, eller metode) en stump kode som udfører en bestemt opgave som del af et større program. Sådanne stumper af kode bliver ofte samlet i biblioteker. De kan kaldes flere forskellige steder uden at kodestumpen skal skrives mere end en gang. I de fleste programmeringssprog skal en sådan kodestump have et navn, men en del sprog tillader også anonyme funktioner, også kaldet lambda-funktioner.
I nogle programmeringssprog, fx Pascal, skelner man mellem funktion og procedure, hvor en funktion returnerer en værdi mens en procedure ikke gør.
En funktion identificeres ud fra dens prototype, eller signatur, som består af tre elementer. De vigtigste 2 er et funktionsnavn og en eller flere formelle parametre; i stærkt typecheckede programmeringssprog specificeres parametertyper, hvor der med type menes datatype. Det tredje element er datatypen af funktionens evt. returværdi.
Ud over prototypen indeholder funktionen noget programkode, der definerer den egentlige behandling af inddata. Koden aktiveres gennem et funktionskald, hvor konkrete værdier – aktuelle parametre, også kaldet argumenter – bliver bundet til, dvs. brugt til at initialisere, de enkelte formelle parametre; det er disse værdier, funktionskoden under udførelse af et funktionskald arbejder på. M.a.o. fungerer navnene på de formelle parametre i koden som pladsholdere for de aktuelle værdier. Der er flere forskellige mekanismer for denne binding af aktuelle værdier, eller argumenter, til de formelle parametre; bindingsprocessen kaldes også parameteroverføring [1].
Kaldets resultat, eller uddata, kan lagres i en variabel, bortkastes, testes på eller indgå som et argument i et andet funktionskald. Funktioner, som ikke returnerer et resultat, har returtypen "void" i mange programmeringssprog, især fra C-familien.
En funktion kan oprette sine egne lokale variabler, der kun eksisterer så længe funktionen kører og som er utilgængelige for andre funktioner. Dette gør funktionen i stand til at arbejde med midlertidige data, som kun skal bruges i forbindelse med det aktuelle fuktionskald. En variant er statiske lokale variabler, som overlever fra kald til kald og derfor gør det muligt at gemme resultatet af en beregning til næste gang den skal udføres, fx som den nye initialværdi.
I modsætning til lokale variabler er globale variabler synlige og tilgængelige for alle funktionerne i en programmeringsenhed (modul) eller endda i hele programmet. Da enhver funktion kan både læse og overskrive værdierne af globale variabler, er det fristende at bruge disse variabler som en slags postkasser til at overføre værdier mellem funktionskald. Denne fremgangsmåde frarådes, da den gør fejl betydelig mere sandsynlige (jf. Murphy's lov) og kodevedligeholdelse og fejlfinding betydelig mere besværlige.
Funktioner kan kalde andre funktioner, og i de fleste moderne programmeringssprog kan de også kalde sig selv, hvorved de bliver rekursive. Eksempler på programmeringssprog som tillader rekursion er Pascal, C/C++, Java og andre sprog fra Algol-familien. I funktionsorienterede programmerinsgssprog bruges rekursion i udpræget grad – eksempler er LISP og SML. Det samme gælder mange deklarative programmeringssprog, fx Prolog.
I samtlige programmeringssprog er der visse prædefinerede funktioner som kan bruges. Disse funktioner omfatter blandt andet systemkald til operativsystemet samt gængse datakonverterings-, formaterings- og behandlingsalgoritmer.
Et eksempel på en prædefineret funktion er "easter_date()" funktionen i PHP. I dette tilfælde er året inddata, og uddata er den dato hvor påskedag ligger for det pågældende år. F.eks. vil "easter_date(2005)" returnere noget i retning af "0411", dvs. 11. April. Typisk vil mange matematiske funktioner også være prædefinerede, f.eks. sinus og cosinus, kvadratrod osv.
Noter
[redigér | rediger kildetekst]- ^ Den mest grundlæggende overføringsmekanisme er værdioverføring, hvor den formelle parameter bliver initialiseret med en kopi af den tilsvarende aktuelle værdi. Da de formelle parametre i funktionskoden fungerer på linje med lokale variabler, kan funktionskoden derfor ændre parametrenes værdier uden at det får virkning på de aktuelle parametre og dermed uden for funktionen. En anden parameteroverføringsmekanisme er referenceoverføring, hvor det er en reference til den aktuelle værdi som parameteren bliver initialiseret med. Hvis funktionskoden modificerer værdien af en referenceoverført formel parameter, indvirker det på den tilsvarende arguments værdi. Den aktuelle parameter skal derfor i dette tilfælde referere til en modificerbar variabel. En tredje parameteroverføringsmodel er navneoverføring, som svarer til at den formelle parameter over alt i funktionskoden bliver erstattet af ordlyden af den aktuelle parameter; derefter bliver den således indsatte værdi gen-evalueret hver gang den bruges. Beregningsmæssigt er referenceoverføring den mindst krævende, da der typisk overføres en eller en pointer, dvs. en enkelt maskindresse, el.lign. Værdioverføring er betydeligt tungere, når de kopierede værdier er omfangsrige eller komplekse. Desuden kan de aktuelle parametre være udtryk. Navneoverføring kan pga. de gentagne gen-evalueringer være særlig omkostningskrævende og ses derfor efterhånden sjældent i imperative programmeringssprog. Til gengæld er det den potentielt mest slagkraftige af disse 3 overføringsmetoder; når den aktuelle parameter er en variabel, svarer navneoverføring nærmest til værdioverføring, men når parameteren er et udtryk, kan den bruges til særdeles avanceret programmering, jf. Jensen's device – i øvrigt en dansk opfindelse.