Programexempel från C-föreläsning 7, onsdag 2 december 2009 =========================================================== Idag: Om rektangeltestuppgiften (deadline på MÅNDAG och inte fredag) Kvar från förra gången: Bygg ett heltal av siffror if-satser och switch-satsen Sammansatta datatyper Arrayer (= "vektorer" = "fält") Strängar (som också är en sorts arrayer) (Om vi hinner) poster Bygg ett heltal av siffror (Gunnars kap 3 sid 2): Körexempel ------------------------------------------------------------ Ge en rad med tecken: 12kh7jsdhsdh8ekjfkjeflkj------77 Siffrorna bildar talet 127877. Bygg ett heltal av siffror (Gunnars kap 3 sid 2): tecken-1.c ------------------------------------------------------------ #include #include int main(void) { int tal = 0; int tecken; printf("Ge en rad med tecken: "); tecken = getchar(); while (tecken != '\n') { if (tecken >= '0' && tecken <= '9') { tal = tal * 10 + tecken - '0'; } tecken = getchar(); } printf("Siffrorna bildar talet %d.\n", tal); return EXIT_SUCCESS; } /* main */ tecken-2.c ---------- #include #include #include int main(void) { int tal = 0; int tecken; printf("Ge en rad med tecken: "); while ((tecken = getchar()) != '\n') { if (isdigit(tecken)) { tal = tal * 10 + tecken - '0'; } } printf("Siffrorna bildar talet %d.\n", tal); return EXIT_SUCCESS; } /* main */ if-satser.c ----------- #include int main(void) { char val; do { printf("R = Read Data\n"); printf("W = Read Data\n"); printf("Q = Quit\n"); printf("Choose: "); scanf("%c", &val); getchar(); if (val == 'R' || val == 'r') { /* Läs data från en fil */ } else if (val == 'W' || val == 'w') { /* Skriv data till filen */ } else if (val == 'Q' || val == 'q') { printf("Hej då!\n"); } else { printf("Ledsen error.\n"); } } while (!(val == 'Q' || val == 'q')); return 0; } switch-sats.c ------------- #include int main(void) { char val; do { printf("R = Read Data\n"); printf("W = Read Data\n"); printf("Q = Quit\n"); printf("Choose: "); scanf("%c", &val); getchar(); switch (val) { case 'R': case 'r': /* Läs data från en fil */ break; case 'W': case 'w': /* Skriv data till filen */ break; case 'Q': case 'q': printf("Hej då!\n"); break; default: printf("Ledsen error.\n"); break; } } while (!(val == 'Q' || val == 'q')); return 0; } Sammansatta datatyper --------------------- * arrayer * strängar (som också är en sorts arrayer) * (om vi hinner) poster Arrayer (= "vektorer" = "fält") ------------------------------- "Array" är det engelska ordet för en uppställd rad av likadana saker. array-1.c --------- #include #include int main (void) { int i; int a[3]; int b[3] = { 7, 6, -9 }; int c[] = { 7, 6, -9 }; double summan; double d[7]; char t[5] = { 'a', 'b', 'c' }; a[1] = 7; i = a[2]; a[1] = a[0] + 3; i = 0; a[i + 1] = b[i - 1]; printf("a[0] = %d\n", a[0]); printf("a[1] = %d\n", a[1]); printf("a[2] = %d\n", a[2]); for (i = 0; i < 3; ++i) printf("b[%d] = %d\n", i, b[i]); for (i = 0; i < 3; ++i) printf("c[%d] = %d\n", i, c[i]); for (i = 0; i < 9; ++i) printf("d[%d] = %f\n", i, d[i]); for (i = 0; i < 5; ++i) printf("t[%d] = '%c' (%d)\n", i, t[i], t[i]); summan = 0; for (i = 0; i < 7; ++i) summan += d[i]; printf("Summan = %f\n", summan); for (i = 0; i < 7; ++i) { printf("d[%d] = ", i); scanf("%lf", &d[i]); } summan = 0; for (i = 0; i < 7; ++i) summan += d[i]; printf("Summan = %f\n", summan); return EXIT_SUCCESS; } /* main */ Körexempel ---------- a[0] = 0 a[1] = 0 a[2] = -1079209048 b[0] = 7 b[1] = 6 b[2] = -9 c[0] = 7 c[1] = 6 c[2] = -9 d[0] = 0.000000 d[1] = 0.000000 d[2] = -0.055812 d[3] = -0.055812 d[4] = 0.000000 d[5] = 0.000000 d[6] = 0.000000 d[7] = 0.000000 d[8] = 0.000000 t[0] = 'a' (97) t[1] = 'b' (98) t[2] = 'c' (99) t[3] = '' (0) t[4] = '' (0) Summan = -0.111625 d[0] = 2 d[1] = 2 d[2] = 2 d[3] = 1000 d[4] = 2 d[5] = 2 d[6] = 2 Summan = 1012.000000 array-2.c --------- /* Det här programmet läser reella tal från stdin, * tills det kommer ett negativt tal, * och skriver sedan ut de inmatade talens medelvärde. */ #include int main (void) { double talet, summan, alla_talen[10]; int i, antal_tal; printf("Skriv reella tal. Avsluta med ett negativt tal.\n"); scanf("%lf", &talet); while (talet >= 0) { alla_talen[antal_tal] = talet; antal_tal++; scanf("%lf", &talet); } summan = 0; for (i = 0; i < antal_tal; ++i) summan += alla_talen[i]; printf("Medelvärdet = %f\n", summan / antal_tal); return 0; } /* main */ array-3.c --------- /* Det här programmet läser reella tal från stdin, * tills det kommer ett negativt tal, * och skriver sedan ut de inmatade talens medelvärde. */ #include #include #define MAX_ANTAL_TAL 10 int main (void) { double talet, summan, alla_talen[MAX_ANTAL_TAL]; int i, antal_tal; printf("Skriv reella tal. Avsluta med ett negativt tal.\n"); scanf("%lf", &talet); while (talet >= 0) { if (antal_tal == MAX_ANTAL_TAL) printf("Nej, jag kan bara hantera %d tal!\n", MAX_ANTAL_TAL); else alla_talen[antal_tal++] = talet; scanf("%lf", &talet); } summan = 0; for (i = 0; i < antal_tal; ++i) summan += alla_talen[i]; printf("Medelvärdet = %f\n", summan / antal_tal); return EXIT_SUCCESS; } /* main */ I modernare C (och i C++): array-4.c ------------------------------------ /* Det här programmet läser ett heltal från stdin, * läser sedan in så många flyttal (med dubbel precision) * som anges av heltalet (dock högst 10), * lagrar dem i en array, och beräknar till sist summan. */ #include #include const int max_antal_flyttal = 10; int main (void) { double sum, alla_talen[max_antal_flyttal]; /* Tillåtet i C99 men inte i C89 */ int antal_tal, i; printf("Hur många flyttal? "); scanf("%d", &antal_tal); if (antal_tal > max_antal_flyttal) { printf("Nej, jag kan bara hantera %d flyttal!\n", max_antal_flyttal); antal_tal = max_antal_flyttal; } for (i = 0; i < antal_tal; ++i) scanf("%lf", &alla_talen[i]); sum = 0; for (i = 0; i < antal_tal; ++i) sum += alla_talen[i]; printf("Summan = %f\n", sum); return EXIT_SUCCESS; } /* main */ Mer om arrayer -------------- Arrayer kan inte direkt (a) jämföras, (b) tilldelas, eller (c) skickas till och från funktioner, utan det måste göras element för element Exempel på saker som inte fungerar (som man tror): a = { 1, -3, 2 }; b = a; if (a == b) .... fnorble(a); b = gnorble(a); Textsträngar (= strängar = teckensträngar) ------------------------------------------ Textsträng i C = array av char, som avslutas med tecknet med teckenkoden 0 (skrivs '\0') Fyra sätt att stoppa in "Hej" i strängen s: char s[4]; s[0] = 'H'; s[1] = 'e'; s[2] = 'j'; s[3] = '\0'; char s[4] = { 'H', 'e', 'j', '\0' }; char s[4] = "Hej"; char s[] = "Hej"; Exempel ------- Gunnar kapitel 4 sid 4: Läs en sträng med scanf("%s") + skriv ut baklänges Gunnar kapitel 4 sid 5: Läs en textrad med gets + räkna antalet mellanslag Varning om både scanf("%s") och gets ------------------------------------ Buffer overflow! Använd fgets! Två körexempel för programmet strangar -------------------------------------- Ge ett namn: Klas Hej, Klas! Ge lösenord: Olle Nähä du! Ge ett namn: Olle Hej, Olle! Ge lösenord: anakin Välkommen! strangar.c ---------- #include #include int main(void) { char namn[80 + 1]; printf("Ge ett namn: "); fgets(namn, sizeof namn, stdin); /* Undvik gets! */ /* Men fgets behåller radslutstecknet - ta bort det */ int sista_positionen = strlen(namn) - 1; if (namn[sista_positionen] == '\n') namn[sista_positionen] = '\0'; printf("Hej, %s!\n", namn); char losenord[80 + 1]; printf("Ge lösenord: "); fgets(losenord, sizeof losenord, stdin); /* Undvik gets! */ if (strcmp(losenord, "anakin\n") == 0) printf("Välkommen!\n"); else printf("Nähä du!\n"); return 0; }