Programexempel från C-föreläsning 9, onsdag 9 december 2009 =========================================================== 1. Inlämningsuppgift 3, automatiserad testning 2. Ett program som jobbar med en array av poster: punkter-1.c 3. Ett bättre exempel: punkter-2.c 4. Hinner vi inte: Programmet monster.c 5. Pekare! Körexempel för programmet punkter-1 ----------------------------------- Mata in punkter genom att skriva x- och y-koordinater, utan komma emellan. Avsluta med punkten 0 0. 3 17 4 9 5 12 2 6 0 0 Punkten med minsta x: x = 2, y = 6 Punkten med största x: x = 5, y = 12 punkter-1.c ----------- #include #include #include struct Punkt { int x; int y; }; const int max_antal_punkter = 100; // Funkar med en tillräckligt modern C int main(void) { struct Punkt a[max_antal_punkter]; int antal = 0; printf("Mata in punkter\n" "genom att skriva x- och y-koordinater, utan komma emellan.\n" "Avsluta med punkten 0 0.\n"); int x; int y; do { scanf("%d %d", &x, &y); if (x == 0 && y == 0) { // Avsluta } else { // Lägg in i arrayen if (antal == max_antal_punkter) { printf("Fullt!"); return EXIT_FAILURE; } a[antal].x = x; a[antal].y = y; ++antal; } } while (x != 0 || y != 0); // Hitta punkterna med minsta och största x-värden, // och skriv ut dem! if (antal == 0) { printf("Inga punkter.\n"); return EXIT_SUCCESS; } struct Punkt min, max; min.x = INT_MAX; // Eller: min = a[0]; max.x = INT_MIN; // Eller: max = a[0]; for (int i = 0; i < antal; ++i) { if (a[i].x < min.x) min = a[i]; if (a[i].x > max.x) max = a[i]; } printf("Punkten med minsta x: x = %d, y = %d\n", min.x, min.y); printf("Punkten med största x: x = %d, y = %d\n", max.x, max.y); return EXIT_SUCCESS; } // main Om vi hinner: Körexempel för programmet punkter-2 ------------------------------------------------- Mata in punkter genom att skriva x- och y-koordinater, utan komma emellan. Avsluta med punkten 0 0. 3 17 4 9 5 12 2 6 0 0 Punkterna (x = 3, y = 17) och (x = 2, y = 6) har störst avstånd: 11.05 Om vi hinner: punkter-2.c ------------------------- #include #include #include #include struct Punkt { int x; int y; }; const int max_antal_punkter = 100; int main(void) { struct Punkt a[max_antal_punkter]; int antal = 0; printf("Mata in punkter\n" "genom att skriva x- och y-koordinater, utan komma emellan.\n" "Avsluta med punkten 0 0.\n"); int x; int y; do { scanf("%d %d", &x, &y); if (x == 0 && y == 0) { // Avsluta } else { // Lägg in i arrayen if (antal == max_antal_punkter) { printf("Fullt!"); return EXIT_FAILURE; } a[antal].x = x; a[antal].y = y; ++antal; } } while (x != 0 || y != 0); // Vilka punkter ligger längst ifrån varandra? struct Punkt p1, p2; double max_avst; for (int i = 0; i < antal; ++i) { for (int j = i + 1; j < antal; ++j) { double avst = sqrt(pow(a[i].x - a[j].x, 2) + pow(a[i].y - a[j].y, 2)); if (avst > max_avst) { max_avst = avst; p1 = a[i]; p2 = a[j]; } } } printf("Punkterna (x = %d, y = %d) och (x = %d, y = %d) har störst avstånd: %.2f\n", p1.x, p1.y, p2.x, p2.y, max_avst); return EXIT_SUCCESS; } // main Om vi hinner: Körexempel för programmet monster ----------------------------------------------- Hur många monster (max 10)? 3 Monster 1. Namn? Hulken Antal hit points? 1000 Vikt? 300 Monster 2. Namn? Varulven Antal hit points? 100 Vikt? 80 Monster 3. Namn? Mumien Antal hit points? 30 Vikt? 50 Varje monster biter ett annat monster... Hulken biter Mumien. Varulven biter Mumien. Mumien biter Hulken. Det är mest synd om Mumien. Om vi hinner: monster.c ----------------------- #include #include #include #define MAX_NAMN 10 #define MAX_MONSTER 10 struct Monster { char namn[MAX_NAMN + 1]; int hp; double vikt; int bett; }; int main(void) { struct Monster monstren[MAX_MONSTER]; int antal_monster; int i; struct Monster maxbiten; do { printf("Hur många monster (max %d)? ", MAX_MONSTER); scanf("%d", &antal_monster); while (getchar() != '\n') ; } while (antal_monster > MAX_MONSTER || antal_monster < 2); for (i = 0; i < antal_monster; ++i) { printf("\n"); printf("Monster %d. Namn? ", i + 1); gets(monstren[i].namn); /* Varning: gets */ printf("Antal hit points? "); scanf("%d", &monstren[i].hp); printf("Vikt? "); scanf("%lf", &monstren[i].vikt); while (getchar() != '\n') ; monstren[i].bett = 0; } printf("\n"); printf("Varje monster biter ett annat monster...\n"); srand(time(0)); for (i = 0; i < antal_monster; ++i) { int stackarn; do stackarn = rand() % antal_monster; while (stackarn == i); printf("%s biter %s.\n", monstren[i].namn, monstren[stackarn].namn); monstren[stackarn].bett++; } maxbiten = monstren[0]; for (i = 1; i < antal_monster; ++i) { if (monstren[i].bett > maxbiten.bett) maxbiten = monstren[i]; } printf("Det är mest synd om %s.\n", maxbiten.namn); return EXIT_SUCCESS; } /* main */ Pekare ------ En pekare är adressen till den plats i minnet där något finns lagrat. Men dessutom har pekaren en typ (nämligen pekare till vad-det-nu-är), så det är inte bara en adress, utan man håller reda på vilken typ av data som pekaren kan peka på. Kom ihåg scanf -------------- int i; printf("Värde: %d\n", i); /* Värdet, dvs innehållet i variabeln i, skickas */ scanf("%d", &i); /* Här skickar vi i stället en pekare till variabeln i */ Exempel med pekare ------------------ (Vi ritar upp allt detta, både som lådor och pilar och som minnesadresser!) float x; scanf("%f", &x); float *pf; pf = &x; /* rita två bilder här: lådor respektive adresser */ *pf = -9.9; int i; pf = &i; /* Fel! Kompilatorn varnar. */ float y; float *pf2; y = x; pf2 = &y; pf2 = y; /* Fel! Kompileringsfel. */ *pf = *pf2 + 2; *pf2 = *pf; pf2 = pf; scanf("%f", &x); scanf("%f", pf); Strängar (och andra arrayer) ---------------------------- Om man skriver namnet på en array-variabel (t ex en char-array = sträng) i ett C-program, så kommer den (för det mesta) att konverteras till en pekare till det första elementet i arrayen. Kom ihåg gets och scanf ----------------------- int i; scanf("%d", &i); /* &-tecken */ char s[3+1]; gets(s); /* Inget &-tecken */ scanf("%s", s); /* Inget &-tecken */ Fortsättning ------------ char *cp; cp = &s; /* Fel! Kompilatorn varnar. */ cp = s; s[1] = 'o'; cp[1] = 'o'; Allt på en gång: poster, pekare, arrayer (jfr: Gunnar kap 4 sid 11) ------------------------------------------------------------------- struct Motor { int cyl; double effekt; }; struct Motor m = { 4, 120 }; Pekare till struct (fortsättning) --------------------------------- struct Motor *mp; mp = &m; (*mp).cyl = 6; (*mp).effekt = 160.0; /* Inte: *mp.effekt = 160.0; */ Alternativ: mp->cyl = 6; mp->effekt = 160.0; Array av poster ("vektor av structar) -- jfr "punktuppgifterna" fö 7 -------------------------------------------------------------------- struct Motor a[5]; a[0].cyl = 8; a[0].effekt = 185; struct Motor *mp; mp = a; /* Inte: mp = &a; */ mp[1].cyl = 4; mp[1].effekt = 110;