Informatyka

Operacje na macierzach

Laboratorium problemowe, II rok AGH



1. Cel ćwiczenia.

Celem ćwiczenia było poznanie nowych obiektów języka C (C++) typu tablice, nauka definiowania tych obiektów, jak też sposobów poruszania się po danych w nich umieszczonych poprzez indeksowanie lub za pomoc± wskaĽnika. Tematem ćwiczenia było napisanie programu, który zgodnie z przekazanymi parametrami podczas jego wywołania dokonuje konkretnej operacji na macierzach. Założenia były następuj±ce:

  1. program powinien zawierać cztery operacje np. dodawanie, odejmowanie, mnożenie i odwrotno¶ć,
  2. macierze powinny być wczytywane z osobnych plików,
  3. program wystarczy żeby wykonywał operacje na macierzach kwadratowych,
  4. rozmiar macierzy można zdefiniować za pomoc± zmiennej globalnej,
  5. operacje na plikach należy wykonywać za pomoc± standardowych funkcji języka C oraz wykorzystuj±c zmienne typu FILE,
  6. program musi być napisany w sposób obsługuj±cy sytuacje awaryjne - błędy użytkownika,
  7. struktura programu powinna wykorzystywać możliwo¶ć definiowania własnych funkcji, ich wywoływania z parametrami, itp.

2. Struktura programu.

Poniżej zamieszczono wydruk pliku zawieraj±cego napisany program.


/*----------------------------- macierze.cpp ------------------------------*/
#include
#define N 3
FILE *wp

int mnozenie(double A[N][N], double B[N][N], double C[N][N], char *argv[])
int dodawanie(double A[N][N], double B[N][N], double C[N][N], char *argv[])
int odejmowanie(double A[N][N], double B[N][N], double C[N][N], char *argv[])
int odwrotnosc(double A[N][N], double I[N][N], char *argv[])

void main(int argc, char *argv[]){
double A[N][N], B[N][N], C[N][N];
int a=0;
char *pw;

     switch(*argv[1]){
     case `*`:
          if(argc!=5){
               a=6;
               break;
          }
          else{
               a=mnozenie(A,B,C,argv);
               break;
          }
     case `+`:
          if(argc!=5){
               a=6;
               break;
          }
          else{
               a=dodawanie(A,B,C,argv);
               break;
          }
     case `-`:
          if(argc!=5){
               a=6;
               break;
          }
          else{
               a=odejmowanie(A,B,C,argv);
               break;
          }
     case `~`:
          if(argc!=4){
               a=6;
               break;
          }
          else{
               a=odwrotnosc(A,I,argv);
               break;
          }
     default: a=4;
     }

     switch(a){
     case 0:
          printf(“\nOK. Operacja wykonana.”);
          if(argc==5){
               pw=argv[4];
          }
          printf(„\nWynik został zapisany w pliku: %s.\n”, pw);
          break;
     case 1:
          printf(„\nBł±d otwierania pliku: %s do czytania!\a\n”, argv[2]);
          break;
     case 2:
          printf(„\nBł±d otwierania pliku: %s do czytania!\a\n”, argv[3]);
          break;
     case 3:
          printf(„\nBł±d zapisu do pliku: %s !\a\n”, argv[4]);]);
          break;
     case 4:
          printf(„\nNie wybrano żadnej opcji!\a\n”);
          break;
     case 5:
          printf(„\nBł±d - macierz wej¶ciowa jest osobliwa!\a\n”);
          break;
     case 6:
          printf(„\nBł±d - sprawdĽ ilo¶ć argumentów!\a\n”);
          break;
     }
}

/*funkcja dodawanie*/
int dodawanie(double A[N][N], double B[N][N], double C[N][N], char *argv[]){
int i,j;

     for(i=0; i < N; ++i{
          for(j=0; j < N; ++j){
               A[i][j]=0;
               B[i][j]=0;
               C[i][j]=0;
          }
     }
     if(wp=fopen(argv[2],"r")==NULL){
          return 1;
     }
     else{
          for(i=0;i < N;++i){
               for(j=0;j < N;++j){
                    fscanf(wp, “%lf”, &A[i][j]);
               }
          }
          fclose(wp);
     }
     if(wp=fopen(argv[3], "r")==NULL){
     return 2;
     }
     else{
          for(i=0;i < N;++i){
               for(j=0;j < N;++j){
                    fscanf(wp, „%lf”, &B[i][j]);
          }
          fclose(wp);
     }
     if(wp=fopen(argv[4],"w")==NULL){
          return 3;
     }
     else{
          for(i=0;i < N;++i){
               for(j=0;j < N;++j){
                    C[i][j]=A[i][j]+B[i][j];
                    fprintf(wp, “%5.1lf”, C[i][j]);
               }
               fprintf(wp,“\n“);
          }
          fclose(wp);
     }
     return 0;
}

/*funkcja odejmowanie*/
int odejmowanie(double A[N][N], double B[N][N], double C[N][N], char *argv[]){
int i,j;

     for(i=0; i < N; ++i{
          for(j=0; j < N; ++j){
               A[i][j]=0;
               B[i][j]=0;
               C[i][j]=0;
          }
     }
     if(wp=fopen(argv[2],"r")==NULL){
          return 1;
     }
     else{
          for(i=0;i < N;++i){
               for(j=0;j < N;++j){
                    fscanf(wp, “%lf”, &A[i][j]);
               }
          }
          fclose(wp);
     }
     if(wp=fopen(argv[3], "r")==NULL){
     return 2;
     }
     else{
          for(i=0;i < N;++i){
               for(j=0;j < N;++j){
                    fscanf(wp, „%lf”, &B[i][j]);
          }
          fclose(wp);
     }
     if(wp=fopen(argv[4],"w")==NULL){
          return 3;
     }
     else{
          for(i=0;i < N;++i){
               for(j=0;j < N;++j){
                    C[i][j]=A[i][j]-B[i][j];
                    fprintf(wp, “%5.1lf”, C[i][j]);
               }
               fprintf(wp,“\n“);
          }
          fclose(wp);
     }
     return 0;
}

/*funkcja mnozenie*/
int mnozenie(double A[N][N], double B[N][N], double C[N][N], char *argv[]){
int i,j;

     for(i=0; i < N; ++i{
          for(j=0; j < N; ++j){
               A[i][j]=0;
               B[i][j]=0;
               C[i][j]=0;
          }
     }
     if(wp=fopen(argv[2],"r")==NULL){
          return 1;
     }
     else{
          for(i=0;i < N;++i){
               for(j=0;j < N;++j){
                    fscanf(wp, “%lf”, &A[i][j]);
               }
          }
          fclose(wp);
     }
     if(wp=fopen(argv[3], "r")==NULL){
     return 2;
     }
     else{
          for(i=0;i < N;++i){
               for(j=0;j < N;++j){
                    fscanf(wp, „%lf”, &B[i][j]);
          }
          fclose(wp);
     }
     if(wp=fopen(argv[4],"w")==NULL){
          return 3;
     }
     else{
          for(i=0;i < N;++i){
               for(j=0;j < N;++j){
                    for(k=0;k < N;++k){
                         C[i][j]+=A[i][k]*B[k][j];
                    }
                    fprintf(wp, “%5.1lf”, C[i][j]);
               }
               fprintf(wp,“\n“);
          }
          fclose(wp);
     }
     return 0;
}

/*funkcja odwrotnosc*/
int odwrotnosc(double A[N][N], double I[N][N], char *argv[]){
int i,j,d;
int e; /*zlicza elementy zerowe macierzy*/
double X[N][N], Y[N][N];

     for(i=0; i < N; ++i{
          for(j=0; j < N; ++j){
               A[i][j]=0;
               I[i][j]=0;
          }
     }
     if(wp=fopen(argv[2],"r")==NULL){
          return 1;
     }
     else{
          for(i=0;i < N;++i){
               for(j=0;j < N;++j){
                    fscanf(wp, “%lf”, &A[i][j]);
               }
          }
          fclose(wp);
     }
     if(wp=fopen(argv[3], "w")==NULL){
     return 3;
     }
     else{
          for(i=0;i < N;++i){
               I[i][i]=1 /*zainicjuj macierz jednostkow±*/
          }
          for(d=0;d < N;++d){
               if(A[d][d]=0){
                    if(d==(N-1)){
                         return 5;
                    }
                    e=0;
                    for(i=d+1;i < N;++i){ /*znajdĽ niezerowe A[i][d]*/
                         if(A[i][d])==0){
                              ++e; /*zlicz każdy zerowy element*/
                         else{
                              for(j=0;j < N;++j){ /*zamień wiersz i z d*/
                                   X[d][j]=A[d][j]; /* w A,I*/
                                   A[d][j]=A[i][j];
                                   A[i][j]=X[d][j];
                                   Y[d][j]=I[d][j];
                                   I[d][j]=I[i][j];
                                   I[i][j]=Y[d][j];
                              }
                              i=N; /*wyjdĽ z pętli*/
                         }
                         if(e==(N-1-d)){ /*je¶li nie ma niezerowych*/
                              return 5; /*A[i][d] to bł±d*/
                         }
                    }
               }
               for(i=0;i < N;++i){ /*podziel wiersz d przez A[d][d] w A,I*/
                    I[d][i]=I[d][i]/A[d][d];
               }
               for(i=0;i < N;++i){
                    X[d][i]=A[d][i]/A[d][d];
               }
               for(i=0;i < N;++i){
                    A[d][i]=X[d][i];
               }
               for(i=0;i < N;++i){
                    if(i < d||i > d){ /*odejmij A[i][d]*wiersz d od i w A,I*/
                         for(j=0;j < N;++j){
                              I[i][j]=I[i][j]-A[i][d]*I[d][j];
                         }
                         for(j=0;j < N;++j){
                              X[i][j]=A[i][j]-A[i][d]*A[d][j];
                         }
                         for(j=0;j < N;++j){
                              A[i][j]=X[i][j];
                         }
                    }
                    else{
                         i=d;
                    }
               }
          }
          for(i=0;i < N;++i){
               for(j=0;j < N;++j){
                    fprintf(wp, “%7.2lf”, I[i][j]);
               }
               fprintf(wp,”\n”);
          }
          fclose(wp);
     }
     return 0;
}
/*----------------------------- koniec pliku ------------------------------*/