Práctica 4: Fonaments de Computadors
Programación en C: Matrices


Saltar a código fuente
Descargar este archivo en formato Word 2000 (comprimido en ZIP) 6.94KB

Introducción

El objetivo de este programa es la presentación del resultado del producto de dos matrices entradas por pantalla por el usuario. Se limita el tamaño de las matrices para que la matriz resultante sea suficientemente pequeña como para ser presentada por pantalla, aunque la estructura del programa permitiría trabajar con matrices arbitrariamente grandes siempre que haya memoria suficiente.
Gestión de memoria
Los elementos de cada matriz son del tipo float y las variables que contienen las tres matrices (los factores y el producto) son de tipo puntero. Esto significa que los elementos de una matriz se almacenan uno tras otro a partir de una posición de memoria determinada, y no en arrays de n x m dimensiones. El inconveniente de este sistema es el hecho de que no se accede al elemento deseado de una matriz indicando su fila y su columna, como pasaría en un array, sino que conociendo la primera posición de memoria y el número de filas y columnas de la matriz podemos ingeniárnoslas para acceder a un elemento cualquiera (ver programa). La ventaja que tiene es que el número de filas y columnas de una matriz ya no queda limitado por el programa sino por el propio sistema, porque podremos almacenar matrices de tamaño tan grande como nos permita la memoria disponible del sistema. Esto rentabiliza completamente la gestión de memoria, ya que solamente se gasta lo que se usa. En los arrays no sucedería esto, porque son de longitud fija, es decir siempre podemos querer usar matrices de tamaño más grande del permitido, entonces el programa fallaría y si siendo cautelosos usamos arrays fijos muy grandes estaríamos malgastando memoria porque la mayoría de veces utilizaríamos matrices pequeñas.
Estructura del programa
El código fuente MULTIMAT.C se compone del procedimiento principal main y de dos subrutinas más lectura y visualitza, que son usadas respectivamente para entrar y visualizar una matriz por pantalla, puesto que son acciones que ocurren más de una vez en el programa y así se ahorra código. Hay otras partes del código que podríamos haber puesto a parte, pero esto solamente hubiese tenido un fin estructural y como el código no era muy largo preferimos incluirlas en la función principal.
Esta es a grandes rasgos la estructura del programa principal, no es detallada porque lo  que se pretendía era mostrar la situación de las subrutinas (color blanco) dentro del programa principal, como dice el enunciado del informe. Se presenta a continuación el código fuente del programa donde si hay comentarios detallados de los pasos más importantes.
 

Código fuente

/* LLISTA DE FUNCIONS UTILITZADES DURANT EL PROGRMA */
#include <stdio.h>
#include <stdlib.h>
#include <process.h>

/* SUBRUTINA DE LECTURA DE MATRIUS */
void lectura(int f,int c,float *p)
{
float num=0;
int i,j=0;
for(i=0;i<f;i++)
 {
 for(j=0;j<c;j++)
  {
  // Lectura de cada element y colocació a la memòria
  printf("\n ELEMENT%d%d=>",i+1,j+1);
  scanf("%f",&num);
  *p=num;
  if((i!=f) && (j!=c))
   {
   p++;
   }
  }
 }

}

/* SUBRUTINA QUE VISUALITZA UNA MAQTRIU */
void visualitza(int f,int c,float *p)
{
int i=0;
int j=0;
for (i=0;i<f;i++)
 {
 for(j=0;j<c;j++)
  {
  printf("\t%5.2f",*p);
  if((i!=f) && (j!=c))
   {
   p++;
   }
  }
  printf("\n");
 }
}

/* PROGRAMA PRINCIPAL*/

/* CRIDES DEL PROGRMA PRINCIPAL */
void lectura(int f,int c,float *p);
void visualitza(int f,int c,float *p);

int main(void)
{
/* INICIALITZACIO DE LES VARIABLES */
float *p1, *p2,*p3;
int i,j,k,f1,c1,f2,c2=0;
float acumu=0;

/*MISSATGES PER PANTALLA */
printf("AQUEST PROGRMA CALCULA EL PRODUCTE DE DUES MATRIUS\n");
printf("VES CONTESTANT ELS MISSATGES QUE APAREIXEN PER LA PANTALLA\n");
 

/* LECTURA DEL TAMANY DE LES MATRIUS */
printf("\n Nø DE FILES DE LA PRIMERA MATRIU: ");
scanf("%i",&f1);
printf("\n Nø DE COLUMNES DE LA PRIMERA MATRIU: ");
scanf("%i",&c1);
printf("\n Nø DE FILES DE LA SEGONA MATRIU: ");
scanf("%i",&f2);
printf("\n Nø DE COLUMNES DE LA SEGONA MATRIU: ");
scanf("%i",&c2);

/* COMPROVEM QUE ES POGUI MULTIPLICAR LES MATRIUS */
if(c1!=f2)
 {
  printf("\nEL Nø DE COLUMNES DE LA PRIMERA ES DIFERENT AL Nø DE FILES DE LA SEGONA MATRIU");
  printf("\nEL PRODUCTE D'AQUESTES MATRIUS NO ES POT REALITZAR\n");
  exit(1);
  }
/* COMPROVEM QUE LES MATRIUS NO SIGUIN MASSA GRANS */
if((c1*f1)>16||(c2*f2)>16)
 {
 printf("\nEL Nø DE VALORS A INTRODUIR SERA MOLT GRAN, NO ES UN PROGRMA DISSENYAT PER A");
 printf("\nAQUEST TIPUS DE MATIRUS TAN GRANS\n");
 exit(1);
 }

/* ASSIGNACIO DINAMICA DE MEMORIA */
if ((p1 = (float *) malloc(((f1*c1)+(f2*c2)+(f1*c2))*sizeof(float))) == NULL)
 {
 printf("MEMEORIA INSUFICIENT\n");
 exit(1);
 }
 

/* LLEGIM LES MATRIUS */
printf("\nINTRODUIEX ELS VALORS DE LA PRIMERA MATRIU:\n");
printf("*******************************************\n");
lectura(f1,c1,p1);
printf("\nINTRODUIEX ELS VALORS DE LA SEGONA MATRIU:\n");
printf("******************************************\n");
p2=p1+(c1*f1);
lectura(f2,c2,p2);

/*ESCRIVIM LES MATRIUS ENTRADES  */
printf("\nLA PRIMERA MATRIU ES: \n\n");
visualitza(f1,c1,p1);
printf("\nLA SEGONA MATRIU ES: \n\n");
visualitza(f2,c2,p2);
p3=p2+(c2*f2);

/* MULTIPLIQUEM LES MATRIUS LLEGIDES */
for (i=0;i<f1;i++)
 {
 for(j=0;j<c2;j++)
  {
  for(k=0;k<c1;k++)
   {
   acumu=acumu+(*p1*(*p2));
   p1++;
   p2=p2+c2;
   }
  *p3=acumu;
  p3++;
  p1=p1-c1;
  p2=p2-c2-(f2-1)*c2+1;
  acumu=0;
  }
 p1=p1+c1;
 p2=p2-c2;
 }

/* ESCRIVIM  LA MATRIU RESPOSTA */
printf("\nEL PRODUCTE DE LES MATRIUS ANTERIORS ES: \n\n");
p3=p3-(f1*c2);
visualitza(f1,c2,p3);

/* ALLIBEREM LA MEMORIA ASSIGNADA */
free(p1);

return 0;
}
 

Josep Antoni Rodríguez Serrano
José Samper Estrada