Systemnahe Programmierung in Chome Systemnahe Programmierung in C: Matrizen mit Deskriptoren und Feldern von Zeigern auf Felder Prof. Dr. Uwe Schmidt FH Wedel

Matrizen mit Deskriptoren und Feldern von Zeigern auf Felder

weiter

weiter

Implementierung von Matrizen als vollwertiger Datentyp

Matrizen
Die erste und zweite Lösung für die Verarbeitung von Matrizen haben noch den Mangel, dass die Dimensionen der Matrizen nicht in den Matrizen selbst, sondern extra in der Anwendung verwaltet werden müssen. Dieses ist nicht nur fehlerträchtig, die Operationen auf Matrizen bekommen auch längliche und unhandliche Parameterlisten.
 
Die Lösung für dieses Problem ist die Einführung einer Indirektstufe: Die Felder werden in einem Deskriptor gespeichert, in diesem werden zusätzlich die Dimensionen gespeichert und beim Erzeugen initialisiert.
 
In diesem Beispiel wird der Ansatz aus dem 2. Beispiel um Deskriptoren erweitert. Hierfür werden Records verwendet. Der Code aus dem 2. Beispiel kann also in großen Teilen übernommen werden.
 
Eine Operation, die beim Manipulieren von Matrizen, z.B. beim Berechnen von Determinanten, von Vorteil sein kann, ist das Vertauschen von Zeilen. Diese Operation ist mit der hier vorgestellten Implementierung sehr effizient umzusetzen (im Gegensatz zur 2. Lösung!(?)).
weiter

weiter

Die Schnittstelle: Matrix3.h

   1#ifndef Matrix3__
   2#define Matrix3__ 1
   3
   4typedef double Element;
   5
   6typedef Element *Row;
   7typedef Row *Rows;
   8
   9typedef struct
  10{
  11  Rows rows;
  12  Element *elems;
  13  int width;
  14  int height;
  15} *Matrix;
  16
  17/* constructor functions */
  18
  19extern Matrix newMatrix (int hint w);
  20extern Matrix zeroMatrix (int hint w);
  21extern Matrix unitMatrix (int hint w);
  22
  23/* destructor */
  24
  25extern void freeMatrix (Matrix m);
  26
  27/* matrix ops */
  28
  29extern Matrix addMatrix (Matrix m1Matrix m2);
  30extern Matrix transposeMatrix (Matrix m);
  31
  32/* element access ops */
  33
  34extern Element at (Matrix mint iint j);
  35extern Matrix setAt (Matrix mint iint jElement v);
  36
  37#endif
weiter

weiter

Die Implementierung: Matrix3.c

   1#include "Matrix3.h"
   2
   3#include <assert.h>
   4#include <stdio.h>
   5#include <stdlib.h>
   6
   7/*--------------------*/
   8
   9Matrix
  10newMatrix (int hint w)
  11{
  12  Matrix res = malloc (sizeof (*res));
  13
  14  if (res)
  15    {
  16      res->rows = malloc (h * sizeof (Row));
  17      res->elems = malloc (h * w * sizeof (Element));
  18      res->width = w;
  19      res->height = h;
  20
  21      {
  22        Rows rs = res->rows;
  23        Row r = res->elems;
  24
  25        if (rs && r)
  26          {
  27            while (h--)
  28              {
  29                *rs++ = r;
  30                r += w;
  31              }
  32
  33            return res;
  34          }
  35      }
  36    }
  37
  38  /* heap overflow */
  39  perror ("newMatrix: can't allocate matix");
  40  exit (1);
  41}
  42
  43/*--------------------*/
  44
  45void
  46freeMatrix (Matrix m)
  47{
  48  free (m->elems);
  49  free (m->rows);
  50  free (m);
  51}
  52
  53/*--------------------*/
  54
  55Matrix
  56zeroMatrix (int hint w)
  57{
  58  Matrix res = newMatrix (hw);
  59  Element *p = res->elems;
  60
  61  int len = w * h;
  62  while (len--)
  63    {
  64      *p++ = 0.0;
  65    }
  66
  67  return res;
  68}
  69
  70/*--------------------*/
  71
  72Matrix
  73unitMatrix (int hint w)
  74{
  75  Matrix res = zeroMatrix (hw);
  76  Rows r = res->rows;
  77
  78  int i;
  79  for (i = 0; i < w && i < h++i)
  80    {
  81      r[i][i] = 1.0;
  82    }
  83
  84  return res;
  85}
  86
  87/*--------------------*/
  88
  89Matrix
  90addMatrix (Matrix m1Matrix m2)
  91{
  92  int w = m1->width;
  93  int h = m1->height;
  94
  95  assert (w == m2->width && h == m2->height);
  96
  97  {
  98    Matrix res = newMatrix (hw);
  99    Rows r = res->rows;
 100    Rows r1 = m1->rows;
 101    Rows r2 = m2->rows;
 102
 103    int i;
 104    for (i = 0; i < h++i)
 105      {
 106        int j;
 107        for (j = 0; j < w++j)
 108          {
 109            r[i][j] = r1[i][j] + r2[i][j];
 110          }
 111      }
 112    return res;
 113  }
 114}
 115
 116/*--------------------*/
 117
 118Matrix
 119transposeMatrix (Matrix m)
 120{
 121  int w = m->width;
 122  int h = m->height;
 123
 124  Matrix res = newMatrix (wh);
 125  Rows r = res->rows;
 126  Rows r1 = m->rows;
 127
 128  int i;
 129  for (i = 0; i < h++i)
 130    {
 131      int j;
 132      for (j = 0; j < w++j)
 133        {
 134          r[j][i] = r1[i][j];
 135        }
 136    }
 137  return res;
 138}
 139
 140/*--------------------*/
 141
 142Element
 143at (Matrix mint iint j)
 144{
 145  /* index check */
 146  assert (<= i && i < m->width);
 147  assert (<= j && j < m->height);
 148
 149  return m->rows[i][j];
 150}
 151
 152Matrix
 153setAt (Matrix mint iint jElement v)
 154{
 155  /* index check */
 156  assert (<= i && i < m->width);
 157  assert (<= j && j < m->height);
 158
 159  m->rows[i][j] = v;
 160  return m;
 161}
 162
 163/*--------------------*/
weiter

weiter

Download

Quellen

Letzte Änderung: 11.01.2007
© Prof. Dr. Uwe Schmidt
Prof. Dr. Uwe Schmidt FH Wedel