Programmering C: Lösningar till tentamen 2008-03-08

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 (1 p)

a) 1

b) -1

c) 5

Uppgift 2 (1 p)

i = 13, k = 5, n = 5

Uppgift 3 (1 p)

float temp;
temp = x;
x = y;
y = temp;

Uppgift 4 (1 p)

int max(int tal1, int tal2) {
    if (tal1 > tal2)
        return tal1;
    else
        return tal2;
}

Uppgift 5 (4 p)

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

int main(void) {
    double x, y, R;

    printf("Ange x: ");
    scanf("%lf", &x);
    printf("Ange y: ");
    scanf("%lf", &y);
    printf("Ange R: ");
    scanf("%lf", &R);

    double produkten = x * y * R;

    if (produkten <= 0)
        printf("Tyvärr går uttrycket inte att beräkna.\n"
               "Vi beklagar att det blev så här.\n");
    else {
        double differensen = 1 - 1 / sqrt(produkten);
        double uttrycket = differensen * differensen * differensen;
        printf("Värde: %f\n", uttrycket);
    }
        
    return 0;
}

Uppgift 6 (1 p)

struct Donation {
    int belopp;
    char namn[40+1];
    char hemstat[40+1];
};

Uppgift 7 (1 p)

struct Donation d = { 1000, "J. R. Ewing", "Texas" };

Uppgift 8 (2 p)

void visa_donation(struct Donation d) {
    printf("Belopp: %d\n", d.belopp);
    printf("Givare: %s\n", d.namn);
    printf("Stat: %s\n", d.hemstat);
}

Uppgift 9 (2 p)

void las_donation(struct Donation *p) {
    printf("Skriv in data om en donation!\n");
    printf("Ange belopp: ");
    scanf("%d", &p->belopp);
    while (getchar() != '\n')
        ;
    printf("Ange givarens namn: ");
    gets(p->namn); // Använd inte gets i riktiga program!
    printf("Ange givarens hemstat: ");
    gets(p->hemstat); // Använd inte gets i riktiga program!
}

Uppgift 10 (2 p)

int main(void) {
    struct Donation d1, d2;
    las_donation(&d1);
    las_donation(&d2);
    visa_donation(d1);
    visa_donation(d2);
    return 0;
}

Uppgift 11 (4 p)

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

// Här ska det finnas definitioner av posttypen, mm

int main(void) {
    struct Donation d;
    FILE *f;
    f = fopen("donationer.txt", "w");
    if (f == NULL) {
        fprintf(stderr, "Kunde inte öppna filen 'donationer.txt'.\n");
        fprintf(stderr, "Möjlig orsak: %s (felkod %d)\n", strerror(errno), errno);
        exit(EXIT_FAILURE);
    }
    printf("Skriv in donationer.\n");
    printf("Avsluta med en donation med beloppet 0.\n");
    las_donation(&d);
    while (d.belopp != 0) {
        fprintf(f, "%d\n%s\n%s\n", d.belopp, d.namn, d.hemstat);
        las_donation(&d);
    }
    fclose(f);
    return 0;
}

Uppgift 12 (5 p)

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

// Här ska det finnas definitioner av posttypen, mm

int main(void) {
    FILE *f;
    f = fopen("donationer.txt", "r");
    if (f == NULL) {
        fprintf(stderr, "Kunde inte öppna filen 'donationer.txt'.\n");
        fprintf(stderr, "Möjlig orsak: %s (felkod %d)\n", strerror(errno), errno);
        exit(EXIT_FAILURE);
    }
    struct Donation d;
    struct Donation storsta = { -1, "", "" };
    int summa = 0;
    while (fscanf(f, "%d", &d.belopp) == 1) {
        while (getc(f) != '\n')
            ;
        fgets(d.namn, sizeof d.namn, f);
        d.namn[strlen(d.namn) - 1] = '\0';
        fgets(d.hemstat, sizeof d.hemstat, f);
        d.hemstat[strlen(d.hemstat) - 1] = '\0';
        if (d.belopp > storsta.belopp)
            storsta = d;
        summa += d.belopp;
    }
    fclose(f);

    printf("Summa: %d dollar\n", summa);
    printf("Största donationen:\n");
    visa_donation(storsta);

    return 0;
}
Kommentar: Den här lösningen förutsätter att det finns minst en donation på filen. Annars kommer programmet att skriva ut "-1"-donationen som den största.

Uppgift 13 (4 p)

#include <stdlib.h>
#include <string.h>

int main(void) {
    char s1[100 + 1 + 1]; // 100 tecken plus '\n' plus '\0'
    char s2[100 + 1 + 1];

    fgets(s1, sizeof s1, stdin);
    fgets(s2, sizeof s2, stdin);

    if (strlen(s1) > strlen(s2))
        fputs(s1, stdout);
    else
        fputs(s2, stdout);

    return 0;
}

Uppgift 14 (5 p)

#include <stdlib.h>
#include <stdio.h>

int main(void) {
    double x, x_summa = 0, y, y_summa = 0;
    int antal = 0;
    printf("Ange koordinater som x y. Avsluta med 0 0.\n");
    scanf("%lf %lf", &x, &y);
    while (x != 0 || y != 0) {
        x_summa += x;
        y_summa += y;
        ++antal;
        scanf("%lf %lf", &x, &y);
    }
    printf("Placera basstationen i x = %f, y = %f\n",
           x_summa / antal,
           y_summa / antal);
    return 0;
}

Uppgift 15 (6 p)

Ett alternativ:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main(void) {
    int antal_kursvarderingar;

    printf("Ange antalet kursvärderingar: ");
    scanf("%d", &antal_kursvarderingar);

    srand(time(NULL));

    for (int fraga = 1; fraga <= 10; ++fraga) {
        int antalen[5] = { 0, 0, 0, 0, 0 }; // 5, så vi kan använda 1-4
        int betygssumma = 0;
        for (int k = 0; k < antal_kursvarderingar; ++k) {
            int detta_betyg = rand() % 4 + 1;
            antalen[detta_betyg]++;
            betygssumma += detta_betyg;
        }
        printf("Fråga %d, ", fraga);
        for (int betyg = 1; betyg <= 4; ++betyg) {
            printf("antal %d:or: %d, ", betyg, antalen[betyg]);
        }
        printf("medelvärde: %.2f\n", 1.0 * betygssumma / antal_kursvarderingar);
    }
        
    return 0;
}
Ett annat alternativ:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main(void) {
    int antal_kursvarderingar;

    printf("Ange antalet kursvärderingar: ");
    scanf("%d", &antal_kursvarderingar);

    srand(time(NULL));

    for (int i = 1; i <= 10; ++i) {
	printf("Fråga %d, ", i);
	int antal_kvar = antal_kursvarderingar;
	int betygen[5]; // 5, så vi kan använda 1-4
	for (int b = 1; b <= 4; ++b) {
	    if (b == 4) {
		betygen[b] = antal_kvar;
	    }
	    else {
		betygen[b] = rand() % antal_kvar;
		antal_kvar -= betygen[b];
	    }
	}
	for (int b = 1; b <= 4; ++b) {
	    printf("antal %d:or: %d, ", b, betygen[b]);
	}
	printf("medelvärde: %.2f\n",
	       1.0 * (1*betygen[1] + 2*betygen[2] + 3*betygen[3] + 4*betygen[4]) / antal_kursvarderingar);
    }
	
    return 0;
}


Thomas Padron-McCarthy (Thomas.Padron-McCarthy@tech.oru.se) 12 mars 2008