Programmering C: Lösningar till tentamen 2016-07-18

Observera att detta är förslag på lösningar. Det kan finnas andra lösningar som också är korrekta, och det kan hända att en del av lösningarna är mer omfattande än vad som krävs för full poäng på uppgiften. En del av lösningarna är kanske inte fullständiga, utan hänvisar bara till var man kan läsa svaret. Dessutom har det inträffat i världshistorien att lärare skrivit fel i lösningsförslagen.

Uppgift 1 (1 p)

a) -4

b) 5

c) 7

d) 6

Uppgift 2 (2 p)

a = 5, b = 6, i = 11

Uppgift 3 (3 p)

#include <stdio.h>

int main(void) {
    int a, b, c;

    printf("Ange ett heltal: ");
    scanf("%d", &a);
    printf("Ange ett heltal: ");
    scanf("%d", &b);
    printf("Ange ett heltal: ");
    scanf("%d", &c);

    for (int i = a; i <= b; ++i) {
        if (i != c)
            printf("%d\n", i);
    }
}

Uppgift 4 (4 p)

#include <stdio.h>
#include <float.h>

int main(void) {
    printf("Mata in minst tre reella tal. Avsluta med talet noll.\n");

    int antalet = 0;
    double summan = 0, lagsta = DBL_MAX, hogsta = DBL_MIN;
    double talet;

    do {
        printf("Skriv ett tal: ");
        scanf("%lf", &talet);
        if (talet != 0) {
            if (talet < lagsta)
                lagsta = talet;
            if (talet > hogsta)
                hogsta = talet;
            summan += talet;
            ++antalet;
        }
    } while (talet != 0);

    printf("Medelvärdet (utom extremvärdena) = %f\n",
           (summan - lagsta - hogsta) / (antalet - 2));
}

Uppgift 5 (5 p)

#define MAX_NAMNLANGD 10
#define MAX_ANTAL_MONSTER_PER_RUM 5
#define MAX_ANTAL_RUM 100

struct Monster {
    int nummer;
    char namn[MAX_NAMNLANGD + 1]; // + 1 för '\0'
    double storlek;
};

struct Monster gluggo = { 17, "Gluggo", 2000 };

struct Rum {
    int nummer;
    struct Monster monster[MAX_ANTAL_MONSTER_PER_RUM];
    int antal_monster;
};

struct Rum rum[MAX_ANTAL_RUM];
int antal_rum = 0;

Uppgift 6 (4 p)

a)
int totalt_antal_monster(struct Rum rum[], int antal_rum) {
    int summa = 0;
    for (int i = 0; i < antal_rum; ++i)
        summa += rum[i].antal_monster;
    return summa;
}
b)
    int antalet = totalt_antal_monster(rum, antal_rum);
    printf("Det totala antalet monster är %d.\n", antalet);

Uppgift 7 (2 p)

void visa_monster(struct Monster m) {
    printf("Nummer: %d\n", m.nummer);
    printf("Namn: %s\n", m.namn);
    printf("Storlek: %f\n", m.storlek);
}

Uppgift 8 (3 p)

void visa_rum(struct Rum r) {
    printf("Rumsnummer: %d\n", r.nummer);
    printf("Rummet innehåller %d monster:\n", r.antal_monster);
    for (int i = 0; i < r.antal_monster; ++i)
        visa_monster(r.monster[i]);
}

Uppgift 9 (3 p)

struct Monster las_monster(void) {
    struct Monster m;
    printf("Ange monstrets nummer: ");
    scanf("%d", &m.nummer);
    printf("Ange monstrets namn: ");
       // Vi antar att namn inte kan innehålla blanktecken
    // Vi kollar inte maxlängden heller
    scanf("%s", m.namn);
    printf("Ange monstrets storlek: ");
    scanf("%lf", &m.storlek);
    return m;
}

Uppgift 10 (3 p)

struct Rum las_rum(void) {
    struct Rum r;
    printf("Ange rummets nummer: ");
    scanf("%d", &r.nummer);
    printf("Ange antalet monster som finns i rummet (max 5): ");
    scanf("%d", &r.antal_monster);
    for (int i = 0; i < r.antal_monster; ++i) {
        printf("Ange data för monster nummer %d!\n", i + 1);        
        r.monster[i] = las_monster();
    }
    return r;
}

Uppgift 11 (4 p)

int main(void) {
    struct Rum rum1 = las_rum();
    struct Rum rum2 = las_rum();
    double maxstorlek = 0;
    for (int i = 0; i < rum1.antal_monster; ++i) {
        if (rum1.monster[i].storlek > maxstorlek)
            maxstorlek = rum1.monster[i].storlek;
    }
    for (int i = 0; i < rum2.antal_monster; ++i) {
        if (rum2.monster[i].storlek > maxstorlek)
            maxstorlek = rum2.monster[i].storlek;
    }
    // Vi antar att det finns minst ett monster,
    // och att det bara är ett som är störst
    for (int i = 0; i < rum1.antal_monster; ++i) {
        if (rum1.monster[i].storlek == maxstorlek)
            visa_monster(rum1.monster[i]);
    }
    for (int i = 0; i < rum2.antal_monster; ++i) {
        if (rum2.monster[i].storlek == maxstorlek)
            visa_monster(rum2.monster[i]);
    }
}

Uppgift 12 (10 p)

a)
void spara_rum(struct Rum r, char filnamn[]) {
    FILE *f = fopen(filnamn, "wb");
    if (f == NULL) {
        fprintf(stderr, "Kunde inte skriva rumsfilen '%s'.\n", filnamn);
        exit(EXIT_FAILURE);
    }
    if (fwrite(&r, sizeof(r), 1, f) != 1) {
        fprintf(stderr, "Kunde inte skriva ett rum på rumsfilen '%s'.\n", filnamn);
        exit(EXIT_FAILURE);
    }
    fclose(f);
}
b)
struct Rum hemta_rum(char filnamn[]) {
    struct Rum r;
    FILE *f = fopen(filnamn, "rb");
    if (f == NULL) {
        fprintf(stderr, "Kunde inte läsa rumsfilen '%s'.\n", filnamn);
        exit(EXIT_FAILURE);
    }
    if (fread(&r, sizeof(r), 1, f) != 1) {
        fprintf(stderr, "Kunde inte läsa ett rum från rumsfilen '%s'.\n", filnamn);
        exit(EXIT_FAILURE);
    }
    fclose(f);
    return r;
}
c)
int main(void) {
    struct Rum rum1;
    struct Rum rum2;

    rum1 = las_rum();
    spara_rum(rum1, "rummet.bin");
    rum2 = hemta_rum("rummet.bin");
    visa_rum(rum2);
}


Thomas Padron-McCarthy (thomas.padron-mccarthy@oru.se), 19 augusti 2016