2 Pekare och dynamiska variabler.

Relevanta dokument
4 Sammansatta datatyper

*Pekarvärden *Pekarvariabler & *

Pekare. Pekare. Varför använder vi pekare? Vad är en pekare? Pekare. Deklaration/initiering av pekare

Övning från förra gången: readword

Lösningar till uppgifterna sätts ut på kurssidan på nätet i dag kl Omtentamen i Programmering C, Fri, Kväll,

Lösningar till uppgifterna sätts ut på kurssidan på nätet i dag kl Tentamen i Programmering C, Fri, Kväll,

4 Sammansatta datatyper

Minnestilldelning (allokering) och frigörande (avallokering) av minne

Pekare och arrayer. Indexering och avreferering

Lösningar till tentauppgifterna sätts ut på kurssidan på nätet idag kl 19. Omtentamen i Programmering C, 5p, fristående, kväll,

Namn:... Klass:... Pnr:... Omtentamen i Programmeringsmetodik, 5p, D1 och E1,

Lösningar till uppgifterna sätts ut på kurssidan på nätet idag kl Omtentamen i Programmering C, 5p, A1, D1, E1, Fri, Pr1, Te/Ek1,

Lösningar till tentauppgifterna sätts ut på kurssidan på nätet idag kl

Lämna in en ifylld kursvärdering tillsammans med tentan! Lösningar till uppgifterna sätts ut på kurssidan på nätet i dag kl

BINÄRA TRÄD. (X = pekarvärdet NULL): struct int_bt_node *pivot, *ny; X X X 12 X X 12 X X -3 X X

Dynamiskt minne. Vad är dynamiskt minne Motivering Hur gör man i C Övningar

TDIU01 - Programmering i C++, grundkurs

#include <stdio.h> #include <string.h>

Poster ( structar ) Postdeklarationer

Lösningar till uppgifterna sätts ut på kurssidan och på WebCT (Gamla Tentor) i dag kl 19. Tentamen i Programmering C, 5p, Distans, övriga,

Programmering, grundkurs, 8.0 hp HI1024, HI1900 etc., Tentamen TEN1. Måndagen den 10 januari 2011,

TDDC76 - Programmering och Datastrukturer

Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??

3 Listor. 3.1 Envägslistor

Lösningar till uppgifterna sätts ut på kurssidan på nätet i dag kl 13. Omtentamen i Programmering C, 5p, A1, D1, PA1, Fri,

Fortsä'ning Pekare. Ulf Assarsson. Originalslides av Viktor Kämpe

struct egendefinierad typ struct LECTURE_TYPE { char teacher[99]; float lengthinminutes; char type; /* L = lecture, E = exercise */ };

Agenda. Arrayer deklaration, åtkomst Makron Flerdimensionella arrayer Initiering Strängar Funktioner och arrayer. Övningar nu och då

Johan Karlsson Datavetenskap för teknisk kemi, 10p, moment 1 Datavetenskap Umeå Universitet. Tentamen

Funktionspekare, inledning: funktionsanropsmekanismen. Anrop via pekare

Lämna in ifylld kursvärdering tillsammans med tentamen! Lösningarna till tentamensuppgifterna sätts ut på kurssidan på nätet i dag kl 13.

Föreläsning 11. Strängar

C++ Lektion Tecken och teckenfält

TDDC76 - Programmering och Datastrukturer

Skriv i mån av plats dina lösningar direkt i tentamen. Skriv ditt kodnummer längst upp på varje blad.

TDIU01 - Programmering i C++, grundkurs

TDP004. Minne och pekare. Eric Elfving Institutionen för datavetenskap

Grundläggande C-programmering del 2 Pekare och Arrayer. Ulf Assarsson

Övningsuppgifter till föreläsning 2 Variabler och uttryck

Programmering i C, 7,5 hp

Föreläsning 5: Introduktion av pekare

Föreläsning 10. Pekare (Pointers)

Programmeringsteknik med C och Matlab

Tommy Färnqvist, IDA, Linköpings universitet

Länkade listor kan ingå som en del av språket, dock ej i C Länkade listor är ett alternativ till:

Fortsä'ning Pekare. Ulf Assarsson. Originalslides av Viktor Kämpe

Enkla datatyper minne

Programmering av inbyggda system. Pekare och Arrayer. Viktor Kämpe

Hantering av textsträngar och talsträngar. William Sandqvist

Tentamen ges för: Tentamensdatum: Tid:

TDDC77 Objektorienterad Programmering

Föreläsning 13. In- och utmatning

Värmedistribution i plåt

En kort text om programmering i C.

Ulf Assarsson. Grundläggande C-programmering del 2 Pekare och Arrayer. Läromoment:

Översikt Introduktion DST 1. Nicholas Wickström. IDE, Högskolan i Halmstad. N. Wickström

Exempel ( )

Föreläsning REPETITION & EXTENTA

Tentamen *:58/ID100V Programmering i C Exempel 3

Variabler använder man sig av för att under programkörningen spara data eller information i primärminnet. En variabel har typ, namn och värde.

Tentamen i Programmering grundkurs och Programmering C

7 Programmeringsteknik

Programmering av inbyggda system. Pekare och Arrayer. Ulf Assarsson. Originalslides av Viktor Kämpe

Strängar. Strängar (forts.)

Grundläggande C-programmering del 2 Pekare och Arrayer. Ulf Assarsson

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

HI1024, Programmering, grundkurs, 8hp KTH STH TENTAMEN. HI1024:TEN2 - Praktisk tentamen Tid: Fredagen den 21 oktober 2011,

Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p

[] Arrayer = Indexerad variabel

Programmeringsteknik för Ingenjörer VT06. Föreläsning 10

Visual Basic, en snabbgenomgång

Programmering i C. Vad är C? Målsättning. Litteratur. Jämförelse med Java. Exempel : Ett program som skriver ut texten Hello, world

Programmering, grundkurs, 8.0 hp HI1024, omtentamen, TEN1. Tisdagen den 7 juni 2011,

1 Modulär programutveckling.

Tentamen i Programmeringsmetodik, 5p, Au2, D1 och E1,

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

6.1 Kompilering och lite grundläggande information

Föreläsning 12. struct

Deklarera en struct som kan användas för att representera en rät linje

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

Inlämningsuppgift 1, Digsim

Tecken & Strängar. Kapitel 7

Alla datorprogram har en sak gemensam; alla processerar indata för att producera något slags resultat, utdata.

Föreläsning 3-4 Innehåll

Abstrakta datastrukturer

Att använda pekare i. C-kod

Exempelsamling Assemblerprogrammering

Tentamen i. för D1 m fl, även distanskursen. lördag 26 februari 2011

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

F5: Högnivåprogrammering

F5: Högnivåprogrammering

Planering Programmering grundkurs HI1024 HT 2014

Tentamen i Programmering grundkurs och Programmering C

Tentamen i. för D1 m fl, även distanskursen. lördag 19 januari 2013

Föreläsning 9. struct

Programmering, grundkurs, 8.0 hp HI1024, TEN1. Fredagen den 2 mars 2012

C++ Funktioner 1. int summa( int a, int b) //funktionshuvud { return a+b; //funktionskropp } Värmdö Gymnasium Programmering B ++ Datainstitutionen

Föreläsning 8 SLUMPTAL, SIMULERING + INTRODUKTION TILL VEKTORER

Föreläsning 2. Variabler, tilldelning och kodblock{} if-satsen Logiska operatorer Andra operatorer Att programmera

Instuderingsfrågor, del D

Transkript:

2 Pekare och dynamiska variabler. När man definierar en variabel reserverar man samtidigt minne för variabelns värde. Detta minnesutrymme kommer man sedan åt med hjälp av variabelns namn. Definierar man en sträng med 80 tecken, reserveras eller allokeras det minne för 80 byte, oberoende av om hela minnesutrymmet utnyttjas eller ej. Detta är en statisk modell för att allokera minne. Det finns ett mer dynamiskt sätt. Man definierar först en vanlig variabel i form av en pekare och sedan, under körning, när man vet hur mycket minne man behöver, reserverar man minne som man sätter pekaren att peka på. Detta minne kommer man sedan åt genom att avreferera pekaren. Denna typ av minne kan man under körningen avallokera, när det ej behövs längre. 2.1 Pekare Pekare är vanliga variabler som defineras till att peka på en speciell typ av data, eller mera generellt på vad som helst (med nyckelordet void). Pekarvariabler kan sedan ges värden i form av adresser. Ex: Definiera en flyttalsvariabel och en pekarvariabel som kan peka på flyttal. Tilldela flyttalet värdet 56.7 och tilldela pekaren adressen för detta flyttal. Ändra sedan flyttalets värde med hjälp av pekaren till 23.4. double f; f odefinierat double *fp; fp odefinierat f = 56.7; f 56.7 fp = &f; fp *fp = 23.4; f 23.4 *fp fp OBS! Avreferering av pekaren med *fp, för att komma åt det som pekaren pekar på. 23

Man kan naturligtvis definiera pekare att peka på andra typer av data. Man kan till och med definiera pekare att peka på vilken typ av data som helst, nämligen void pekare. Ex: Definiera två tecken samt två pekare som sätts att peka på dessa tecken. Tilldela sedan med hjälp av pekaren det första tecknet till det andra och därefter det första pekarvärdet till det andra pekarvärdet. char c1 = A ; c1 A char c2 = B ; c2 B char *cp1 = &c1; cp1 char *cp2 = &c2; cp2 /* Tilldela tecken */ c1 A *cp2 = *cp1; c2 cp1 A cp2 /* Tilldela pekarvärden */ c1 A cp2 = cp1; c2 cp1 A cp2 24

Pekare använder man exempelvis då man ska förändra värdet på en aktuell parameter med en funktion. Ex: Skriv ett program som läser in ett heltalsvärde och skriver ut talet kvadrerat. Kvadreringen ska utföras av en void funktion som tar talet som parameter och förändrar talet genom att kvadrera det. #include <stdio.h> void kvadrera(int *tp) *tp = (*tp) * (*tp); tp int main() int tal; printf( Ge ett tal : ); scanf( %d, &tal); kvadrera(&tal); tal *tp printf( Talet kvadrerat : %d\n, tal); return 0; OBS!Vid anropet skickas adressen för tal till funktionen som tar emot med en pekare. I funktionen har man nu tillgång till den aktuella parameterns minnesutrymme via pekaren. OBS! Då man, som ovan, enbart ska returnera ett enda värde är det bättre att använda en int funktion som returnerar det kvadrerade talet. Då man använder funktionsvärdet som informationsöverförare slipper man också ifrån nackdelen att den aktuella parameterns värde förändras efter anropet. Denna typ av sidoeffekt är oftast ej önskvärd. 25

Vektorer och strängar är inga vanliga variabler utan kan hellre ses som konstanta adresser eller konstanta pekarvärden. Har man vektorer eller strängar som aktuella parametrar ska man alltid ta emot dessa formellt som pekare. Ex: Skriv ett program som läser in en sträng och som byter ut alla stora bokstäver till motsvarande små. #include <stdio.h> #include <string.h> void smastr(char *sp) int i; sp for (i = 0; i < strlen(sp); i++) if ( sp[i] >= 'A' && sp[i] <= 'Z') sp[i] = sp[i] + 32; int main() char str[80]; str printf( Ge sträng : ); gets(str); smastr(str); h e j sp[0] printf( Strängen : %s \n, str); return 0; \0 OBS!Indexering av pekaren sp som egentligen är en pekaruppräkning. Exempelvis kommer man åt det andra tecknet i strängen med indexeringen sp[1] eller alternativt med avrefereringen *(sp + 1). Pekaruppräkningen lägger automatiskt till det antal byte som gäller för den datatyp som den aktuella pekaren är definierad att peka på. (Men kom ihåg att man egentligen bör undvika funktionen gets, eftersom den inte kollar att den inlästa strängen får plats i variabeln! Använd fgets i stället. Dessutom vill man kanske titta lite på funktionen tolower, som finns i standardbiblioteket.) 26

2.2 Dynamiska variabler För variabler som definieras på vanligt sätt, exempelvis inuti en funktion som main, reserveras det minnesutrymme för automatiskt direkt vid definitionen. Det finns ett annat sätt att reservera eller allokera minnesutrymme, där man som programkonstruktör själv bestämmer när och hur mycket minne som ska reserveras. Dessa variabler eller minnesutrymmen som är mer flexibla, kallas dynamiska variabler. När det gäller att ge tillbaka det reserverade minnesutrymmet gäller motsvarande. Vanliga variabler avallokeras alltid vid funktionens slut, medan de dynamiska avallokeras av programmet när de ej behövs längre. Ex: Allokera två reella variabler den första automatiskt och den andra dynamiskt. Tilldela dessa sedan värden samt skriv ut summan av dessa värden. double f ; f odefinierat double *fp; fp odefinierat f = 3.4; f 3.4 /* Allokera minne */ fp = malloc(sizeof(double)); fp *fp = 2.3; 2.3 printf( Summan = %f, f + (*fp)); /* Avallokera minne*/ free(fp); fp odefinierat OBS! För att allokera minne dynamiskt måste man först definiera en pekare, som man sedan sätter att peka på det allokerade minnet. Eftersom detta minne är anonymt, dvs saknar namn, måste man alltid använda denna pekare för att komma åt detta minne. OBS! Funktionen malloc finns i stdlib.h. Den tar antalet byte som ska allokeras som parameter och returnerar en void pekare. Denna pekare omvandlas ovan automatiskt till en double pekare vid tilldelningen. Vissa kompilatorer kräver en explicit typomvandling enligt: 27

fp = (double *)malloc(sizeof(double)); Efter avallokeringen eller frigörandet av minne kommer pekaren att ha ett odefinierat värde, vilket innebär att den kan peka på ett förbjudet minnesområde. Därför är det alltid säkrast att se till att pekare har väl definierade värden då man skapar dem eller då man frigör minne som de pekar på. Det finns ett sådant väl definierat konstant värde, nämligen värdet, som också finns i stdlib.h. I exemplet ovan ska man använda detta värde, då man definierar pekarvariabeln och då man avallokerar minne enligt: double *fp = ; fp...... /* Avallokera minne*/ free(fp); fp odefinierat fp = ; fp Funktionen malloc som allokerar minne returnerar ett pekarvärde till det allokerade minnet. Misslyckas allokeringen av minne, vilket exempelvis inträffar då minnet är slut, returnerar malloc värdet. Detta kan man testa på efter allokeringen enligt: fp = malloc(sizeof(double)); if (fp == ) /* Kunde ej allokera */; else /* Gick bra */; Har man odefinierade pekare i sitt program är det lätt att man skriver över väsentliga delar av minnet och datorn hänger sig. Se till att alltid ha väl definierade värden på alla pekare i programmet. Väl definierade pekare får man genom att tilldela dessa värdet eller tilldela dessa adresser för variabler eller dynamiskt allokera minne. Regel : Se alltid till att ha väl definierade pekare i programmet. Har man inget annat värde, ger man pekarna värdet. 28

Man kan naturligtvis tilldela en pekare värdet av en annan pekare. Här bör man också se upp eftersom man först tappar det minnesutrymme som den vänstra pekaren pekar på och sedan får två pekare att peka på samma minnesutrymme. /* Allokera minne */ fp1 = malloc(sizeof(double)); fp1 *fp1 = 2.3; 2.3 fp2 = malloc(sizeof(double)); fp2 *fp2 = 4.5; 4.5 /* Pekartilldelning */ fp1 2.3 fp2 = fp1; fp2 4.5 OBS! Minnesutrymmet som innehåller talet 4.5 har man tappat bort. Man kan inte komma åt detta mer under programmets gång. Minnet är dock fortfarande upptaget. Detta är ett fel som medför att programmet äter minne. OBS! Frigör man minne, som två pekare pekar på, med hjälp av den ena pekaren som man sedan ställer har man fortfarande kvar en pekare som pekar på otillåtet (redan avallokerat) minne. OBS! Skillnaden mellan tilldelning av reella tal och mellan pekare *fp2 = *fp1; fp2 = fp1; 29

Man kan naturligtvis allokera minne dynamiskt även för sammansatta datatyper som strängar, vektorer och poster. Ex: Allokera två strängar som maximalt kan innehålla 4 tecken (plus strängavslutningstecknet). Den första ska allokeras automatiskt och initieras. Den andra ska allokeras dynamiskt och sedan ska den första strängens värde kopieras över till denna. Slutligen skrivs den andra strängen ut på skärmen. #include <stdio.h> #include <string.h> #include <stdlib.h> int main() char astr[5] = Hej! ; astr H e j! \0 char *dstr = ; dstr dstr dstr = malloc(5*sizeof(char)); strcpy(dstr, astr); H e j! \0 puts(dstr); free(dstr); dstr dstr = ; OBS! Istället för att använda malloc kan man använda calloc enligt: dstr = calloc(5, sizeof(char)); Här nollställs också minnesutrymmet automatiskt. (Egentligen är sizeof(char) onödigt, för det är alltid 1, enligt C standarden. Storlekar mäts alltså egentligen i char platser, och inte i bytes! Men man kan ha med det för tydlighets skull.) 30

Ex: Skriv ett program som läser in hur många reella tal som ska läsas in till en vektor, allokerar utrymme för denna vektor dynamiskt samt läser in värden och skriver ut medelvärdet. #include <stdlib.h> #include <stdio.h> int main() int nr, i; double *vek =, sum = 0.0; /* Läs in antal element */ printf( Ge antalet element : ); scanf( %d, &nr); /* Allokera vektor med nr st element */ vek = calloc(nr, sizeof(double)); /* Läs in vektorelementen */ for (i = 0; i < nr; i++) printf( Ge vek[%d]:, i); scanf( %lf, &vek[i]); /* Addera elementen i vektorn */ for (i = 0; i < nr; i++) sum += vek[i]; /* Skriv ut medelvärdet */ printf( Medelvärdet = %f\n, sum / nr); /* Frigör minne */ free(vek); vek = ; return 0; Här kan man inte skapa vektorn automatiskt eftersom man inte vet hur många element man ska ha i vektorn innan programmet körs. Därför definierar man först en pekare och, när man vet hur många element vektorn ska innehålla, skapar man dynamiskt utrymme för denna vektor. Man kunde naturligtvis ha tagit till lite extra och definierat en vektor automatiskt med exempelvis 1000 element. Den dynamiska modellen sparar dock minne eftersom man bara allokerar upp så mycket minne som man för tillfället verkligen behöver. 31

Ex: Skapa två poster för medlemmar med medlemsnummer och namn. Den första ska skapas automatiskt (statiskt) och den andra dynamiskt. Initiera den första posten med lämpliga värden samt tilldela dessa sedan till den andra posten och skriv ut den andra postens termer. struct medlem int nr; char namn[30]; ; struct medlem m1 = 123, O.Persson ; m1.nr m1.namn m1 123 O.Persson struct medlem *mp = ; mp mp = malloc(sizeof(struct medlem)); *mp = m1; mp mp >nr mp >namn *mp 123 O.Persson printf( Nummer : %d\n, mp >nr); printf( Namn : %s\n, mp >namn); OBS! För att avreferera hela posten används på vanligt sätt *mp. För att komma åt enskilda termer i posten, som exempelvis medlemsnummer, kan man skriva (*mp).nr eller kortare med piloperatorn mp >nr. 32

Poster kan länkas ihop till en kedja i minnet om man sätter in en extra term i posten i form av en pekare till nästa post. Ex: Skapa två poster av medlemmar som är ihoplänkade så att den första pekar på den andra. struct medlem int nr; char namn[30]; struct medlem *next; ; struct medlem *mp = ; mp = malloc(sizeof(struct medlem)); mp mp >nr = 234; strcpy(mp >namn, E.Karlsson ); 234 E.Karlsson mp >next = malloc(sizeof(struct medlem)); mp >next >nr = 235; strcpy(mp >next >namn, P.Larsson ); mp >next >next = ; 235 P.Larsson OBS! Strängkopiering med strcpy. OBS! Termen next som är en pekare till samma posttyp, som den ingår i. Ovanstående definition är tillåten även om man tycker att struct medlem ej är definierad innan man använder den för att definiera next. OBS! Har man en pekare i sin post som kan sättas att peka på en ny post av samma typ kan man länka ihop posterna till en kedja. För att detta ska fungera för flera poster måste man dock använda någon annan metod än ovanstående, något begränsade metod. 33

2.3 Länkade strukturer För att avbilda datastrukturer som köer, träd mm på ett dynamiskt sätt, använder man sig av poster med pekare som i sin tur pekar på nästa post osv. Man behöver aldrig allokera mer minne än vad som för tillfället behövs för exempelvis en kö. När det dyker upp en ny person som ska stoppas in i kön, allokerar man bara upp nytt minne och placerar in personen i kön. Ex: Skissa på ett program som läser in data till medlemsposter innehållande nummer och namn och länkar ihop posterna med hjälp av en pekare till nästa post. /* Definiera data */ struct medlem int nr; char namn[30]; struct medlem *next; ; struct medlem *lista =, *temp = ; /* Skapa den första medlemmen */ temp = malloc(sizeof(struct medlem)); temp >nr = 100; strcpy(temp >namn, A.Ason ); temp >next = ; /* Sätt lista att peka på den första posten */ lista = temp; Läget är följande: temp lista 100 A.Ason Eftersom man nu har två pekare som pekar på samma post kan man fortsätta med att allokera upp nytt minne för nästa post med hjälp av pekaren temp. Eftersom pekaren lista finns, tappar man ej bort den första posten. 34

/* Skapa en ny medlem */ temp = malloc(sizeof(struct medlem)); temp >nr = 200; strcpy(temp >namn, B.Bson ); temp >next = ; Läget är nu följande: temp 200 B.Bson lista 100 A.Ason Hur ska man göra för att länka ihop listan? /* Länka ihop */ temp >next = lista; lista = temp; Nu har listan länkats ihop enligt: temp 200 B.Bson lista 100 A.Ason 35

Ovanstående länkade struktur blir en lista av samma typ som en tallriksstapel. Man lägger på tallrikar på varandra och kommer bara åt den översta direkt. Man kan stoppa in nya länkar (tallrikar) i listan med en loop, där man läser in data enligt: /* Skapa en länkad medlem */ /* Läs nytt medlemsnummer */ printf( Ge nr ( Avslut 0 ) : ); scanf( %d, &tal); while ( tal!= 0 ) /* Skapa en ny medlem */ temp = malloc(sizeof(struct medlem)); temp >nr = tal; getchar(); printf( Ge namn : ); gets(temp >namn); /* Länka ihop med föregående */ temp >next = lista; lista = temp; /* Läs nytt medlemsnummer */ printf( Ge nr ( Avslut 0 ) : ); scanf( %d, &tal); OBS! Ihoplänkningen som även kan användas för en tom lista om lista initierats till. Efter inläsning av ytterligare två medlemmar ser listan ut som: lista 400 300 200 D.Dson C.Cson B.Bson 100 A.Ason 36

Vill man ha en utskrift av alla länkar i listan börjar man med att skaffa sig en temporär pekare, som man sätter att peka på den första länken. Sedan kan man stega framåt i listan och skriva ut varje länk. /* Skriv ut listans data */ temp = lista; while ( temp!= ) printf( \nmedlemsnr : %d\n, temp >nr); printf( Medlemsnamn : %s\n, temp >namn); /* Flytta till nästa länk */ temp = temp >next; Pekaren temp används som en iterator, för att skriva ut alla länkar i listan. Då temp vid uppräkningen tilldelas värdet, vilket inträffar då den sista länkens temp >next tilldelas, har man skrivit ut hela listan. temp lista 400 300 200 D.Dson C.Cson B.Bson 100 A.Ason OBS! Använd ej pekaren lista för att flytta framåt i listan för då tappar man bort början på listan! 37

Man kan söka efter en medlem i listan på motsvarande sätt som när man skriver ut listan. Man har en temporär pekare som man flyttar framåt i listan så länge man inte hittat medlemmen och listan inte slut. int snr, hittat = 0; /* Läs in medlemsnummer som ska sökas */ printf( Ge medlemsnummer : ); scanf( %d, &snr); /* Sök i listan */ temp = lista; while ( temp!= &&!hittat ) if ( snr == temp >nr ) /* Hittat länken */ hittat = 1; else /* Flytta till nästa länk */ temp = temp >next; /* Skriv ut sökresultat */ if ( hittat ) printf( Medlemsnamn : %s\n, temp >namn); else printf( Medlemmen finns ej i listan!\n ); Läser man exempelvis in medlemsnumret 300 stannar sökningen med temp pekande på länken: temp lista 400 300 200 D.Dson C.Cson B.Bson 100 A.Ason och C.Cson skrivs ut. 38

Vill man stoppa in nya medlemmar i listan på speciella ställen efter en länk söker man sig fram i listan länk för länk, skriver ut medlemsnumret och frågar om instoppning ska ske efter länken. Ska instoppning ske skapar man en ny medlem, läser in data till den och stoppar in den i listan enligt: slask 250 temp BC.Bcson lista 400 300 200 D.Dson C.Cson B.Bson 100 A.Ason struct medlem *slask; char svar; /* Sök dig fram i listan */ temp = lista; while ( temp!= ) printf( Medlem nr : %d\n,temp >nr); printf( Ska du länka in (J/N)? ); svar = toupper(getchar()); getchar(); if ( svar == J ) slask = malloc(sizeof(struct medlem)); printf( Ge medlemsnummer : ); scanf( %d, &slask >nr); getchar(); printf( Ge medlemsnamn : ); gets(slask >namn); /* Stoppa in länken */ slask >next = temp >next; temp >next = slask; temp = temp >next; OBS!Man måste ställa om pekarna i rätt ordning annars kan man tappa bort resten av listan. Innan man ställer om temp >next att peka på slask måste man sätta 39

slask >next att peka på temp >next. Vill man ta bort en medlem från listan kan man på motsvarande sätt leta sig fram i listan till aktuell medlem och sedan plocka bort denna enligt: slask temp lista 400 300 200 D.Dson C.Cson B.Bson 100 A.Ason temp = slask = lista; while ( temp!= ) printf( Medlem nr : %d\n,temp >nr); printf( Ska du ta bort (J/N)? ); svar = toupper(getchar()); getchar(); if ( svar == J && temp == lista) /* Första medlemmen ska bort */ slask = lista = lista >next; free(temp); temp = lista; else if ( svar == J ) /* Medlem inuti listan ska bort*/ slask >next = temp >next; free(temp); temp = slask >next else /* Medlemmen ska ej bort */ slask = temp; temp = temp >next; OBS! Hur man måste skilja på att ta bort den första medlemmen jämfört med resten av medlemmarna. 40