Variabler är centrala för att lagra och komma åt data inom programmering. Till varje variabel finns ett, av programmeraren definierat, namn som används för att referera till den lagrade datan.
En variabel i C deklareras och tilldelas ett värde på följande vis:
int var;
var = 10;
På första raden allokeras minne för en variabel av typen int och sedan associerar vi den här inten med namnet var. På andra raden lägger vi in värdet 10 på just den minnesplatsen som är associerad med namnet var.
Det är också möjligt att tilldela värdet direkt vid deklareringen, s.k. initiering:
int var = 10;
Olika datatyper ger möjligheten att koda in olika typer av information i datorns minne. Även storleken på informationen återspeglas av datatypen.
Det finns ett flertal olika typer för variabler i C. För numeriska värden har vi två huvudtyper: heltal och flyttal (decimaltal). Då datorn har ett begränsat minne kan inte hur stora tal eller tal med hur hög precision som helst lagras. Ska man lagra t.ex. pi så måste man begränsa antalet decimaler.
För heltal har vi följande datatyper:
char
int
och för flyttal har vi:
float
double
Det som skiljer de olika typerna för heltal respektive flyttal är med vilken precision data går att lagra, d.v.s. hur stor plats i minnet den lagrade variabeln ska uppta. Exakt hur många bytes en viss datortyp tar går inte att säga generellt, det beror helt enkelt på hur din dator är byggd och hur de olika datortyperna är implementerade i den kompilator du använder. Dock för en vanlig modern persondator ser det vanligtvis ut som i tabellerna 1 och 2.
Det är möjligt att, för en viss datatyp, modifera den genom att lägga till ett visst nyckelord framför datatypen. Ett sådant nyckelord kallas för en modifierare (eng. modifier).
I C finns följande modifierare:
signed
unsigned
short
long
signed och unsigned används endast för heltal och talar om huruvida talet ska lagras med tecken eller ej. Anges inget antas signed. Ofta har man värden som endast kan vara positiva, t.ex. ett antal, då kan man med fördel använda en unsigned datatyp eftersom större positiva tal då kan lagras med samma mängd minne.
short och long används för att modifiera mängden minne och därmed storleken på de värden som är möjliga att lagra. Kan användas både för hel- och flyttal. Tumregeln är att inte använda mer minne än man behöver, dock tenderar folk att inte reflektera så mycket över det nuförtiden då minneskapaciteten i en modern dator ofta är stor i förhållande till vad många program kräver.
OBS: alla kombinationer av modifierare är inte möjliga, se nästa stycke.
Som tidigare nämnts så är inte t.ex. en int ett visst antal bytes per definition. På en mikrocontroller kan en int vara 2 bytes och på en vanlig persondator 4 bytes. I tabellerna nedan sammanfattas hur det vanligtvis brukar se ut på en modern persondator.
Så vad händer då man överskrider det maximala värdet för en datatyp? Då man ökar det maximala värdet för ett heltal med 1 så kommer det lägsta värdet antas igen (eng. wrap around).
char c = 128; /*c har nu värdet -128 då 127 är maximalt möjliga värde för en signed char*/
char d = 130; /* d = -126 */
Det finns även förutom modifierare andra typer av nyckelord som kan placeras framför datatypen vid deklarationen, dessa kallas för qualifiers. I C finns följande två qualifiers:
const
volatile
const: en variabel med qualifier const kan endast anges ett värde vid initieringen. Försöker man sedan ändra värdet så kommer kompilatorn se det och koden kommer inte att kompilera. const används för konstanter.
volatile: för att till fullo förstå nyttan med qualifiern volatile och när den ska användas så krävs lite djupare kunskaper inom hur processorn fungerar och hur datorns minneshantering ser ut. Här ges endast en kort svepande förklaring. Mellan processorn och RAM-minnet finns ett eller flera mindre snabbare s.k. cache-minnen, då data läses från RAMet så sparas det i cache-minnet för att ev. kunna läsas där ifrån nästa gång för att snabba upp läsningen. En volatile-variabel kommer alltid läsas från den minnesadress i RAMet där den är lagrad och inte från något cache-minne. Det kan vara användbart då dess värde kan komma att ändras av en annan process.
Nedan följer ett exempel på hur en konstant unisigned char kan initieras:
const unsigned char width = 100; /*den här variabeln kommer inte att kunna ändras igen*/
För att konvertera en datatyp till en annan kan konvertingsoperatorn () användas. Här följer ett exempel på hur t.ex. en int kan konverteras till en float.
int a = 10;
float f = (float)a;
I praktiken hade det, idet här fallet, fungerat utan att använda ()-operatorn, då kompilatorn hade förstått att det var fråga om en typkonvertering. I andra fall måste man dock använda explicit typkonvertering för att koden ska kompilera.