GPT föreläsning 8 Förra veckan: Man kan ta tiden på en sorterad teckensträng Förra gången: Problemlösning på lägre nivå kan sortera funktioner Denna gång Reflektioner kring OU1 Funktioner
Reflektioner kring OU1 Goto är en del av C Att använda goto anses dock inte vara god programmeringsmetodik Det blir givetvis enbart en gradskillnad mellan att använda goto å ena sidan och break och continue å andra sidan man lär sig inte använda de mer naturliga konstruktionerna i språket: if-, while- och forsatser Vi har beslutat att på OU3 kommer det att ge O om man använder villkorliga styrningar av programflödet (dvs goto, break och continue). Break i switch-satsen undantaget På OU1 och OU2 kommer goto att ge K och man skall kunna motivera varför goto är motiverat Nackdelarna med goto är det blir svårt att förstå flödet i programmet det blir svårt att se vilken kontext vi hamnar i vid hopp kompilatorn får oerhörda problem att generera bra kod
Reflektioner kring OU1 Tänk också på att det kommer individuell programmeringstenta och teoritenta Till dessa uppgifter kommer det inte att finnas facit
Funktioner En egendefinierad funktion kan ligga före eller efter mainfunktionen Om funktionen ligger efter main måste vi även lägga en funktionsdeklaration före main Detta för att kompilatorn ska veta vad funktionen skall ha för argument och vad den returnerar int sum(int a, int b); int main(void){ int a=1,b=2,c; c=sum(a,b); return 0; int sum(int a, int b){ return a+b;
Funktioner Om du vill använda din funktion i flera olika program är det lämpligt att lägga den i en egen fil Filen med funktionen/ funktionerna ges ändelsen.c Denna fil skall inte ha något main-funktion För att kompilatorn skall kunna kompilera måste du skapa en fil som endast innehåller funktionsdeklarationen Denna fil ges ändelsen.h I din programfil måste.h-filen inkluderas Detta görs med #include Vid kompilering anger du namnet på alla.c-filer som innehåller kod som du vill ha med i det slutliga programmet
sum.c sum.h int sum(int a, int b){ return a+b; int sum(int a, int b); prog.c #include<stdio.h> #include sum.h peppar>gcc Wall prog.c sum.c o prog peppar>./prog 5 int main(void){ printf( %d,sum(2,3)); return 0;
Funktioner En funktion kan givetvis vara utan formella parametrar En funktion behöver inte heller returnera något void PrintHej(void){ time_t t[1];struct tm *timeinfo; time(t);timeinfo=localtime(t); int hour=timeinfo->tm_hour; switch(hour){ case 21: case 22: case 23: case 0: case 1: case 2: case 3: case 4: printf("god natt");break; case 5: case 6: case 7: case 8: case 9: printf("god morgon");break; case 10: case 11: case 12: case 13: printf("god middag");break; case 14: case 15: case 16: case 17: printf("god eftermiddag"); break;
Funktioner Vi definierar formella parametrarna till en funktion De parametrar som skickas till funktionen vid anrop kallas aktuella parametrar De aktuella parametrarna kan utgöras av uttryck Uttrycket evalueras i så fall innan anropet sker Vilken aktuell parameter som knyts till vilken formell parameter styrs enbart av ordningen i anropet och deklarationen int sum(int a, int b){ return a+b; int main(void){ int a=3,b=2,c; /*Alla anrop ger samma svar*/ c=sum(5,3); c=sum(a+b,3); c=sum(a+2,3); c=sum(a+b,a) c=sum(a+b++,b);
Funktioner Det finns inget som hindrar att en funktion anropar andra funktioner En funktion kan till och med anropa sig själv Detta kallas rekursion För att rekursionen skall terminera, dvs avslutas, måste det finnas stoppvilkor Varje rekursivt anrop måste ta oss ett steg närmare stoppvilkoret
Rekursion vs. iteration Rekursion är ett sätt att uttrycka iteration, dvs en kontrollerad upprepning av satser I en del språk (som ML, Prolog, Lisp) är rekursion den enda formen av iteration I en del språk (som Fortran 77) kan man inte skriva rekursiva funktioner Fördelar med rekursion är att det ofta blir eleganta, kompakta lösningar det lämpar sig oerhört väl för problem som är rekursiva i sin natur, tex att söka information i ett träd Nackdelar är ineffektivitet, vid varje funktionsanrop skall en massa data sparas undan etc. olämpligt för applikationer som tex servrar som skall iterera för alltid
Våra första C-program (12) Skriv en rekursiv funktion som beräknar fakulteten för ett tal. Fakulteten för n definieras som n! = 1*2*3* *(n-1)*n
Variablers räckvidd En variabel som deklareras i ett block är lokal i det blocket Den deklarerade variabeln gäller från deklarationen och neråt i blocket Om en variabel deklareras utanför alla block i början av filen blir den global Om samma variabelnamn använts på flera nivåer gäller den deklaration som ligger närmast det block där variabeln används Den mest lokala deklarationen slår alltså ut den mer globala
Variablers räckvidd #include<stdio.h> int a=1; void f1(int a){ printf( %d,a); void f2(void){ printf( %d,a); peppar>./test 1312 void f3(void){ int a=2; printf( %d,a); int main(void){ f1(a); int a=3; f1(a); f2(); f3();
Våra första C-program (13) Skriv en funktion som omvandlar valutor. Funktionen skall ha följande deklaration. float = valutaomvandling(float intotal, char from, char to) Där tecknen from och to kan vara k kr, e euro och d US. dollar. Använd kurserna (forex 23/11): 100 kr ger 9,52 euro 100 kr ger 11,91 dollar Skriv ett main-program som testar funktionen
Sammanfattning Sammanfattande nyckelord: rekursion, h-filer, funktioner, scope Sammanfattande mening: Rekursiva funktioner som läggs in externa filer har stor räckvidd