Föreläsning 6, F.Bergholm • Alla professionella programmerare använder debug. (Utom det lilla fåtal som tycker om att göra massvis med kontrollutskrifter). Detta gäller stora program, halvstora program , icke-triviala algoritmer. Samt svåranalyserade fel i små program. • I små enkla program duger ofta kontrollutskrifter. • Vanligt debugprogram: gdb • (BRYTPUNKT) Stanna programmet på viss rad och titta på variablerna. • (STEGA RAD FÖR RAD) Kör en rad i taget och titta på vad som händer med variablerna Vanliga kommandon i en debugger är: r c s b 9 p x (=run) (=continue) (=gå en rad till) (=stanna på rad 9 (t.ex)) (=skriv ut variabeln x) • (Rad för rad) En debugger (ett felsökningsprogram) går vanligtvis rad för rad med s-kommandot (s=step) utan att gå in i funktioner. Om man vill gå in i funktioner finns n-kommandot . • (Brytpunkt i funktion) Istället för att ha en brytpunkt på en rad kan man ange vilken funktion man vill stanna i. Typiska varianter på de vanligaste kommandona (b,p,r,c,s), är i gdb: info local (=lista alla lokala variabler) b n b b 17 if n == 10 (=gå in i funktion,step inside) main (=stanna i main) foo (=stanna i funktion foo) För att starta debug med gdb måste man kompilera: gcc -g program.c -o program Därefter kör man exe-filen med gdb: gdb program.exe (Det beror på att felsökningsprogram behöver inte bara maskinkod utan ytterligare information, en specialkompilering (Option: -g) krävs.) (gdb) b 9 (gdb) r (gdb) info local a= 3, area=7 antal=16 (gdb) s (gdb) s (gdb) p antal antal=17 (gdb) c Program exited with 0 (gdb) quit (gdb) l 1 #include <stdio.h> 2 int main() { 3 printf(”Hej\n ”); 4 return 0; 5} (gdb) b 3 (gdb) r osv…. Man listar med kommandot ”l” (litet L), eller ”l 10”, som betyder lista de 10 kommande raderna. Rött är gdb:s utskrift. Grundide: Lägg in alla heltal i en lång vektor genom att markera med 1 vilka tal som ska sorteras. (Vektorarrayen är initierad med nollor.) int v[100]={0}; Sortera talen: 5,3,10,9 V= 0 0 1 0 1 0 0 0 1 1 0… En for-slinga behövs för att lägga in heltalen (=ettorna) i arrayen v. Ytterligare en for-slinga behövs för att ta i tur och ordning de tal som inte är noll i arrayen. Gör man det, blir talen automatiskt sorterade (skiss): if (v[i] != 0) res[j++]= i; Ett idiom är ett invant mönster (som man använder vid C-programmering) av säkerhetsskäl. Exempel: Stega alltid från noll till i< längden av arrayen, i en for-slinga. Då kommer man inte UTANFÖR arrayen. Om (King, s.163 )man kommer utanför en array kan vad-som-helst hända.) int for v[125]; (i=0, i< 125; ++i) SKRIV INTE for (i=0; i <=124; ++i) for (i= 1; i <=125; ++i) • Läs F6debug.pdf. Läs F6debugBeskrivning.pdf. • Läs F5_6checklista.pdf noga., och testa att med flit göra de fel som nämns. Testa speciellt ”blankfällan” dvs att i scanf skriva ”%d ” med ett blanktecken efter d:et, dvs ”%d ”. • * Programmera själva pigeon hole-uppgift (finns efter denna sida) • * Gör utdelad övning på idiom (finns efter denna sida) • *Gör en funktion platsbyt(&a,&b,&c) som byter plats på värdena så att a får b:s värde, b får c:s värde och c får a:s värde,där vi antar att variablerna är deklarerade double a,b,c i main(). • Repetera Förel. 1-5, och gör övningar du missat. Testa debug! Det underlättar i labbarna • Gör debug på Isdans-poängprogrammet. (se nästa sida) #include <stdio.h> int poang[4][8]= {{4,5,4,4,5,4,4,3}, {4,4,4,4,4,4,4,4}, {4,5,5,5,5,5,5,5}, {5,4,3,4,3,5,3,2}}; double beraknaPoang(int par[], int antal); int main() { int i=0; int antal; //antal domare int par[]; double res=0; for (i=0; i<4; ++i) { par= poang[i]; res= beraknaPoang(par,antal); printf(”slutpoang= %f \n”,res); } return 0; } /*end main*/ /* *************************** Funktionen beraknapoang() ***************************/ double beraknaPoang(int par[], int antal) double max,min,summa=0; int j=0; for (j=1;j<antal; ++j) { summa= summa+ par[j]; if (par[j]>max) max= par[j]; if (par[j]<min) min= par[j]; } return (summa-max-min)/(antal-2); } Uppg.1 Gör en for-loop som printar ut innehållet i vektorn double varden[5]={1,1.5,1.75,1.875,1.9375}; Uppg.2 Gör 2 dubbelloopar (for) för matrisen (matrisarrayen) int schack[8][8], Fyll den med varden, bonde=1,torn=2,springare=3,dam=4,kung=5. tom=0, och skriv ut matrisen. Uppg.3 Gör en for-loop som kastar tärning med rand(). Uppg.4 Gör en while-slinga som läser förbi nollor i en pigeon-hole vektor. (Idiomet är att ha en tom sats i while-slingan.) Uppg.5 Använd ++-operatorn inuti en indicerad variabel i en slinga. Du ska först hämta värdet, sedan inkrementera index (dvs öka med 1). UPPG: Slumpa tal mellan 1 och 100, men släng bort tal som sammanfaller, och sortera dem med pigeon holemetoden. Man ska slumpa 50 gånger. TIPS: Använd vektorn int v[100] för att lagra nollorna och ettorna i. Och det är smart att lagra nollor och ”antal förekomster” istället för ettor. TIPS: När man slumpar med rand(),som tal%100, får man tal mellan 0 och 99. Man förskjuter detta till 1 och 100, på enklaste sätt. (Detta är också ett idiom.)