next up previous contents
Nästa: 14.3 Argument Upp: 14. De första programmen Förra: 14.1 Hej, världen!

14.2 Variabler

Med en variabel i C menas ett lagringsutrymme som har getts ett namn. I lagringsutrymmet kan man förvara exempelvis ett heltal eller en textsträng. Det som finns i lagringsutrymmet kallas för variabelns värde.

Vi kommer ofta att tala om lagringsutrymmet som ett gömställe; värdet som finns där betraktar vi som en skatt. Detta är naturligtvis en smula barnsligt, något jag ber läsaren ha överseende med eftersom det kommer att hjälpa oss att bättre förstå hur variabler fungerar.

Man måste i förväg tala om för C vilken typ av värde variabeln ska ha. Detta kallas för att deklarera variabeln. Följande program använder en heltalsvariabel:

#include <stdio.h>

int main(int argc,char *argv[])
{
  int tal;

  tal=5;
  printf("Talet har värdet %d.\n",tal);
return 0;
}

Raden int tal; deklarerar tal som en heltalsvariabel (int). Satsen tal=5; ger variabeln tal värdet 5. Eller, med vår terminologi, en skatt på 5 miljoner kronor lagras i ett gömställe med namnet tal. Likhetstecknet ska alltså läsas som ''tilldelas värdet''. Syntaxen för textsträngen i printf ovan är något besynnerlig. Mellan citationstecknen har vi med %d angett att ett heltal ska stoppas in på den platsen, och efter kommat anges vilket heltal det är som ska stoppas in där.

Antag att programmet ovan är sparat under namnet heltal.c. Vid kompileringen vill vi att det körbara programmet ska heta heltal snarare är a.out. Detta anges med flaggan -o till gcc.$ gcc -o heltal heltal.c
$ heltal
Talet har värdet 5.
$
Ett variabelnamn som står till vänster om ett likhetstecken syftar på lagringsutrymmet, inte på värdet som finns lagrat där (dvs på gömstället, inte på skatten). Likhetstecknet kallas för tilldelningsoperatorn. Satsen tal=5; betyder alltså ''lagra talet 5 i lagringsutrymmet med namnet tal''. I andra sammanhang, dvs när tal inte står till vänster om en tilldelningsoperator, är det underförstått att namnet tal syftar på det värde som lagras i variabeln (dvs det syftar på skatten, inte på gömstället). Ett exempel på detta är att tal såsom argument till funktionen printf tolkades som talet 5.

Ändra nu programmet ovan till följande:

#include <stdio.h>

int main(int argc,char *argv[])
{
  int tal;

  printf("Ange ett tal: ");
  scanf("%d",&tal);
printf("Talet har värdet %d.\n",tal);
return 0;
}

 Instruktionen scanf("%d",&tal) läser in ett heltal och tilldelar variabeln tal detta heltal som värde. Kompilera om programmet och prova:$ gcc -o heltal heltal.c
$ heltal
Ange ett tal: 34
Talet har värdet 34.
$
Observera tecknet & före tal ovan. Det är inte särskilt lätt att förklara varför tecknet behövs, men vi försöker ändå: scanf ska läsa in ett heltal och lagra det i variabeln tal. Därför måste scanf få veta var lagringsutrymmet finns. Om vi hade utelämnat tecknet &, och skrivit scanf("%d",tal), så hade tal syftat på det värde som finns lagrat i variabeln. Men scanf vill inte veta vad det gamla värdet (skatten som ska ersättas) var, utan bara var lagringsutrymmet (gömstället) finns. Tecknet & anger att vi syftar på lagringsutrymmet, inte på värdet.

Misströsta inte om stycket ovan förefaller obegripligt. För tillfället räcker det att vi är medvetna om att tecknet & behövs vid anrop av scanf. Vad hade hänt om vi glömt ta med tecknet & i programmet ovan? Jo, tyvärr hade C-kompilatorn accepterat programmet utan någon som helst varning, och vid körningen hade det gått så här:$ heltal
Ange ett tal: 34
Segmenteringsfel (core dumped)
$
Programmet kraschar alltså efter att vi matat in det nya värdet. På gott och ont får man göra hur man vill i C - till och med vissa grova fel accepteras eftersom C-kompilatorer utgår från att programmeraren alltid vet vad hon/han gör. Därför är C oerhört flexibelt men samtidigt oerhört farligt. Liksom en extremt vass kniv, är C ett mycket användbart verktyg - men om man använder detta verktyg oskickligt kan man göra sig ordentligt illa. Ett bra sätt att minska risken för olyckor är att ge gcc flaggan -Wall, vilken anger att vi vill bli varnade för allt i programmet som ser mystiskt ut. Om vi tar bort tecknet & från programmet ovan och kompilerar det med flaggan -Wall, så går det så här:$ gcc -Wall heltal.c
heltal.c: In function `main':
heltal.c:8: warning: format argument is not a pointer (arg 2)
$
Varningen avser att det andra argumentet i rad 8 verkar skumt, det ''är inte en pekare''.

Nästa program ska läsa in två tal, beräkna deras summa och skriva ut resultatet. Så här kan det se ut:

#include <stdio.h>

int main(int argc,char *argv[])
{
  int tal1,tal2,summa;

  printf("Ange två tal: ");
  scanf("%d%d",&tal1,&tal2);
summa=tal1+tal2;
  printf("Summan av %d och %d är %d.\n",tal1,tal2,summa);
return 0;
}

Här deklareras tre heltalsvariabler, nämligen tal1, tal2 och summa. Funktionen scanf läser in två heltal och lagrar värdena i variablerna tal1 och tal2. Sedan sätts värdet av variabeln summa till summan av de båda talen, och printf gör en utskrift. I textsträngen som är det första argumentet till funktionen printf har vi angett tre stycken %d. För var och en av dessa %d måste vi ange ytterligare ett argument till printf. Det första %d byts vid utskriften ut mot det argument som följer textsträngen, nämligen värdet av variabeln tal1. Det andra %d byts ut mot värdet av tal2, och det sista %d byts ut mot värdet av summa.$ gcc -o heltal heltal.c
$ heltal
Ange två tal: 5 7
Summan av 5 och 7 är 12.
$

När en variabel för första gången tilldelas ett värde säger man att den initieras. C ger inget felmeddelande ifall en oinitierad variabel används, men vilket värde variabeln har då är oklart. Här är ett exempel, programmet oinitierad.c:

#include <stdio.h>

int main(int argc,char *argv[])
{
  int tal;

  printf("Talet har värdet %d.\n",tal);
return 0;
}

Jag hoppas att ingen tar efter programmet ovan. Det är inte meningen att man ska använda en variabel innan den initieras.$ gcc -o oinitierad oinitierad.c
$ oinitierad
Talet har värdet 0.
$
Ovan hade variabeln tal värdet 0, men detta är inget man kan lita på att den alltid har. Istället kan man initiera variabeln vid deklarationen:

#include <stdio.h>

int main(int argc,char *argv[])
{
  int tal=13;

  printf("Talet har värdet %d.\n",tal);
return 0;
}

Om vi kompilerar och kör detta program, så ger det utskriften

Talet har värdet 13.


next up previous contents
Nästa: 14.3 Argument Upp: 14. De första programmen Förra: 14.1 Hej, världen!
Goran Andersson
1999-03-08