C++-manual
Förutgående | Kapitel 7. Funktioner | Nästa

# Funktionen `main()`

Som vi redan tidigare såg i programmet Hello world! finns det en speciell funktion som heter `main()`. Denna funktion är speciell på det sättet att den är alltid den första funktionen som utförs i ett C/C++-program. Denna funktion kan sedan i sin tur anropa andra funktioner och på så vis bygga upp den egentliga funktionaliteten i programmet. Det finns inga undantag till detta, `main()` är alltid den första funktionen. När funktionen `main()` avslutas, avslutas även hela programmet. Vi ska i fortsättningen alltid använda `main()` i exempel där det är möjligt, för att göra dem mera kompletta.

Funktionen `main()` kan inte heta något annat än just `main()`, inga andra stavningar tillåts. Om kompilatorn inte hittar denna funktion när den kompilerar ett program fås en varning eller ett fel. Ett program med två funktioner som anropas från `main()` kan se ut som följande:

    #include <iostream>

    float RaknaArea (float Sida1, float Sida2) {
      // beräkna och returnera en area av en rektangel
      return Sida1 * Sida2;
    }

    void SkrivSvar (float Area) {
      cout << "Arean är: " << Area << endl;
    }

    int main () {
      // beräkna arean
      float Area = RaknaArea ( 5.5, 10 );

      // skriv ut svaret
      SkrivSvar ( Area );
    }

Här har vi nu två skilda funktioner som anropas från `main()`. En liten förenklig som kunde göras i `main()` är att kombinera areaberäkningen med utskriften. Eftersom `RaknaArea()` returnerar en `float`, och `SkrivSvar()` vill ha en `float` som parameter kan man skriva om `main()` på detta sätt:

    int main () {
      // beräkna arean och skriv ut svaret
      SkrivSvar ( RaknaArea ( 5.5, 10 ) );
    }

Nu använder vi resultatet från `RaknaArea()` direkt och skickar det till `SkrivSvar()` utan använda en temporär variabel som mellanlagring.

## Returvärde från `main()`

Som vi sett deklareras `main()` alltid med returvärdet `int`, även om vi aldrig utför någon `return`-sats. Detta returvärde skall om det ges vara ett positivt heltal som skall ange hur programmets körning lyckades. Värdet 0 indikerar en lyckad körning utan fel, medan andra värden indikerar fel av olika typ. Det system som kör programmet kan således få reda på hur programmets exekvering gick. Om inget returvärde ges explicit placera kompilatorn automatiskt en sats `return 0` sist i programmet. Alltså om man inte manuellt specifierare returvärdet från `main()` fås alltid värdet 0. Detta gäller dock endast funktionen `main()`.

## Prototyper

I exemplen ovan har vi alltid haft `main()` sist i programmet. Vad händer om man istället flyttar `main()` först, och placerar `RaknaArea()` och `SkrivSvar()` efter? Man skulle ju tycka att det inte vore någon skillnad överhuvudtaget, men det är tyvärr en skillnad. C++-kompilatorer är för det mesta ganska lata, och kräver att alla symboler, variabler och funktioner måste vara definierade före de används. Då kompilatorn läser ett program med `main()` först, kommer den att stöta på funktionerna `RaknaArea()` och `SkrivSvar()` som inte ännu är definierade, eftersom de definieras först några rader senare! Allting måste alltså vara definierat före det används. Tänk om man har en situation med två funktioner som anropar varandra. I det fallet går det helt enkelt inte att definera båda funktionerna före de används. Det finns en omväg runt detta dilemma, och det är något som kallas prototyper. En prototyp är en en definition som är menad för kompilatorn och berättar hur en funktion ser ut. Prototypen innehåller ingen kod, endast funktionens namn, returvärde och parametrar. Allmänt ser det ut så här:

    returtyp funktionsnamn (parametertyp1 parameter1, ... );

En funktionsprototyp har ingen kropp innesluten mellan `{` och `}`. När kompilatorn stöter på en dylik rad vet den hur en viss funktion ser ut, och kan använda den redan innan den definieras. Kompilatorn vet även att själva koden för funktionen "kommer senare". Vi kan nu skriva om vår areaberäkning med prototyper så att `main()` är först:

    #include  <iostream>

    // prototyper för våra två funktioner
    float RaknaArea (float Sida1, float Sida2);
    void SkrivSvar (float Area);

    int main () {
      // beräkna arean
      float Area = RaknaArea ( 5.5, 10 );

      // skriv ut svaret
      SkrivSvar ( Area );
    }

    float RaknaArea (float Sida1, float Sida2) {
      // beräkna och returnera en area av en rektangel
      return Sida1 * Sida2;
    }

    void SkrivSvar (float Area) {
      cout << "Arean är: " << Area << endl;
    }

Notera de två prototyperna överst. De måste stämma överens med de parametrar och returvärden som sedan egentligen används av funktionerna. Om prototyper ges för funktioner som sedan aldrig skrivs kommer kompilatorn att ge ett felmeddelande. Den "magiska" raden `#include <iostream>` kommer att behandlas senare (se Kapitel 10), och nu räcker det med att raden syftar till en fil som innehåller prototyp-deklarationer för de I/O-funktioner vi använder (`cout`).

Förutgående | Hem | Nästa
Parametertyper | Upp | Parametrar till `main()`