Umu logo

Umeå Universitet
Institutionen för datavetenskap
Programmeringsteknik för tekniska fysiker


Tentamen 990825

Uppgift 1 (3 + 1 + 1 p)

a)

Skriv funktionen


void write_replace(char *s, char a, char b)

som tar en sträng s och två bokstäver a och b som argument. Funktionen skall skriva ut strängen s, men byta ut bokstaven a mot b överallt i utskriften.

Anropet write_replace("Pappa mu", 'p', 'm') skall ge utskriften "Pamma mu".

b)

Standardbiblioteksfunktionen rand() ger ett slumptal i intervallet [0, RAND_MAX], där RAND_MAX är en konstant som definieras i headerfilerna. En programmerare som vill använda slumptalsfunktionen för att generera tärningsslag i intervallet 1-6 har skrivit följande makro


#define DIE ((rand()/(RAND_MAX+1))*6 + 1)

Vid en testkörning upptäcker programmeraren att tärningen hela tiden visar samma värde. Varför och vilket är värdet?

c)

Nämn en av anledningarna till varför man programmerar i C i stället för att skriva program direkt i maskinkod.

Uppgift 2 (2 + 2 + 1 p)

a)

En matematiker har upptäckt en ny viktig grupp av tal, x-tal. Ett x-tal definieras på följande sätt

Skriv en rekursiv funktion


int xtal(int n)

som returnerar sant om n är ett x-tal och falskt i annat fall.

b)

Förklara vad den rekursiva funktionen nedan gör (vilket problem löser den) och skriv en iterativ (icke-rekursiv) funktion som gör samma sak.


int secret(int a[], int n)

{

    return n > 0 ? *a + secret(a+1,n-1) : 0;

}

c)

Varför bör man som programmerare hellre använda lokala variabler än globala när det är möjligt?

Uppgift 3 (3 + 2 p)

a)

En länkad lista är definierad som


struct list_s {

    int    data;

    struct list_s *next;

};

Next-pekaren pekar på nästa element i listan och är NULL för det sista elementet i listan. Skriv funktionen


void zero_list(struct list_s *first)

Funktionen skall ta en pekare till en lista som argument och sätta alla datavärden i listan till 0.

c)

Vad skrivs ut av följande program? Motivera ditt svar genom att rita en figur som visar vart alla pekare pekar.


#include <stdio.h>


int main(void)

{

    int a[10] = {0,1,2,3,4,5,6,7,8,9};

    int *p[3] = {a, a+3, &a[5]};


    printf("%i %i %i", **p, (*(p+1))[1], p[2][-2]);

}

Uppgift 4 (5 p)

En programmerare använder en uppsättning av 110 filer för att lagra numerisk information om olika grundämnen. Varje fil har namn efter det grundämne den innehåller information om, med tillägget ".txt". Filen om koppar heter till exempel koppar.txt. Innehållet i en fil består av ett antal namn på egenskaper följda av egenskapens värde. Filen koppar.txt kan t ex se ut som.


atomnummer 29

atommassa 63.546

specifik_vikt 8.96

marknadspris 107.4

Egenskaperna är inte ordnade i någon speciell ordning, och alla egenskaper finns inte nödvändigtvis med för alla grundämnen. Filen xenon.txt kan t ex se ut som


specifik_vikt 0.005887

kokpunkt -107

atomnummer 54

Skriv funktionen


double egenskapsvarde(char *grundamne, char *egenskap)

Funktionen tar som argument namnet på ett grundämne och namnet på en egenskap. Den ska använda filerna som beskrivits ovan för att ta reda på egenskapens värde och returnera det. Om funktionen anropas som egenskapsvarde("koppar", "specifik_vikt") skall den t ex returnera 8.96.

Om någonting går fel, t ex att filen för grundämnet inte hittas eller att den sökta egenskapen inte finns lagrad för det grundämnet, så skall funktionen returnera DBL_MAX. (Detta är en konstant som finns definierad i header-filen float.h) Inget felmeddelande behöver skrivas ut.

Egenskapsnamnen är alltid ett enda ord. Inget egenskapsnamn eller grundämnesnamn är längre än 40 bokstäver.

Uppgift 5 (3 + 2 p)

a)

En internetbutik använder följande datastrukturer för att lagra information om de köp som en viss kund har gjort


struct vara_s {         /* Lagrar information om en vara. */

    int    varunr;         /* Ett ID-nummer för varan. */

    double pris;     /* Varans pris. */

};


struct kop_s {            /* Information om ett visst köptillfälle. */

    int antal_varor;      /* Antal varor som kunden har köpt */

    struct vara_s *varor; /* Pekare till vektor med varor. */

};

Skriv funktionen


double totalpris(struct kop_s *kop)

Funktionen skall summera priset för alla varor som ingår i köptillfället kop och returnera resultatet.

b)

Skriv funktionen


void lagg_till_vara(struct kop_s *kop, struct vara_s *vara)

Funktionen skall lägga till varan vara till köptillfället kop. Observera att funktionen måste se till att det finns tillräckligt med plats i pekaren varor för att rymma den nya varan.

Uppgift 6 (4 + 1 p)

a)

Skriv funktionen


void stapel(int h1, int h2, int h3)

Funktionen skall skriva ut ett stående stapeldiagram med tre staplar. Varje stapel byggs upp av tecknet '*' och är tre tecken bred. Det skall vara två teckens mellanrum mellan staplarna. Variablerna h1, h2 och h3 anger höjden (i antal tecken) på de tre staplarna.

Anropet stapel(3,5,2) skall ge utskriften


     ***

     ***

***  ***

***  ***  ***

***  ***  ***

Om uppgiften verkar för svår kan du i stället låta funktionen skriva ut ett liggande diagram


***

***

***


******

******

******


**

**

**

En sådan lösning kan dock inte ge mer än 2 poäng.

b)

Antag att filen linjer.h innehåller de abstrakta datatyperna punkt_t och linje_t för att hantera linjer och punkter, med bland annat följande funktioner:


/* Skapar en punkt med koordinaterna (x,y). */

punkt_t skapa_punkt(double x, double y);


/* Returnerar en punkts x-koordinat. */

double punkt_x(punkt_t p);


/* Returnerar en punkts y-koordinat. */

double punkt_y(punkt_t p);


/* Skapar en linje som går mellan punkterna p1 och p2 */

linje_t skapa_linje(punkt_t p1, punkt_t p2);


/* Returnerar sant om linjerna l1 och l2 skär varandra. */

int skar(linje_t l1, linje_t l2);


/* Returnerar skärningspunkten mellan linjerna l1 och l2. Denna funktion

   får endast anropas om linjerna skär varandra. */

punkt_t skarningspunkt(linje_t l1, linje_t l2);

Skriv ett program som läser in koordinaterna för två linjer och avgör om de skär varandra och i så fall i vilken punkt. Resultatet skall skrivas ut på skärmen.


HTML-konverterat av Niklas Frykholm, augusti 1999