Programmeringsspråket C

Strängar - grunderna

Vad är en sträng?

En sträng är en serie bokstäver som hör ihop. En sträng är inte ett värde. En sträng är inte en enstaka bosktav (som ju är ett värde, så långt datorn bryr sig). När man anger strängar brukar man använda text inom citattecken.

"detta är en sträng"
'd'
637
"637"
'7'
7
"7"

Det är viktigt att skilja på dessa olika typer. Det första är en sträng, en serie bokstäver. Det andra är en enstaka bokstav. Det tredje är ett numeriskt värde. Det fjärde är en sträng, alltså går det inte att utföra matematik på den (för datorn är det inget värde, bara en serie tecken). Det femte är ett tecken, nämligen en sjua. Det har inte värdet sju. Om du kollar på en ASCII-tabell ser du att '7' har värdet 55. Det sjätte är värdet 7. Det sjunde är en sträng som innehåller en sjua. Det är inte samma sak som en enstaka sjua.

När detta är klargjort kan vi dyka mer in i strängar och hur de fungerar i C. Som vi nämnde i tidigare kapitel så hör arrays och char-typen ihop med strängar. Detta är för att i C är strängar precis samma sak som en array med chars. Denna typ av sträng kallas för "C-sträng", och är det vi arbetar med i C. Det fungerar som följer, enstrang är en char-array med längd 9.

enstrang [0]  [1]  [2]  [3]  [4]  [5]  [6]  [7]  [8]
         'h'  'e'  'j'  'h'  'o'  'p'  'p'  's'  '\0'

Varje position i arrayen har en bokstav som värde, och tillsammans utgör de en sträng. Notera dock det sista tecknet, '\0'. Detta kallas null-tecken och har ASCII-värde 0. Det används av olika funktioner att visa att "här tar strängen slut, leta inte efter fler bokstäver".

Varning! En sträng utan ett avslutande null-tecken kan orsaka att programmet kraschar, eftersom den då kommer leta på en plats i arrayen som inte finns. Om vi tar vårat exempel från ovan, om inte '\0' finns med, kommer den sen försöka leta på position [9], [10], [11] och så vidare. Eftersom datorn inte är förberedd på detta (minnescellerna är inte allokerade som "våra") är beteendet odefinierat.

Studera följande kod, som visar en exempelanvändning av strängar.

#include <stdio.h>
 
int main() {
    char namn[7] = "anonym";
 
    printf("Ditt namn är: %s\n", namn);
 
    return 0;
}

Det finns några viktiga grejer att komma ihåg från detta exempel. Hur man bäddar in strängar i output med hjälp av printf() är den minst viktiga. Det riktigt intressanta sker på raden där strängen får sitt värde. Det är två saker vi vill dra din uppmärksamhet där. Det ena är att kompilatorn tolkar "citerade bokstäver" som en lång följd av enstaka tecken, och även automatiskt lägger till null-tecken på slutet. Detta är till fördel i till exempel detta fall, men det är långt ifrån alltid det fungerar som man kanske tänkt sig.

Det andra är storleken på arrayen. Vi reserverar 7 platser, trots att namnet bara är 6 tecken. Detta kan verka förvirrande, men kom ihåg att null-tecknet också är ett tecken som måste få plats. Får det inte plats uppstår gärna en segfault, och hur det ter sig i programmet är svårt att veta.

Varning! Ett viktigt ord om segfaults: Windows tenderar att sopa dem under mattan. Om Windows stöter på en segfault försöker den göra det bästa av situationen och tuffa vidare, och även om det kan låta bra är det verkligen inte det. För när olyckan är framme och det blir fel så kan det vara svårt att upptäcka i tid. Detta verkar också bara ha blivit värre och värre för varje Windowsversion. Windows 98 verkar rapportera segfaults lika bra som Unix/Linux, Windows XP rapporterar vissa, men oftast inte i tid. Windows Vista brukar inte rapportera dessa alls.

Eftersom alla tecken ska få plats, är det viktigt att ha marginal när man låter användaren skriva in strängar. Om inte hela strängen med null-tecken får plats tas alla tecken som inte fick plats bort, detta inkluderar null-tecknet och då hamnar vi där vi inte får vara. Därför är ett tips att se till att det sista tecknet alltid är ett null-tecken.

Notera att vi nu har gått igenom absoluta grunderna för strängar, inget mer. Utifrån dessa grunder kan man göra i princip allt, men det gäller att verkligen tänka till. För den som undrar: i nästa del tar vi upp ett sätt att läsa in strängar.

← Char-typen

Funktioner →

Copyleft kqr & slaeshjag 2009, 2012 some rights reserved