Umu logo

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


Niklas Frykholm, 24 februari 1999

Gruppövning 3 - Vektorer, strängar, pekare

1. Finn sex fel

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

void sort(char *s, int n);

/* Detta program läser in tre strängar och skriver ut
   dem i sorterad ordning. */
int main(void)
{
  char *s[3];
  int i;

  s[0] = s[1] = s[2] = malloc(100);

  for (i=0; i<3; i++)
    scanf("%s", &s[i]);

  sort(s,3);

  printf("\n%s", s);

  free(s[0]); free(s[1]); free(s[2]);
  return 0;
}

/* Sorterar en vektor med strängar i bokstavsordning. */
void sort(char *s, int n)
{
  int i, j;

  for (i=0; i<n-1; i++)
    for (j=i+1; j<n; j++)
      if (s[i] < s[j]) {
        s[i] = s[j];
        s[j] = s[i];
      }
}

2. Hisstopp

Skriv en funktion som beräknar hur många våningar en hiss har åkt sedan den installerades. Funktionen skall ta som indata de våningar som hissen har stannat på och ett heltal som anger storleken på fältet.

int akt_vaningar(int vaningsstopp[], int antal)

Exempel: Om hissen har stannat på våningarna 2, 4, -2 och 1 så har den åkt 11 våningar.

Om en hiss har åkt mer än 10 000 våningar är det dags för service. Skriv ett program som läser in ett antal våningsstopp från användaren och sedan skriver ut om det är dags för service eller inte. Använd dig av funktionen akt_vaningar.

3. Baklängessträng

Skriv ett program som läser in en sträng från användaren (med scanf("%s",s)) och sedan skriver ut strängen baklänges.

Skriv ditt program så att det enbart använder sig av pekare --- inte av vektorer och inte av indexvariabler.

4. Pekarträsk I

Vad kommer att skrivas ut av följande program? Motivera ditt svar ordentligt. Pröva att lösa uppgiften med alla de tre metoder som har visats på lektionen: grafiskt, med adresser och matematiskt.

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

int main(void)
{
    int **i;
    i = malloc(sizeof(int *)*3);
    *i = malloc(sizeof(int));
    **i = 5;
    *(i+1) = malloc(sizeof(int)*2);
    i[1][0] = 7;
    i[1][1] = i[0][0] + 4;
    i[2] = NULL;
    printf("%i", *(i[1]+1));
}

5. Pokerhänder

En hand i poker kan representeras som en vektor med fem heltal. int hand[5], där varje tal ligger i intervallet 0...51 (eftersom det finns 52 kort i leken). Man kan t ex tänka sig att låta 0 svara mot hjärter ess, 1 mot hjärter två,... 51 mot spader kung.

Skriv funktionen

int full_hand(int hand[5]);

Funktionen skall returnera sant om handen innehåller en kåk och falskt i annat fall.

Om du vill kan du prova att skriva funktioner också för andra pokerhänder, t ex par, två par, triss, fyrtal, färg och stege. Den sistnämnda är förmodligen den besvärligaste.

6. Kodade strängar

a)

Skriv en funktion som tar en sträng som argument (du kan förutsätta att strängen bara innehåller stora bokstäver ur det engelska alfabetet A-Z) och skriver ut den på kodad form. Koden som skall användas är

A -> B
B -> C
C -> D
...
Y -> Z
Z -> A

b)

Vad kommer att hända (vad skrivs ut) om ni anropar er funktion på följande sätt:

char *s = "HEMLIGT";
skriv_kod(s + 1);

Använd detta för att skriva en rekursiv variant av funktionen.

7. Matrismultiplikation

Skriv en funktion för att beräkna multiplikationen c = Ab, där A är en n x n matris och c och b är n x 1 vektorer.

void matrix_vector(int n, double A[], double b[], double c[]);

Tänk över följande:

8. Pekarträsk II

Vad kommer att skrivas ut av följande progrma. Motivera ditt svar.

#include <stdio.h>

int main(void)
{
    int i[] = {0,1,2,3,4,5,6,7,8,9};
    int *p1 = &i[0], *p2 = &i[2];
    *p1 = 10;
    *p2 = 11;
    p1[3] = 12;
    p2[-1] = 13;
    printf("%d", *(p1+1));
}

9. Söka bland lösenord

Om du skriver ypcat passwd vid Unix-prompten så kommer hela lösenordsfilen att skriva ut. Om du vill plocka ut raden för en viss person kan du skriva t ex ypcat passwd | grep niklasf. Raden som du får ut ser ut som

niklasf:PdxZOtU0dsLMU:4533:1101:Niklas Frykholm:/Home/staff/niklasf:/usr/local/bin/tcsh

Dom du ser består raden av sju olika fält åtskilda av kolon :. Det första fältet är användarnamnet, det andra lösenordet (på krypterad form) och det femte är det fullständiga namnet.

a)

Skriv funktionen

void read_fields(char *fields[7])

Funktionen tar som argument en vektor med sju stycken pekare till char. Den skall allokera minne för pekarna och läsa in de olika fälten, så att fields[0] efter anropet innehåller en pekare till strängen "niklasf", fields[1] till "PdxZOtU0dsLMU", och så vidare.

Tips: Använd getchar för att läsa in ett tecken i taget. När du läser in ':' eller '\n' har du kommit till slutet av ett fält.

b)

Använd din funktion för att skriva ett program som läser in en rad från lösenordsfilen och skriver ut den på formen:

Namn:             Niklas Frykholm
Användarnamn:     niklasf
Lösenord (kodat): PdxZOtU0dsLMU
Användar-ID:      4533
Grupp-ID:         1101
Hemkatalog:       /Home/staff/niklasf
Skalprogram:      /usr/local/bin/tcsh


© Niklas Frykholm, februari 1999