Funktioner
Biblioteksfunktioner Top-down design Funktioner Något om konstanter I dag
Ett program #include <stdio.h> int main(void) { double x, result; /* Läs in ett tal från användaren */ printf("skriv in ett tal > "); scanf("%lf",&x); /* Beräkna sinus */?????; /* Skriv ut vad som beräknats och resultatet */ printf("sin(%f) = %f\n", x, result); return 0;
Återanvändning Vi skulle naturligtvis kunna skriva kod för att räkna ut sinus tar tid komplicerat blir lätt fel (och antagligen ineffektivt) måste testas Smidigare att använda kod som någon annan har skrivit och testat ordentligt Färdiga biblioteksfunktioner - i detta fall i math
#include <stdio.h> #include <math.h> int main(void) { double x, result; Ny variant /* Läs in ett tal från användaren */ printf("skriv in ett tal > "); scanf("%lf",&x); /* Beräkna sinus */ resultat = sin(x); /* Skriv ut vad som beräknats och resultatet */ printf("sin(%f) = %f\n", x, result); return 0;
Principskiss Innehåller deklarationer av vad som finns i kodfilen, tex hur en funktion ser ut myexample.h myexample.h Definition av olika funktioner. Skriven för att kunna användas i olika program myexample.c Kompilator myexample.o
Kompilera programmet I math.h finns bara deklarationerna av funktionerna, inte själva koden Det färdigkompilerade biblioteket måste länkas in Beroende på miljö får man göra olika saker, i Code Blocks ska det fungera direkt. Man kan bli tvungen att skriva något liknande detta (se boken kap 10 i boken för mer info om biblioteksfunktioner) cc -Wall -pedantic -std=c99 -lm -o example example.c Klaga på allt Mattebiblio Källkod Slå på alla varningar Önskat prgnamn Följ standarden C99
Top-down design En problemlösningsmetod Bryt upp ett problem i sub-problem Därefter försöker du lösa dessa sub-problem eller också delar du upp dem i sub-sub-problem. Kort sagt: söndra och härska Bra problemlösningsstrategi
Abstraktion För att göra det enklare att resonera om problem Istället för medelvärdet av rösterna från loopen som kollar vad alla domare har röstat minus högsta och minsta rösten så är det lättare med domarpoängen
Funktioner - vad behövs? double Namn - t.ex. sqrt Beräknar kvadratroten ur ett tal double 1. Namnet 2. Vad funktionen gör 3. Vilka inparametrar 4. Vad är resultatet
Funktioner Gör det lättare att abstrahera Det är det som händer vid uppdelningen Exempel: sqrt - mycket enklare än att beskriva koden (som antagligen är ointressant för det aktuella problemet) Det gör att det blir enklare att resonera om problemet och det är precis vad söndra och härska handlar om.
printf("skriv in födelseår > "); scanf("%d",&year); if( databasecontainspeopleborn( year ) ){ listpeopleborn( year ); else{ displaymessage( NoneBornThisYear );
Motivering för funktioner Abstraktion - problemlösning Återanvändning ofta ser man samma kod på flera ställen, använd en funktion istället rätt skriven kan funktionen användas i flera program Lättare att samarbeta - det blir möjligt att arbeta på olika delar av koden Lättare att byta ut delar av ett program
Funktion i C Ett namn Ett antal parametrar ( 0) 0 eller 1 returvärde (om man ska vara petig så returnerar en funktion alltid ett värde, annars är det ett kommando/procedur) Kod som gör något
Funktionens namn En lista av de parametrar som funktionen förväntar sig. Här två stycken heltal Typen på det värde som funktionen returnerar int add( int a, int b ) { Lokala variabler int result; result = a + b; return result; Den kod som funktionen innehåller Det värde som ska returneras
#include <stdio.h> int add( int a, int b ) { int result; result = a + b; return result; int main(void) { int firstlength = 10, secondlength = 20; int totallength; int topweight = 20, bottomweight = 129; int fullweight; totallength = add( firstlength, secondlength ); fullweight = add( topweight, bottomweight ); printf("total length: %d\n",totallength); printf("full weight: %d\n",fullweight);
Vad händer? 30 fl totallength sl 10 20 10 20 a b result 30 add( firstlength, secondlength ) add 30 main
Funktioner Notera att det är värdet av en variabel som skickas, inte variabeln Det är möjligt att göra anrop som res = add(a,12) dvs en konstant är en av parametrarna
#include <stdio.h> int sub( int a, int b ); int add( int a, int b ) { int result; result = a + b; return result; int main(void) { int firstlength = 10, secondlength = 20; int totallength; int topweight = 20, bottomweight = 129; int fullweight; Funktioner Funktionsdeklaration utan kod totallength = add( firstlength, secondlength ); fullweight = add( topweight, bottomweight ); Tolka detta som ett löfte om att själva definitionen kommer att finnas någon annanstans. Kallas även för funktionsprototyp. printf("total length: %d\n",totallength); printf("full weight: %d\n",fullweight);
Resultatet från en funktion C tillåter två alternativ Strunta i returvärdet Använda det tilldela värdet till en variabel använda det vidare i en beräkning använda det i en jämförelse add(firstlength, secondlength); totallength = add(firstlength, secondlength) * 10; if( add(firstlength, secondlength) * 20 < 2000 ){ printf("buuuu\n");
Varianter void dosomecommand( int c ); void doothercommand( void ); int getsomedata( void ); funktioner som inte returnerar data kallas ibland procedurer
Generellt returtyp funktionsnamn( typ1 namn1,, typn namnn ) { lokala variabeldeklarationer satser skicka tillbaka resultat
int add( int a, int b ) { int result; Formella parametrar result = a + b; return result; add( firstlength, secondlength ) add( 12, 200 ) Aktuella parametrar
add( 2*x - 10, 5*secondLength ) Dessa uttryck evalueras innan själva anropet I C är det bara positionen som styr vilken aktuell parameter som binds till vilken formell parameter
Minnesregel - NOT Number - antalet aktuella parametrar måste vara samma som antalet formella parametrar (inte riktigt sant i alla lägen). Order - ordningen på aktuella parametrar måste vara samma som ordningen på formella parametrar Type - typerna måste överensstämma
Placering av main enligt boken #include <stdio.h> int add( int, int ); int main(void) { int firstlength = 10, secondlength = 20; int totallength; totallength = add( firstlength, secondlength ); printf("total length: %d\n",totallength); int add( int a, int b ) { int result; result = a + b; return result;
#include <stdio.h> int add( int a, int b ) { int result; Placering av main en vanlig variant result = a + b; return result; int main(void) { int firstlength = 10, secondlength = 20; int totallength; totallength = add( firstlength, secondlength ); printf("total length: %d\n",totallength);
#include <stdio.h> int add( int, int ); int sub( int a, int b ) { return a-b; int main(void) { int firstlength = 10, secondlength = 20; int totallength; totallength = add( firstlength, secondlength ); printf("total length: %d\n",totallength); int add( int a, int b ) { int result; Placering av main alltid fel result = a + b; return result;
Ett exempel Programmet ska skriva ut info om sig själv Läs in tre decimaltal Beräkna summan av de två första talen Beräkna summan av alla tre tal Skriv ut resultaten inklusive de ursprungliga talen. Koden finns på sajten
Skriv ut info om programmet Läs in tal 1 Läs in tal 2 Läs in tal 3 räkna ut: tal 1 + tal 2 räkna ut: tal 1 + tal 2 + tal 3 Skriv ut resultat
int main( void ) { skriv_info number_1 = läs_tal number_2 = läs_tal number_3 = läs_tal summan_1_2 = summera(number_1, number_2) summan_1_2_3 = summera(summan_1_2, number_3) eller summan_1_2_3 = summera(summera(number_1,number_2), number_3) skriv_ut_första_resultatet skriv_ut_andra_resultatet
int main( void ) { double number_1, number_2, number_3; double sum2, sum3; printtext(); number_1 = readnumber(); number_2 = readnumber(); number_3 = readnumber(); void printtext( void ) double readnumber( void ) sum2 = sum(number_1, number_2); sum3 = sum(sum2, number_3); eller sum3 = sum(sum(number_1, number_2), number_3); printf("%f + %f = %f\n", number_1, number_2, sum2); printf("%f + %f + %f = %f\n", number_1, number_2, number_3, sum3); return 0; double sum( double, double )
void printtext(void) { printf("\nprogrammet läser in tre tal. "); printf("beräknar summan av de två första talen, \n"); printf("summan av de tre talen, samt skriver ut "); printf("resultaten\n\n"); double readnumber(void) { double number; printf("skriv in tal > "); scanf("%lf", &number); return number; double sum(double n1, double n2) { return n1 + n2;
Variabels synlighet En variabel som deklareras i ett block är bara synlig i det blocket (och ev nästlade block) Den deklarerade variabeln är bara synlig från den plats den deklarerades och till slutet av blocket Om en deklareras utanför alla block (på toppnivå) så blir den global - undvik detta Ger kod som är svår att underhålla Gör det svårare att skriva modulär kod Gör det svårt att skriva återanvändbar kod Berättigat i vissa fall, se dessa som undantag
Variablers synlighet Om samma namn används på flera nivåer så skuggar den tidigare deklarationer (de som finns längre ut ) Stå inuti och titta ut Exempel
double edge; example.c #include <stdio.h> double edge; double cubevolume( int e ) { double edge = e*2.13; double edge; cubevolume double edge; double edge; for-snurra main return edge*edge*edge; int main( void ) { double edge; for(int i = 0; i < 5 ; i++){ double edge; edge = cubevolume( i );
Konstanter Om värden används på flera ställen i programmet så kan de anses vara konstanter och bör då konstantdeklareras Det ger kod som är lättare att underhålla/modifiera /* Print pair-combinations */ for( int a = 0 ; a < 10 ; a++){ for( int b = 0 ; b < 10 ; b++){ printf("(%d,%d)\n",a,b); /* Print pair-combinations */ for( int a = 0 ; a < Number ; a++){ for( int b = 0 ; b < Number ; b++){ printf("(%d,%d)\n",a,b);
Konstanter - define Define - definierar två textsträngar. Vid kompilering kommer den ena att bytas ut mot den andra. Skrivs direkt efter #include-raderna i början av filen Pre-processorn kommer att byta ut texten i filen innan själva kompileringen Normalt använder man versaler (stora bokstäver) #define PI 3.141392654 volume = 4 / 3 * PI * r * r * r;
Konstanter - const En annan variant är nyckelordet const Används på samma sätt som en variabel men kan inte ändras Har samma synlighetsregler som variabler const double pi = 3.141392654; volume = 4 / 3 * pi * r * r * r; Ni bör använda konstantdeklarationer
Biblioteksfunktioner Top-down design Funktioner Lite om konstanter Sammanfattning
Nästa gång Funktioner som returnerar resultat via parametrar Arrayer