Framsidan Framsidan på din labrapport kan du utforma ganska fritt. Tänk bara på att den ska vara läsbar, och innehålla (minst) följande information: Ditt namn Din e-mail adress här på CS! Kursens namn samt vilken termin det är (t.ex. ht05) Vilken laboration det är Handledarens/handledarnas namn Datum Vilken inlämning det är (första/andra/uppsamling etc.) Lämna plats för kommentarer Innehållsförteckning Innehållsförteckningen ska innehålla alla rubriker i rapporten, och eventuellt en del underrubriker, beroende på hur rörigt det blir. Tänk på att innehållsförteckningen inte bör vara listad i innehållsförteckningen 207 208 Åtkomst & användarhandledning Kan ibland delas upp i två avdelningar Hur kan handledaren komma åt din lösning för testning, alltså sökvägen till din källkod och ditt program. Hur används programmet Hur ska handledaren gå tillväga för att kompilera din källkod. Om din kod kräver att någon option till kompilatorn anges, bör du nämna det här. Problemspecifikation Beskriver med egna ord vad uppgiften gick ut på. Systembeskrivning Beskriv datatyper som du själv skapat. Hur de ser ut, varför du valde att skapa dem på just det sättet etc. Beskriv anropsstrukturen för programmet, helst med en bild som visar de olika funktionerna i programmet, och pilar mellan dem som visar vilka funktioner som anropar vilka. Lista alla funktioner i ditt program, och för varje funktion beskriv vilka argument den tar, vad den returnerar, dess syfte 209 210 Exempel Funktionshuvud: boolean print_file(string fil_namn) Syfte: Skickar iväg filen fil_namn till skrivaren. Argument: string fil_namn - en sträng som innehåller namnet på filen som ska skrivas ut. Returnerar: boolean - ett boolskt värde som är true om allt gick bra och false om något gick snett. Kommentar: Filnamnet får inte vara längre än 50 tecken. Är namnet längre, kommer funktionen inte att skicka filen till skrivaren, utan istället avbryta och returnera false. 211 Algoritmbeskrivning Om du har använt några icke självklara algoritmer, t.ex. en sorteringsalgoritm, en sökalgoritm eller något annat, ska du beskriva den/dem här. Lösningens begränsningar Kraschar ditt program om användaren trycker på en viss tangent? Klarar ditt program inte av något som specificerades i laborationsspecifikationen? Tro inte att labrättaren missar eventuella fel/begränsningar. 212 1
Problem och reflektioner Stället där du kan skriva "vad som helst". Vad du tyckte om laborationens svårighetsgrad, Hur handledningen fungerat Hur bra datorerna fungerat Vilka problem som uppstått under arbetets gång Om du haft nog med tid etc. Tack. Om du fått mycket hjälp av någon (kurskamrat, handledare, mamma), kan det vara på sin plats att tacka denne i rapporten. Testkörningar Du måste testa din lösning innan du lämnar in den. För att visa att du gjort det, och för att ge handledarna ett snabbt sätt att kontrollera att din lösning ser OK ut så bifogar man testkörningarna i rapporten. Tänk ut vettiga testfall. Vad kan tänkas vara svårt för programmet? Kommentera testfallen. Varför valde du detta testfall? Blev resultatet som det var meningen att det skulle bli? 213 214 Källkod Källkod skall finnas med i rapporten Kan antingen infogas i rapporten, eller bifogas som bilaga. Oftast är det bäst att skriva ut koden separat och bifoga som bilaga, eftersom ordbehandlare har en tendens att misshandla källkod ganska rejält vad gäller indentering, stavning etc. Källkoden ska vara utskriven med ett ickeproportionellt typsnitt, t.ex. Courier. Övrigt Sidhuvud och sidfot. Använd dessa, men ha inte för mycket information i dem. I sidhuvudet kan du t.ex. ha ditt namn, datum, kursens namn och vilken laboration det är. I sidfoten kan du ha sidnumret. Tänk på att förstasidan inte bör vara numrerad eller ha samma sidhuvud som resten av rapporten. Läs igenom rapporten innan ni lämnar in den! 215 216 Preprocessorn Preprocessorn evaluerar speciella direktiv i koden innan koden kompileras. Rader med preprocessordirektiv börjar med en #. Preprocessorn utför inkludering av filer, villkorlig kompilering och expansion av makron. Rader med preprocessordirektiv kan förekomma var som helst i koden. Filinkludering Inkludering av filer utförs med #include. Standardfiler Standardfiler anges inom < och > varefter preprocessorn söker på ett antal fördefinierade ställen. #include <tcp.h> Användarfiler Användarfiler anges inom " varefter preprocessorn letar i den aktuella katalogen. #include "list.h" #include "matrix.h" 217 218 2
Filinkludering Raden med preprocessordirektivet byts ut mot en kopia av filen vilket kan vara av intresse om det finns beroenden mellan filer som inkluderas. Filinkluderingar kan vara nästlade, d.v.s filer som inkluderas kan själv inkludera filer. Makron och konstanter Makron kan användas till att definiera konstanter och öka tydligheten och portabiliteten av kod. Ett makro definieras med #define. #define identifier token_string Preprocessorn byter ut alla förekomster av identifier mot token_string i koden. #define MAX_STR_LEN 50 #define EPS 2.2204e-16 #define EQ == Det finns inga begränsningar i vad som kan definieras som makron. 219 220 Makron med argument #define identifier(identifier,, identifier) token_string Efter en deklaration #define max(x,y) ((x)>(y)? (x) : (y)) blir uttrycket c = max(a+1,b-1); expanderat av preprocessorn till c = ((a+1)>(b-1)? (a+1) : (b-1)); Vanliga fel Utan parenteser #define SQ(x) x*x c = SQ(5 + 1); blir expanderat av preprocessorn till c = 5 + 1 * 5 + 1 ; /* == 11 och ej 36 */ Semikolon och lika med #define add = + #define A 3; c = b add A-5; blir expanderat av preprocessorn till c = b = + 3; -5; 221 222 Fler vanliga fel Funktionsargument Vad blir nämligen egentligen detta? #define MAX(x,y) ((x) > (y)? (x) : (y)) int give_next() { static int d = 2; d++; return d;.. MAX(3, give_next()) Villkorlig kompilering #if constant_integer_expression #ifdef identifier #ifndef identifier #elif #else Portabel kod Debug utskrifter Undvika att inkludera filer flera gånger 223 224 3
Villkorlig kompilering Debugutskrifter: #define DEBUG 1 #if DEBUG printf("debug: a = %d\n", a); eller #define DEBUG #ifdef DEBUG printf("debug: a = %d\n", a); Bryta upp kod i moduler Hålla samman relaterade funktioner Lättare felsökning Lättare att bygga ut. 225 226 Headerfiler: Filinkluderingar Typdeklarationer Definitioner, makron Funktionsprototyper Källkodsfil: Filinkluderingar Funktioner 227 temp.h #ifndef TEMP_H #define TEMP_H #include <stdlib.h> #define CK_ADJUST 273.15 #define CF_SCALE 1.8 #define CF_ADJUST 32 typedef double celsius; typedef double kelvin; typedef double farenheit; kelvin celsius_to_kelvin (celsius); farenheit celsius_to_farenheit (celsius); celsius farenheit_to_celsius (farenheit); kelvin farenheit_to_kelvin (farenheit); celsius kelvin_to_celsius (kelvin); farenheit kelvin_to_farenheit (kelvin); 228 temp.c #include temp.h kelvin celsius_to_kelvin(celsius c) { return (kelvin)(c - CK_ADJUST); farenheit celsius_to_farenheit(celsius c) { return (farenheit)((c * CF_SCALE) + CF_ADJUST); celsius farenheit_to_celsius(farenheit f) { return (celsius)((f - CF_ADJUST)/CF_SCALE); makefile Används för att underlätta kompileringen Specificerar beroenden mellan filerna och hur de ska kompileras Körs med komandot make Obs! Börja inte rader med mellanslag Ex Makefile: complex_test: complex.o complex_test.o gcc -o complex_test complex.o complex_test.o complex.o: complex.c complex.h gcc -c complex.c complex_test.o: complex_test.c complex.h gcc -c complex_test.c clean: rm -f *.o complex_test 229 230 4
Makron i stdio.h int getchar(); int putchar(int c); Returnerar: c vid OK, annars EOF getchar läser ett tecken från tangentbordet. putchar skriver ett tecken till skärmen. Makron i ctype.h Makron för teckenhantering. #include <ctype.h> int isalpha(int c); 0 om c är en bokstav int isupper(int c); 0 om c är en stor bokstav int islower(int c); 0 om c är en liten bokstav int isdigit(int c); 0 om c är en siffra int isspace(int c); 0 om c är ett vitt tecken int toupper(int c); motsvarande stora bokstav eller c int tolower(int c); motsvarande lilla bokstav eller c 231 232 Skriva eller läsa enskilda tecken Motsvarigheten till getchar och putchar heter för filer getc och putc. int putc(int c, FILE *stream); Returnerar: värdet av c. EOF vid filslut eller fel. int getc(file *stream); Returnerar: Nästa tecken från strömmen. EOF vid filslut eller fel. Dessa anrop sker genom makron. Det finns också litet långsammare funktionsvarianter av dessa som heter fputc och fgetc. Exempel Observera att dessa två satser är ekvivalenta och att man inte kan öppna eller stänga stdout. fprintf(stdout, "Detta skrivs till skärm\n"): printf("detta skrivs till skärm\n"): Liksom att dessa tre satser är ekvivalenta. putc( a, stdout); fputc( a, stdout); putchar( a ); 233 234 5