Tentamen för teknisk kemi, 10p, moment 1 29 november 1999 Skrivtid 9-15 Hjälpmedel: av följande böcker. - U. Bilting och J. Skansholm: Vägen till C - A. Kelley & I. Pohl: A Book on C Maxpoäng: Gräns för 3: (50 %) Gräns för 4: (65 %) Gräns för 5: (80 %) Uppgifterna är slumpmässigt ordnade. Börja varje uppgift på ett blad, skriv namn, personnummer, uppgiftsnummer och sidnummer på därför avsedd plats på varje sida och använd endast ena sidan av varje papper. Uttryck dig. Alla! "# $%&' ()")* tolkas till din +, -./01. Gör endast det uppgiften säger, konstruera till exempel ingen huvudfunktion i onödan. Gör ej heller några utskrifter till skärmen eller inläsningar från tangentbordet om det inte anges i uppgiften. Tänk på att indentera den källkod du skriver. Lägg in /* kommentarer */ om du gör något som ej är uppenbart. Även om du inte klarar av hela uppgiften kan du få poäng. Lös så mycket du kan! Tentamens genomgång hålls den 9/12 kl 13-15 i sal MA112. Där kan ni kvittera ut er tentamen. Fråga om någonting är oklart! (Lärare kommer förbi kl 11.00 och 13.00) Lycka Till! 1
243357689;: (2 + 2 + 2 p) (a) Ge två motiveringar till att man bör använda symboliska konstanter i stället för att använda värdena direkt. T.ex. använda PI istället för 3.14, givet följande: #define PI 3.14 (b) Ge två anledningar till att man kan vilja skicka pekare till ett minnesobjekt istället för själva objektet som argument till funktioner. Motivera. (c) Ge två anledningar till att man bör undvika att använda globala variabler. Motivera. <4==>7?@ACB (2 + 2 p) (a) Följande program innehåller ett antal syntax fel (som kompilatorn upptäcker). Vilka? Hur ska det egentligen vara? (Använd gärna radnumren för att referera till satserna.) Minuspoäng utdelas för korrigering av saker som inte är felaktiga. Ni kan dock aldrig få mindre än 0 poäng totalt. 1: #include <stdio.h> 2: int main(void); 3: { 4: int y, *p; 5: 6: p = &y; 7: printf(ge ett tal); 8: scanf( %d, p); 9: if (0 <= y <= 10) { 10: printf( Talet du skrev in: %d, p); 11: printf( ligger mellan 0 och 10.\n ); 12: else ; 13: return 0; 14: (b) Programmet ovan förväntas läsa in ett heltal och sedan skriva ut lite text och det inlästa talet om talet ligger mellan 0 och 10 (inklusive 0 och 10), annars ska ingen mer text skrivas ut. Då finns det två semantiska ( logiska ) fel som inte upptäcks av kompilatorn. Vilka? Visa också hur det borde se ut, utan att göra några större förändringar av den givna koden. 2
D4EEF7GHICJ (3 + 2 p) (a) Skriv en icke-rekursiv funktion g som beräknar och returnerar samma sak som den rekursiva funktionen f nedan. (Tips: för att förstå vad funktionen f gör, prova korta exempel). int f(int n, int v[]) { int a; if (n <= 1) return (v[0]); else { a = f(n-1, &v[1]); return ((v[0] > a)? v[0] : a); (b) Vad skulle en körning av följande program som anropar funktionen f ovan (eller din funktion g) resultera i för utskrift? #include <stdio.h> /* funktionsprototyp */ int f(int, int*); /* eller int g(int, int*); */ int main(void) { int numbers[10] = {0, 0, 10, 20, 4, 5, 1, 0, 88, 9; /* tre anrop av f (eller g) */ printf( %d\n, f(10, numbers)); printf( %d\n, f(5, numbers)); printf( %d\n, f(4, &numbers[4])); return 0; 3
K4LLM7NOPRQ (5 p) Vad skrivs ut av följande kod? #include <stdio.h> int main(void) { int v[8] = {1, 2, 3, 4, 5, 6, 7, 8; int *p[2] = {v; int **h; p[1] = v + 2; h = p; printf("%d %d\n", *p[1], h[0][3]); p[0][2] += 5; **p += 2; v[3] = h[0][2] (*p[1] += 10); printf("%d %d %d\n", **h, v[3], (*h)[2]); return 0; 4
S4TTU7VWXRY (4 p) Bland det mest respektlösa man kan bli utsatt för är att få ett "personligt" standardiserat reklambrev, med det egna namnet instoppat i texten. Implementera följande funktion (och sälj den aldrig till en krämare): /* Kopiera textfilen Z[]\^]_ till textfilen `a]bc]d, men byt ut alla förekomster av tecknet @ mot innehållet i strängen e]fg]h */ void personalize(char *fname, char *gname, char *name); Filerna är specificerade via sina fysiska namn, så du måste börja med att koppla de fysiska namnen till variabler av typen pekare på FILE. Exempel, name = "Jan", ger: fname Det börjar bli dags att tänka på en julklapp till farmor nu, @, och eftersom jag vet att du har god smak... gname Det börjar bli dags att tänka på en julklapp till farmor nu, Jan, och eftersom jag vet att du har god smak... 5
i4jjk7lmnro (3 +1 p) (a) För att beräkna en approximation till ln(1+p ), där q är ett reellt tal och 1< r 1, kan man använda sig av följande serie: ln(1+s ) = t u 2v 2 + w 3x 3 y 4 /4 + z 5{ 5 7 6~ 6 +... (-1 < 1) Er uppgift är att skriva en funktion, lnapprox, som använder sig av serien ovan för att beräkna en approximation till ln(1+ ). double lnapprox(double x, int n); där n är antalet termer från serien ovan som ska ingå i approximationen. Ni måste kontrollera att inparametrarna har rimliga/korrekta värden. OBS! Ni får ej använda er av pow()-funktionen i math.h (b) Vilket problem kan uppstå om du anropar funktionen ovan med höga värden på n? Motivera. 4 ƒ7 R (3 + 2 p) I ett program så lagrar vi födelsedatum för ett antal personer som en vektor med long, enligt följande exempel long datum[] = {731126, 760606, 481012, 801102, 491112, -1; Som framgår av exemplet så markeras den sista positionen i vektorn med talet -1. I exemplet ovan är den första personen född den 26 november 1973. Den andra personen är född den 6 juni 1976, osv. (a) Skriv en ˆ Š ŒŽ för att utifrån en sådan här vektor avgöra om det finns minst två personer i vektorn som fyller år på samma dag. (b) Implementera din algoritm som en C-funktion med följande funktionsprototyp int samma_fodelsedag(long datum[]); där datum är en vektor med födelsedatum lagrade enligt ovan. Funktionen skall returnera 1 om det finns minst två personer i vektorn som har samma födelsedag och 0 i annat fall. 6
4 7 R (1 + 2 + 4 p) Givet följande deklaration: typedef struct { char title[40]; char author[40]; unsigned NrOfPages; unsigned price; /* Priset i öre */ book; typedef struct { unsigned size; book b[maxsize]; library; (a) Komplettera ovanstående med en definition av MAXSIZE som ett makro med värdet femtiotusen. (b) Implementera följande funktion: void printbook(book b); Funktionen ska ge exempelvis följande utskrift (den kursiverade informationen hämtas ur b): Titel: Krig och fred Författare: Dostojevskij, Fjodor Antal sidor: 1000 Pris: 123 kr och 45 öre. Observera att b lagrar priset i ören, men priset ska skrivas ut i kronor och ören. Ni får förutsätta att b innehåller korrekt information. (c) Implementera följande funktion: /* Returnera, i parametern b, den billigaste boken i biblioteket L. */ void FindCheapestBook(library *L, book *b); Du får förutsätta att det finns minst en bok i L. Funktionen ska returnera, i parametern b, den billigaste boken i biblioteket L. 7