Programmering C: Lösningar till tentamen 2016-01-13

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

Hej!
Hej!
a = 5, b = 5, x = 0.000000, y = odefinierat
Odefinierat betyder att utskriften kan bli vad som helst. Variabeln y har inte fått något startvärde, och då säger C-standarden att vad som helst kan hända. En del kompilatorer lägger in värdet noll i variabeln från början, och i en del blir variabelns startvärde bara vad det nu var som råkade finnas på den platsen i minnet. Även helt andra saker, som att datorn smälter, är ett tillåtet beteende enligt C-standarden.

När jag provkörde skrev programmet ut y = 2.000000.

Uppgift 2 (4 p)

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

int main(void) {
    double x, y;

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

    double divisor = x*y + 1;

    if (divisor == 0) {
        printf("x*y + 1 får inte vara noll.\n");
        exit(EXIT_FAILURE);
    }

    double radicand = x*x - y*y;

    if (radicand <= 0) {
        printf("Uttrycket under roten får inte vara noll eller negativt.\n");
        exit(EXIT_FAILURE);
    }

    double radix = sqrt(radicand);
    double result = 1.0 / radix * pow(radix / divisor - radix, 3);

    printf("Resultat: %f\n", result);

    return EXIT_SUCCESS;
}

Uppgift 3 (3 p)

#include <stdio.h>

int main(void) {
    int tal, hojd, bredd;

    printf("Ange ett tvåsiffrigt heltal: ");
    scanf("%d", &tal);

    hojd = tal / 10;
    bredd = tal % 10;

    printf("\n");

    for (int y = 0; y < hojd; ++y) {
        for (int x = 0; x < bredd; ++x) {
            printf("*");
        }
        printf("\n");
    }

    return 0;
}

Uppgift 4 (10 p)

a) (1p)
#define MAX_ROBOTAR 100
#define MAX_NAMN 20
#define MAX_X 1000 // Koordinaterna går från 0 till MAX_X - 1
#define MAX_Y 1000 // Dito
b) (2p)
struct Robot {
    int nummer;
    char namn[MAX_NAMN + 1];
    int x;
    int y;
};
typedef struct Robot Robot; // Så man kan skriva bara "Robot"
c) (2p)
void visa_robot(Robot r) {
    printf("Nummer: %d\n", r.nummer);
    printf("Namn: %s\n", r.namn);
    printf("Position: x = %d, y = %d\n", r.x, r.y);
}
d) (3p)
Robot las_robot(void) {
    Robot r;
    printf("Ange robotens nummer: ");
    scanf("%d", &r.nummer);
    printf("Ange robotens namn: ");
    scanf("%s", r.namn);
    printf("Ange robotens x-koordinat: ");
    scanf("%d", &r.x);
    printf("Ange robotens y-koordinat: ");
    scanf("%d", &r.y);
    return r;
}
e) (2p)
int main(void) {
    Robot robot1 = las_robot();
    Robot robot2 = las_robot();
    visa_robot(robot1);
    visa_robot(robot2);
}

Uppgift 5 (11 p)

a) (4p)
void kolla_namnen(Robot robotar[], int antal_robotar) {
    for (int i = 0; i < antal_robotar; ++i) {
        for (int j = i + 1; j < antal_robotar; ++j) {
            if (strcmp(robotar[i].namn, robotar[j].namn) == 0) {
                printf("Både robot %d och robot %d heter '%s'.\n",
                       robotar[i].nummer, robotar[j].nummer, robotar[i].namn);
            }
        }
    }
}
b) (3p)
void placera_ut(Robot *robotar, int antal_robotar, int arena[MAX_X][MAX_Y]) {
    for (int i = 0; i < antal_robotar; ++i)
        arena[robotar[i].x][robotar[i].y] += 1;
}
c) (3p)
void kolla_arenan(int arena[MAX_X][MAX_Y]) {
    for (int x = 0; x < MAX_X; ++x) {
        for (int y = 0; y < MAX_Y; ++y) {
            if (arena[x][y] > 1)
                printf("%d robotar på position x = %d, y = %d\n", arena[x][y], x, y);
        }
    }
}
d) (1p)

Nej. Numreringen av positionerna i arrayer i C börjar med noll, och går till storleken minus ett. Så det högsta tal som kan användas i koordinaterna är 99.

Uppgift 6 (10 p)

a) (4p)
void spara_robotar(char *filnamn, Robot robotar[], int antal_robotar) {
    FILE *tsut = fopen(filnamn, "w");
    if (tsut == NULL) {
        fprintf(stderr, "Kunde inte skriva filen '%s'.\n", filnamn);
        exit(EXIT_FAILURE);
    }
    for (int i = 0; i < antal_robotar; ++i)
        fprintf(tsut, "%d %s %d %d\n",
                robotar[i].nummer, robotar[i].namn, robotar[i].x, robotar[i].y);
    fclose(tsut);
}
b) (1p)
spara_robotar("robotar.txt", robotar, antal_robotar);
c) (4p)
void hemta_robotar(char *filnamn, Robot robotar[], int *antal_robotar) {
    FILE *tsin = fopen(filnamn, "r");
    if (tsin == NULL) {
        fprintf(stderr, "Kunde inte läsa filen '%s'.\n", filnamn);
        exit(EXIT_FAILURE);
    }
    int antal = 0;
    while (fscanf(tsin, "%d %s %d %d",
                  &robotar[antal].nummer,
                  robotar[antal].namn,
                  &robotar[antal].x,
                  &robotar[antal].y) == 4);
    fclose(tsin);
    *antal_robotar = antal;
}
d) (1p)
hemta_robotar("robotar.txt", robotar, &antal_robotar);


Thomas Padron-McCarthy (thomas.padron-mccarthy@oru.se), 13 januari 2016