Programexempel från C-föreläsning 9, tisdag 11 december 2012 ============================================================ Idag: 1. Funktioner Om vi eventuellt skulle hinna: 2. Allegro-biblioteket 3. Filhantering med stdio-paketet 1. Funktioner ============= Funktioner ---------- "Funktion" i matematiken = avbildning, t. ex. y = f(x) = 2x + 3, där t. ex. värdet x=7 avbildas på y=17 "Funktion" i C: programsnutt En C-funktion kan ta emot värden (via parametrar) och returnera ett värde ("retur-värdet"). (Med olika trick kan man returnera flera värden.) Exempel på funktioner: main, printf, scanf, sqrt En ren programsnutt ------------------- time_t nu; char* nu_text; nu = time(NULL); nu_text = ctime(&nu); printf("Klockan är nu %.8s\n", nu_text + 11); Gör en funktion, och anropa den (klockan.c) ------------------------------------------- #include #include void skriv_tiden() { time_t nu; char* nu_text; nu = time(NULL); nu_text = ctime(&nu); printf("Klockan är nu %.8s\n", nu_text + 11); } int main() { skriv_tiden(); skriv_tiden(); skriv_tiden(); return 0; } /* main */ En funktion som returnerar ett värde (som rand och main) -------------------------------------------------------- int kolla_losenordet() { char s[100 + 1]; printf("Lösenord: "); fgets(s, sizeof s, stdin); if (strcmp(s, "dungeon\n") == 0) return 1; else return 0; } Alternativ ---------- int kolla_losenordet() { char s[100 + 1]; printf("Lösenord: "); fgets(s, sizeof s, stdin); return strcmp(s, "dungeon\n") == 0; } Olika anrop ----------- int main() { int ok_losen; kolla_losenordet(); if (kolla_losenordet()) printf("Rätt!\n"); else printf("Fel!\n"); ok_losen = kolla_losenordet(); if (ok_losen) printf("Rätt!\n"); else printf("Fel!\n"); return 0; } /* main */ Parametrar och argument, formella och aktuella ---------------------------------------------- Funktion: void f(int x, float y, double z) { ... } Anrop: f(3, r, sqrt(r + 2)); x, y och z: "parametrar", "formella parametrar" 3, r och sqrt(r + 2): "argument", "aktuella parametrar" Ett anrop till: f(i, 2.0, 3.0); parametrar.c ------------ #include #include void f(int x, float y, double z) { printf("x = %d\n", x); printf("y = %f\n", y); printf("z = %f\n", z); } int main() { float r; int i; r = 6.2; i = 12; f(3, r, sqrt(r + 2)); f(i, 2.0, 3.0); return 0; } /* main */ parametrar-2.c -------------- #include #include double g(int x, float y, double z) { double summan; summan = x + y + z; return summan; } int main() { float r; int i; double resultat; r = 6.2; i = 12; resultat = g(3, r, sqrt(r + 2)); printf("resultat = %f\n", resultat); printf("resultat = %f\n", g(i, 2.0, 3.0)); return 0; } /* main */ Returnera flera värden ---------------------- 1. Pekare (exempel: scanf) 2. Globala variabler (exempel: errno) 3. Poster (se nedan) Poster som argument och returnerade värden -- helt okej ------------------------------------------------------- Arrayer som argument och returnerade värden -- se upp ----------------------------------------------------- Det som skickas respektive returneras är en pekare till första elementet i arrayen! Ex: en funktion som beräknar medelvärdet av en reell vektor Mer exempel ----------- Ex 1: Funktionen "udda", som returnerar sant om talet är udda (Gunnar 2. 5-7) Ex 2: Funktionen "swap" (som inte fungerar och som fungerar) Poster som argument och returnerade värden -- helt okej: punkter.c ------------------------------------------------------------------ #include #include #include #include struct Punkt { double x; double y; }; struct Punkt hitta_mitten(struct Punkt p1, struct Punkt p2) { struct Punkt resultat; resultat.x = (p1.x + p2.x) / 2; resultat.y = (p1.y + p2.y) / 2; return resultat; } int main(void) { struct Punkt ena = { -1, 1 }, andra = { 3, 3 }; struct Punkt mittpunkten; mittpunkten = hitta_mitten(ena, andra); printf("mittpunkten = ( %f, %f )\n", mittpunkten.x, mittpunkten.y); return EXIT_SUCCESS; } // main Arrayer som argument och returnerade värden -- se upp ----------------------------------------------------- Det som skickas respektive returneras är en pekare till första elementet i arrayen! Ex: en funktion som beräknar medelvärdet av en vektor med flyttal (Rita upp "talen" och "a") En funktion som beräknar medelvärdet av en vektor med flyttal ------------------------------------------------------------- #include double medel(double a[], int antal) { // Eller: *a int i; double summan = 0; for (i = 0; i < antal; ++i) summan += a[i]; if (antal > 0) // Eller inte? return summan / antal; else return 0; } int main() { double talen[] = { 3.2, 3.3, 3.4, 3.1, 3.1 }; printf("Medel = %f\n", medel(talen, 5)); return 0; } /* main */ Funktionen "swap" (som inte fungerar): swap-1.c ----------------------------------------------- #include void swap(int a, int b) { int temp; temp = a; a = b; b = temp; } int main() { int x = 7; int y = 13; printf("Före: x = %d, y = %d\n", x, y); swap(x, y); printf("Efter: x = %d, y = %d\n", x, y); return 0; } /* main */ Funktionen "swap" (som fungerar): swap-2.c ------------------------------------------ #include void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } int main() { int x = 7; int y = 13; printf("Före: x = %d, y = %d\n", x, y); swap(&x, &y); printf("Efter: x = %d, y = %d\n", x, y); return 0; } /* main */ arrayfel.c (om vi hinner) ------------------------- #include #include char* smart_fgets() { char s[100 + 1]; printf("Skriv en rad: "); fgets(s, sizeof s, stdin); int sista = strlen(s) - 1; if (s[sista] == '\n') s[sista] = '\0'; return s; } int main() { char *raden; raden = smart_fgets(); printf("Raden var: %s\n", raden); return 0; } /* main */ Körexempel ---------- Skriv en rad: Hej alla glada fotogenkaminer! Raden var: Hej alla glada fotogenkaminer! Kompileringsvarning ------------------- arrayfel.c: In function `smart_fgets': arrayfel.c:11: warning: function returns address of local variable