Programmering C: Lösningar till tentamen 2009-05-23

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.

Uppgift 1 (3 p)

#include <stdio.h>

int main(void) {
    int antal;
    double talet;
    double summa = 0;

    printf("Antal reella tal att mata in: ");
    scanf("%d", &antal);

    printf("Mata in %d reella tal:\n", antal);
    for (int i = 0; i < antal; ++i) {
        scanf("%lf", &talet);
        summa += talet;
    }

    printf("Summa: %.2f\n", summa);

    return 0;
}

Uppgift 2 (3 p)

#include <stdio.h>

int main(void) {
    double volume, effect;
    double max_volume = 0, max_volume_effect = 0;

    printf("Mata in volym och effekt. "
           "Avsluta med minst ett värde som är noll.\n");
    scanf("%lf %lf", &volume, &effect);
    while (effect != 0 && volume != 0) {
        if (volume > max_volume) {
            max_volume = volume;
            max_volume_effect = effect;
        }
        printf("Mata in volym och effekt. "
               "Avsluta med minst ett värde som är noll.\n");
        scanf("%lf %lf", &volume, &effect);
    }

    printf("Den största vattenkokaren har effekten %.2f W.\n",
           max_volume_effect);

    return 0;
}

Uppgift 3 (3 p)

int array_count(double numbers[], int elements, double wanted) {
    int count = 0;
    for (int i = 0; i < elements; ++i)
        if (numbers[i] == wanted)
            ++count;
    return count;
}

Uppgift 4 (2 p)

int main(void) {
    double a[] = { -1.5, 3.0, 17.6, -19, 3.0, 3.0 };

    printf("Resultat: %d\n",
           array_count(a, sizeof a / sizeof a[0], 3.0));

    return 0;
}

Uppgift 5 (3 p)

#include <stdio.h>

int main(void) {
    double riktvarde;
    double temperatur;

    printf("Ange önskad temperatur: ");
    scanf("%lf", &riktvarde);

    while (1) {
        printf("Ange aktuell temperatur: ");
        scanf("%lf", &temperatur);
        double skillnad = temperatur - riktvarde;
        if (skillnad > 3)
            printf("Kylning för fullt!\n");
        else if (skillnad >= 1)
            printf("Lite kylning.\n");
        else if (skillnad > -1)
            printf("Ingen åtgärd.\n");
        else if (skillnad >= -3)
            printf("Elementet på lite.\n");
        else
            printf("Elementet på för fullt!\n");
    }

    return 0;
}

Uppgift 6 (5 p)

#include <stdio.h>

int min(int a, int b, int c) {
    if (a < b && a < c)
        return a;
    else if (b < c)
        return b;
    else
        return c;
}

int main(void) {
    int forsta, andra, tredje;
    printf("Ge första talet (avsluta med 0): ");
    scanf("%d", &forsta);
    while (forsta != 0) {
        printf("Ge andra talet: ");
        scanf("%d", &andra);
        printf("Ge tredje talet: ");
        scanf("%d", &tredje);
        printf("Minsta talet = %d\n", min(forsta, andra, tredje));
        printf("Ge första talet (avsluta med 0): ");
        scanf("%d", &forsta);
    }

    return 0;
}

Uppgift 7 (5 p)

#include <stdio.h>
#include <string.h>

#define MAX_RADER 618
#define MAX_TECKEN_PER_RAD 719

char raderna[MAX_RADER][MAX_TECKEN_PER_RAD + 2];
// Varför +2? Jo, plus ett för radslutstecknet '\n, och plus ett till för '\0'.

int antal_tecken(char s[], char c) {
    int n = strlen(s);
    int antal = 0;
    for (int i = 0; i < n; ++i)
        if (s[i] == c)
            ++antal;
    return antal;
}

int main(void) {
    int antal_sparade_rader = 0;
    char raden[MAX_TECKEN_PER_RAD + 2];
    do {
        fgets(raden, sizeof raden, stdin);
        if (antal_tecken(raden, 'T') == 3)
            strcpy(raderna[antal_sparade_rader++], raden);
    } while (raden[0] != '\n');
    for (int i = 0; i < antal_sparade_rader; ++i) {
        fputs(raderna[i], stdout);
    }
    return 0;
}

Uppgift 8 (16 p)

a) (1p)
struct VideoKlick {
    int videonummer;
    int antal_klick;
};
b) (1p)
#define MAX_ANTAL_VIDEOSAR 1000000
c) (1p)
/* Arrayen görs global, för den får nog inte plats på stacken */
struct VideoKlick klick[MAX_ANTAL_VIDEOSAR];
int antal_videosar = 0;
d) (1p)

MAX_ANTAL_VIDEOSAR anger hur många positioner som finns i arrayen, men säger inte hur många av dessa positioner som vi faktiskt använt för att lagra något i.

e) (2p)

int hitta_position(int videonummer) {
    for (int i = 0; i < antal_videosar; ++i)
        if (klick[i].videonummer == videonummer)
            return i;
    return -1;
}
f) (3p)
int ny_video(int videonummer) {
    if (antal_videosar == MAX_ANTAL_VIDEOSAR) {
        fprintf(stderr, "För många olika videosar!");
        exit(EXIT_FAILURE);
    }
    int nya_positionen = antal_videosar;
    ++antal_videosar;
    klick[nya_positionen].videonummer = videonummer;
    klick[nya_positionen].antal_klick = 0;
    return nya_positionen;
}
g) (2p)
void addera_klick(int videonummer, int antal_nya_klick) {
    int position = hitta_position(videonummer);
    if (position == -1)
        position = ny_video(videonummer);
    klick[position].antal_klick += antal_nya_klick;
}
h) (4p)
int main(void) {
    FILE* infil = fopen("indata.txt", "r");
    if (infil == NULL) {
        fprintf(stderr, "Gick inte att öppna infilen!");
        exit(EXIT_FAILURE);
    }

    int videonummer;
    int antal_klick;
    while (fscanf(infil, "%d %d", &videonummer, &antal_klick) == 2) {
        addera_klick(videonummer, antal_klick);
    }

    fclose(infil);

    FILE* utfil = fopen("utdata.txt", "w");
    if (infil == NULL) {
        fprintf(stderr, "Gick inte att öppna utfilen!");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < antal_videosar; ++i)
        fprintf(utfil, "%d %d\n", klick[i].videonummer, klick[i].antal_klick);

    fclose(utfil);

    return EXIT_SUCCESS;
}
i) (1p)
#include <stdlib.h>
#include <stdio.h>



Thomas Padron-McCarthy (thomas.padron-mccarthy@oru.se), 4 juni 2009