Programmering C: Lösningar till tentamen 2017-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 (1 p)

a) 10

b) 11

c) 12

d) -13

Uppgift 2 (3 p)

int add_matrix(int m[5][5]) {
    int sum = 0;
    for (int i = 0; i < 5; ++i)
        for (int j = 0; j < 5; ++j)
            sum += m[i][j];
    return sum;
}

Uppgift 3 (5 p)

#include <stdio.h>

int main(void) {
    int storlek, rad, kolumn;

    printf("Hur stort ska X:et vara? ");
    scanf("%d", &storlek);
    for (rad = 0; rad < storlek; ++rad) {
        for (kolumn = 0; kolumn < storlek; ++kolumn) {
            if (kolumn == rad || kolumn == storlek - rad - 1)
                putchar('*');
            else
                putchar(' ');
        }
        putchar('\n');
    }
}

Uppgift 4 (8 p)

a) (6p)

int count_words(char *str) {
    int length, nr_words, inside_word;

    length = strlen(str);
    nr_words = 0;
    inside_word = 0;

    for (int i = 0; i < length; ++i) {
	if (inside_word && str[i] == ' ')
		inside_word = 0;
	else if (!inside_word && str[i] != ' ') {
		inside_word = 1;
		++nr_words;
	}
    }

    return nr_words;
} // count_words

b) (2p)

int main(void) {
    char line[1000 + 1 + 1];

    // Repeat until empty line
    printf("Skriv en rad: ");
    fgets(line, sizeof line, stdin);
    while (line[0] != '\n') {
        // Remove end-of-line character
        if (line[strlen(line) - 1] == '\n')
            line[strlen(line) - 1] = '\0';
        printf("Antal ord: %d\n", count_words(line));
        printf("Skriv en rad: ");
        fgets(line, sizeof line, stdin);
    }
} // main

Uppgift 5 (11 p)

Heltal ska lagras i en länkad lista.

a) (1p) Definiera de datatyper och variabler som behövs.

struct Link {
    int data;
    struct Link *next;
};

struct Link *first = NULL;

b) (3p) Skriv funktionen add_number_first, som tar ett heltal som argument och på lämpligt sätt stoppar in det först i den länkade listan.

void add_number_first(int data) {
    struct Link *new = malloc(sizeof(struct Link));
    new->data = data;
    new->next = first;
    first = new;
}
Ovanstående lösning förutsätter att pekaren till första elementet i listan finns i en globalt tillgänglig variabel. Man brukar vilja undvika globala variabler, och här är en annan lösning där man i stället ska skicka en pekare till den pekarvariabeln:
void add_number_first(struct Link **firstp, int data) {
    struct Link *new = malloc(sizeof(struct Link));
    new->data = data;
    new->next = *firstp;
    *firstp = new;
}

c) (2p) Skriv funktionen sum_list, som returnerar summan av alla talen i listan.

int sum_list(void) {
    struct Link *this = first;
    int sum = 0;
    while (this != NULL) {
        sum += this->data;
        this = this->next;
    }
    return sum;
}

d) (2p) Skriv funktionen in_list, som tar ett heltal som argument, och som returnerar 1 om talet finns i listan. Om talet inte finns i listan ska 0 returneras.

int in_list(int wanted) {
    struct Link *this = first;
    while (this != NULL) {
        if (this->data == wanted)
            return 1;
        this = this->next;
    }
    return 0;
}

e) (3p) Skriv en main-funktion som läser in heltal från standardinmatningen ända tills talet noll lästs in, som mellanlagrar talen i en länkad lista med hjälp av funktionerna ovan, och till sist skriver ut talens summa.

int main(void) {
    int number;
    printf("Mata in heltal. Avsluta med 0.\n");
    scanf("%d", &number);
    while (number != 0) {
        add_number_first(&first, number);
        scanf("%d", &number);
    }
    printf("Summan: %d\n", sum_list());
} // main

Uppgift 6 (7 p)

Vi ska skriva ett par funktioner som arbetar med textfiler.

a) (3p)

// 0 = ok, -1 = fail
int print_file_content(char* file_name) {
    FILE *f = fopen(file_name, "r");
    if (f == NULL)
        return -1;
    int c;
    while ((c = getc(f)) != EOF)
        putchar(c);
    fclose(f);
    return 0;
}

b) (4p)

void print_help(char* subject) {
    char file_name[2000]; // We just hope it's big enough
    snprintf(file_name, sizeof file_name, "%s.help", subject);
    if (print_file_content(file_name) == -1)
        printf("Tyvärr finns ingen hjälpinformation om '%s'.\n", subject);
}


Thomas Padron-McCarthy (thomas.padron-mccarthy@oru.se), 30 januari 2017