Programexempel från C-föreläsning 10, torsdag 10 januari 2008 ============================================================= Idag: 1. Parametrar och argument, formella och aktuella 2. Funktionen "udda", som returnerar sant om talet är udda 3. Att returnera flera värden från en funktion 4. Poster som argument och returnerade värden -- helt okej 5. Arrayer som argument och returnerade värden -- se upp 6. En funktion som beräknar medelvärdet av en reell vektor 7. Funktionen "swap" (som inte fungerar och som fungerar) 8. Filhantering med stdio-paketet 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); Ett exempel: funktionen "udda", som returnerar sant om talet är udda (Gunnar 2.5-7) ----------------------------------------------------------------------------------- int udda(int tal) { if (tal % 2 == 0) return 0; else return 1; } int udda(int tal) { if (tal % 2 == 0) return 0; return 1; } int udda(int tal) { return tal % 2; } udda-2.c -------- #include int udda(int tal) { if (tal % 2 == 0) return 0; else return 1; } int main() { int talet; printf("Ge ett tal: "); scanf("%d", &talet); if (udda(talet)) printf("%d är udda.\n", talet); else printf("%d är jämnt.\n", talet); return 0; } /* main */ Att returnera flera värden från en funktion ------------------------------------------- 1. Pekare (exempel: scanf) 2. Globala variabler (exempel: errno) 3. Poster (se nedan) 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 reell vektor Ett exempel: en funktion som beräknar medelvärdet av en reell vektor -------------------------------------------------------------------- (Rita upp "talen" och "a") #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 Filhantering med stdio-paketet ------------------------------ "Ström" (datatypen FILE): transporterar data mellan programmets primärminne och sekundärminnet (normalt disken) Textström (vanligast, enklast): omvandlar mellan binära data (i primärminnet) och text (på sekundärminnet) Binärström: bara transporterar, utan omvandling filer-1.c --------- #include int main() { int tal = 130; printf("Nu är talet = %d\n", tal); FILE *tsut; tsut = fopen("tal.txt", "wt"); fprintf(tsut, "%d", tal); fclose(tsut); printf("Nu är talet = %d\n", tal); FILE *tsin; tsin = fopen("tal.txt", "rt"); fscanf(tsin, "%d", &tal); fclose(tsin); printf("Nu är talet = %d\n", tal); return 0; } /* main */ reellatal.txt ------------- 4.92927 8.52385 6.1061 5.49319 3.16384 6.47934 0.405324 3.10623 7.66471 4.43504 0.0 filmedel.c ---------- #include #include int main() { FILE *tsin; double talet, summan; int antal; tsin = fopen("reellatal.txt", "rt"); if (tsin == NULL) { printf("Kunde inte öppna filen.\n"); return EXIT_FAILURE; } summan = 0.0; antal = 0; fscanf(tsin, "%lf", &talet); while (talet != 0.0) { summan += talet; ++antal; fscanf(tsin, "%lf", &talet); } fclose(tsin); printf("Medel = %f\n", summan / antal); return EXIT_SUCCESS; } /* main */ filmedel-2.c ------------ #include #include int main() { FILE *tsin; double talet, summan; int antal; if ((tsin = fopen("reellatal.txt", "rt")) == NULL) { printf("Kunde inte öppna filen.\n"); return EXIT_FAILURE; } summan = 0.0; antal = 0; while (fscanf(tsin, "%lf", &talet) != EOF) { summan += talet; ++antal; } fclose(tsin); printf("Medel = %f\n", summan / antal); return EXIT_SUCCESS; } /* main */