Programexempel från C-föreläsning 10, tisdag 9 januari 2007 =========================================================== Ny föreläsningsplanering ------------------------ Fö 10 (idag, tisdag 9/1): forts funktioner; filer med stdio Fö 11 (onsdag 10/1): filer med stdio (bl a binärfiler) Fö 12 (fredag 12/1): felhantering, repetition, tentauppgifter, frågor Obs! Två extrainsatta föreläsningstider (lokal ej klart än) Obs! Tentan på lördag går i Hörsal T kl 14-18. (Det stod en annan lokal tidigare, men den visade sig bli för liten.) Forts. om funktioner -------------------- Heläxan: En funktion som byter plats på innehållet i två heltalsvariabler Pekare för att returnera mer än ett värde 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 */ Poster som argument och returnerade värden -- helt okej: poster.c ----------------------------------------------------------------- #include struct person { int nummer; char namn[10 + 1]; double vikt; }; void skriv_post(struct person p) { printf("Nummer: %d\n", p.nummer); printf("Namn: %s\n", p.namn); printf("Vikt: %f\n", p.vikt); } void skriv_post_2(struct person *pp) { printf("Nummer: %d\n", pp->nummer); printf("Namn: %s\n", pp->namn); printf("Vikt: %f\n", pp->vikt); } void las_post(struct person *pp) { printf("Nummer: "); scanf("%d", &pp->nummer); printf("Namn: "); scanf("%s", pp->namn); printf("Vikt: "); scanf("%lf", &pp->vikt); } struct person las_post_2() { struct person p; printf("Nummer: "); scanf("%d", &p.nummer); printf("Namn: "); scanf("%s", p.namn); printf("Vikt: "); scanf("%lf", &p.vikt); return p; } int main() { struct person personen; las_post(&personen); personen = las_post_2(); skriv_post(personen); skriv_post_2(&personen); return 0; } /* main */ Arrayer som argument och returnerade värden -- se upp ----------------------------------------------------- Det som skickas respektive returneras är en pekare till första elementet i arrayen! arrayfel.c ---------- #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 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 */ Ett exempel: funktionen "udda", som returnerar sant om talet är udda -------------------------------------------------------------------- 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 */ 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 */