[WikiDyd] [TitleIndex] [WordIndex

Języki i metodyka programowania

Przykłady z wykładów w semestrze jesiennym 2011

Wykład VIII, 6 grudnia 2011

Było sporo gadania: o rozwiązywaniu układów równań i o reprezentacji tablic wielowymiarowych w języku C. Napisaliśmy wspólnie kod do elementarnych operacjach na tablicy 2D podanej w postaci pliku podobnego do tego:

3 4
 3.0 5.0 7.0  18
2.0 4.0 -3.0  21
1.0 0.0 20.0   5

Nasze funkcje umieją czytać i pisać takie macierze oraz zmieniać wartości ich elementów:

   1 #ifndef _MAT_H_
   2 #define _MAT_H_
   3 
   4 #include <stdio.h>
   5 
   6 typedef struct {
   7         int rn;
   8         int cn;
   9         double *v;
  10 } mat_t;
  11 
  12 mat_t *alloc_mat( int r, int c ); // allokacja pamięci na miacierz r x c
  13 
  14 mat_t *read_mat( FILE *inp ); // czyta macierz z inp
  15 
  16 void write_mat( mat_t *m, FILE *out ); // pisze macierz do out
  17 
  18 int set_mat( mat_t *m, int i, int j, double x ); // ustawia m[i,j]= x
  19 
  20 #endif
  21 

   1 #include "mat.h"
   2 
   3 #include <stdlib.h>
   4 
   5 mat_t *alloc_mat( int r, int c ) {
   6 // allokacja pamięci na miacierz r x c
   7         mat_t *new = malloc( sizeof *new );
   8         if( new == NULL )
   9                 return NULL;
  10         new->v = malloc( r*c * sizeof * new->v );
  11         if( new->v == NULL ) {
  12                 free( new );
  13                 return NULL;
  14         }
  15         new->rn = r;
  16         new->cn = c;
  17 
  18         return new;
  19 }
  20 
  21 mat_t *read_mat( FILE *inp ) {
  22 // czyta macierz z inp
  23         int r,c;
  24         if( fscanf( inp, "%d %d", &r, &c ) != 2 )
  25                 return NULL;
  26         else {
  27                 mat_t *new = alloc_mat( r, c );
  28                 if( new == NULL )
  29                         return NULL;
  30 
  31                 for( r= 0; r < new->rn; r++ )
  32                         for( c= 0; c < new->cn; c++ )
  33                 //      if( fscanf( inp, "%lf", &(new->v[r*new->cn+c]) ) != 1 ) {
  34                                 if( fscanf( inp, "%lf", new->v+r*new->cn+c ) != 1 ) {
  35                                         free( new->v );
  36                                         free( new );
  37                                         return NULL;
  38                                 }
  39                 return new;
  40         }
  41 }
  42 
  43 void write_mat( mat_t *m, FILE *out ) {
  44 // pisze macierz do out
  45         int i,j;
  46 
  47         fprintf( out, "%d %d\n", m->rn, m->cn );
  48 
  49         for( i= 0; i < m->rn; i++ ) {
  50                 for( j= 0; j < m->cn; j++ )
  51                         fprintf( out, "%f ", m->v[i*m->cn+j] );
  52                 fprintf( out, "\n" );
  53         }
  54 }
  55 
  56 int set_mat( mat_t *m, int i, int j, double x ) {
  57 // ustawia m[i,j] = x
  58         if( i < 0 || i >= m->rn || j < 0 || j >= m->cn )
  59                 return 0;
  60 
  61         m->v[i*m->cn+j] = x;
  62         return 1;
  63 }

Program, który testuje tę funkcjonalność wygląda tak:

   1 #include <stdio.h>
   2 
   3 #include "mat.h"
   4 
   5 int
   6 main( int argc, char **argv ) {
   7         FILE *in = argc > 1 ? fopen( argv[1], "r" ) : stdin;
   8 
   9         mat_t *m = read_mat( in );
  10 
  11         if( m == NULL ) {
  12                 fprintf( stderr, "Zła zawartość pliku wejściowego\n" );
  13                 return 1;
  14         } else {
  15                 write_mat( m, stdout );
  16                 if( set_mat( m, 2, 3, 0.0 ) == 0 )
  17                         fprintf( stderr, "[2,3] to niepoprawne indeksy\n" );
  18                 if( set_mat( m, 4, 5, 0.0 ) == 0 )
  19                         fprintf( stderr, "[4,5] to niepoprawne indeksy\n" );
  20 
  21                 fprintf( stderr, "Macierz po przejściach:\n" );
  22 
  23                 write_mat( m, stdout );
  24   }
  25 
  26         return 0;
  27 }

2015-09-23 06:44