returnera.xml

Denna kod är public domain. Om ni hittar fel eller vill ändra något i koden blir jag jätteglad om ni skickar dessa ändringar till jesper [at] fantasi [punkt] se.


<?xml version="1.0"?>
<article category="software" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="article.xsd">
  <keyword>Returnera</keyword>
  <keyword>Returtyp</keyword>
  <keyword>Felkod</keyword>
  <keyword hidden="true">returnerar</keyword>
  <keyword hidden="true">returneras</keyword>
  <keyword hidden="true">returtypen</keyword>
  <keyword hidden="true">return</keyword>
  <keyword hidden="true">felkoder</keyword>
  <keyword hidden="true">felkoden</keyword>
  <keyword hidden="true">exit_success</keyword>
  <keyword hidden="true">exit_failure</keyword>
  <keyword hidden="true">returvärde</keyword>
  <keyword hidden="true">returvärden</keyword>
  <keyword hidden="true">returvärdena</keyword>
  <topic>Att returnera data</topic>

  <ingress>
    Att returnera något i ett program betyder att man skickar något
    värde till den som anropade koden. Är det en funktion som
    returnerar ett värde så hamnar det hos den som anropade
    funktionen. Är det ett program som returnerar ett värde så hamnar
    värdet hos den som startade programmet.
  </ingress>

  <text>
    Funktioner måste i många språk deklareras med en <em>returtyp</em>
    som talar om vilken sorts data som ska returneras.  Om inget data
    ska returneras från funktionen kan man i språk som till exempel C
    och Java ge den returtypen <code>void</code>.  I andra språk, som
    till exempel Ada och Pascal, måste funktioner alltid returnera ett
    värde. Funktioner som inte returnerar något heter nämligen
    procedurer i dessa språk. Strikt sett så är det Ada och Pascal som
    har rätt. Det är skillnad på funktioner och procedurer, och
    funktioner ska alltid ha ett returvärde.
  </text>

  <text>
    När programkörningen når en retursats så hoppar den ur funktionen
    den befinner sig i. Programkörningen fortsätter på instruktionen
    direkt efter funktionsanropet i den anropande koden.
    Eventuell kod som ligger efter retursatsen kommer aldrig
    att kunna köras. Man brukar kalla sådan kod för död kod.
  </text>

  <codebox title="Kodexempel i C">
    char printable(char ch)
    {
       if (ch <lt /> 32)
          return ' ';
       if (ch <gt /> 126 &amp;amp;&amp;amp; ch <lt /> 161)
          return ' ';
       return ch;
    }
  </codebox>

  <text>
    Här ser vi att det finns flera retursatser i en funktion.
    Beroende på hur de olika villkoren faller ut kommer olika värden
    att returneras.  När man har retursatser i villkorliga satser så
    är det viktigt att komma ihåg att ha en retursats som fångar upp
    de fall som inte matchar något av villkoren. Om man har deklarerat
    att funktionen ska returnera någon typ så måste den göra
    det i alla lägen.  Programkörningen får aldrig nå slutet av
    funktionen utan att nå fram till en retursats.
  </text>
  <text>
    Det är också viktigt att alla retursatser returnerar data av rätt
    typ. Returtypen återkommer på tre ställen i samband med en
    funktion och det är viktigt att alla tre platser hanterar samma
    typ. Dels är det själva funktionsdeklarationen som har en
    returtyp. Denna returtyp deklareras ofta innan funktionsnamnet.
    Funktionen <code>printable</code> ovan har returtypen <code>char</code>.
    Det andra stället som ska matcha returtypen är där funktionen tar
    slut. Där finns kommandot <code>return</code> som kommer att utföra
    själva tillbakaskickandet av returvärdet. Om funktionen säger att
    den ska skicka tillbaka en <code>char</code> så får man se till att
    <code>return</code> faktiskt gör det. Det tredje stället där det
    måste stämma är i den anropande koden. Om en funktion returnerar
    ett värde ska man ta hand om det och då måste man förstås behandla
    det som den typ som funktionen säger att den returnerar.
  </text>

  <subtopic>Returvärden</subtopic>
  <text>
    De flesta språk har någon form av huvudfunktion där man anser att
    programmet startar. I C och Java brukar den heta <code>main</code>
    medan till exempel Basic-dialekter och Pascal har en huvudfunktion
    som rent visuellt ligger ytterst i koden. Returvärdet från denna
    huvudfunktion är lite speciellt. Detta värde ska ju skickas
    tillbaka till den som anropade programmet och det måste därför
    följa de anropskonventioner som det aktuella operativsystemet
    har. Unix och C har satt standarden för detta och de flesta följer
    den i stora drag.  Ett programs returvärde i Unix representerar en
    statusflagga som talar om ifall programmet lyckades med sin
    uppgift eller ej. Om ett program returnerar 0 betyder det att allt
    gick bra, ett returvärde skilt från 0 betyder att något gick
    fel.
  </text>
  <text>
    I ANSI C representeras dessa felkoder med två konstanter:
    <code>EXIT_SUCCESS</code> och <code>EXIT_FAILURE</code>. När man
    jobbar i C bör man alltid använda dessa konstanter som returvärde
    från <code>main</code> (både då man avslutar med
    <code>return</code> och <code>exit</code>) för att hålla koden så
    plattformsoberoende som möjligt. Andra plattformar än Unix kan
    betrakta ett returvärde på andra sätt och anpassar då definitionen
    av felkoderna därefter. I till exempel Sony NEWS-OS version 4.0C
    har man av misstag definierat <code>EXIT_SUCCESS</code> till 1 och
    <code>EXIT_FAILURE</code> till 0. VMS definierar
    <code>EXIT_SUCCESS</code> till 1 och <code>EXIT_FAILURE</code>
    till <code>0x10000002</code> (eller 3, eller 0...). En annan
    ganska vanlig implementation av <code>EXIT_FAILURE</code> är
    -1. AmigaOS har en bredare skala av felkoder som vi kan se i
    tabellen nedan.  Man kan även tänka sig inbyggda system som tolkar
    felkoderna helt annorlunda beroende på minnesbesparingar eller
    begränsade datatyper. Det enda man kan lita på när man
    programmerar för inbyggda system är att ingenting fungerar som man
    är van vid.
  </text>

  <table start="-1" header="Returvärde-+-Kommentar">
    <row data="0-+-Allt är bra."/>
    <row data="5-+-Mindre fel uppstod. Inget som påverkar kommande programs funktion." />
    <row data="10-+-Fel uppstod. Programmets utdata kan vara felaktig." />
    <row data="20-+-Allvarligt fel. Eventuella kringliggande script bör avbrytas." />
  </table>
</article>