Umu logo

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


Lösningsförslag 990825

Uppgift 1

a)


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

{

  while (*s) {

    putchar (*s == a ? b : *s);

    s++;

  }

}

b)

Tärningen kommer alltid att visa värdet 1.

Problemet är att vi dividerar rand() med RAND_MAX + 1 innan vi multiplicerar med 6. Eftersom detta är en heltalsdivision och eftersom rand() alltid är mindre än RAND_MAX + 1 så kommer resultatet av denna division alltid att bli 0.

Här är två sätt att göra en tärning som funkar:


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

#define DIE2  (rand()%6 + 1)

c)

Några skäl är t ex

Uppgift 2

a)


int xtal(int n)

{

  assert(n>=0);


  if (n==1)

    return 1;

  else if (n==0)

    return 0;

  else

    return xtal(((n/2)*(n/3))%(n-1));

}

b)

Funktionen summerar de n första talen i vektorn a.


int iter(int a[], int n)

{

  int i, sum=0;

  for (i=0; i<n; i++)

    sum +=a[i];

  return sum;

}

c)

En global variabel kan ändras var som helst i programmet. Det gör det svårt att överblicka när och hur variabeln ändras och fel kan lätt smyga sig in, som i programmet nedan. (Kan du se varför det blir fel?)


/* ----------------------------------------------------------------------

  Program som skriver ut multiplikationstabellerna för talen 1 - 10. 

---------------------------------------------------------------------- */


#include <stdio.h>


int i;


void print_tabell(int n)

{

  printf("\n\n%i:ANS TABELL\n\n", n);

  for (i=1; i<=10; i++)

    printf ("%i * %i = %i\n", i, n, n*i);

}


int main(void)

{

  for (i=1; i<=10; i++)

    print_tabell(i);

}

Uppgift 3


void zero_list(struct list_s *first)

{

  while (first != NULL) {

    first->data = 0;

    first = first->next;

  }

}

Eller rekursivt


void zero_list(struct list_s *first)

{

  if (first != NULL) {

    first->data = 0;

    zero_list(first->next);

  }

}

b)

Pekarna kommer att peka på följande sätt.


p[0] --------> a[0] (0)    p[0][0] <=> **p

p[1] -----+    a[1] (1)

p[2] --+  |    a[2] (2)

       |  +--> a[3] (3)    p[1][0], p[2][-2]

       |       a[4] (4)    p[1][1] <=> (*(p+1))[1], p[2][-1]

       +-----> a[5] (5)    p[2][0]

               a[6] (6)

               a[7] (7)

               a[8] (8)

               a[9] (9)

Utskriften blir 0 4 3.

Uppgift 4


double egenskapsvarde(char *grundamne, char *egenskap)

{

  char filnamn[50], fil_eg[50];

  double varde;

  FILE *f;


  strcpy(filnamn, grundamne);

  strcat(filnamn, ".txt");

  f = fopen(filnamn, "r");

  if (f==NULL)

    return DBL_MAX;

  while (fscanf(f, "%s %lf", fil_eg, &varde) == 2)

    if (!strcmp(fil_eg, egenskap)) {

      fclose(f);

      return varde;

    }

  fclose(f);

  return DBL_MAX;

}

Uppgift 5

a)


double totalpris(struct kop_s *kop)

{

  int i;

  double res = 0;


  for (i=0; i<kop->antal_varor; i++)

    res += kop->varor[i].pris;

  return res;

}

b)


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

{

  kop->antal_varor++;

  kop->varor = realloc(kop->varor, kop->antal_varor * sizeof(struct vara_s));

  kop->varor[kop->antal_varor - 1] = *vara;

}

Uppgift 6

a)


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

{

  int max, i;


  max = h1 > h2 ? h1 : h2;

  max = max > h3 ? max : h3;


  for (i=max; i>=1; i--)

    printf("%s  %s  %s\n", h1>=i ? "***" : "   ", h2>=i ? "***" : "   ",

       h3>=i ? "***" : "   ");

}

Och här är en liggande variant.


/* Skriver ut en liggande stapel av längd h. */

void print1(int h)

{

  int i,j;

  for (i=1; i<=3; i++) {

    for (j=1; j<=h; j++)

      putchar('*');

    putchar('\n');

  }

}


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

{

  print1(h1); printf("\n\n");

  print1(h2); printf("\n\n");

  print1(h3);

}

b)


int main(void)

{

  double x[2], y[2];

  punkt_t p[2];

  linje_t l[2];

  int i;


  for (i=0; i<2; i++) {

    printf("Ange linjens koordinater (x1, y1, x2, y2): ");

    scanf("%lf %lf %lf %lf", x, y, x+1, y+1);

    p[0] = skapa_punkt(x[0],y[0]);

    p[1] = skapa_punkt(x[1],y[1]);

    l[i] = skapa_linje(p[0],p[1]);

  }


  if (skar(l[0], l[1])) {

    punkt_t skarning = skarningspunkt(l[0], l[1]);

    printf("Skärningspunkt: (%f, %f)\n", punkt_x(skarning), punkt_y(skarning));

  }

  else

    printf("Linjerna skär inte varandra.");

}


HTML-konverterat av Niklas Frykholm, augusti 1999