diff --git a/matmult.c b/matmult.c
index 360bc19806a0fad6ac0ab120f3073208c912a438..7c89509a45371cfba8d3f9042ef5cccfd5976251 100644
--- a/matmult.c
+++ b/matmult.c
@@ -28,11 +28,10 @@ static void usage(char *progname)
 int main (int argc, char *argv[]) 
 {
   int c, n=DEF_SIZE;
-  double norma;
   
-  MatPtr mPtr;
-  MatRow mRow;
-  Vetor vet, resPtr, resRow, resCol;
+  MatPtr mPtr_1, mPtr_2, resMatPtr;
+  MatRow mRow_1, mRow_2, resMatRow;
+  Vetor vet, resPtr, resRow;
   
   /* =============== TRATAMENTO DE LINHA DE COMANDO =============== */
 
@@ -50,33 +49,51 @@ int main (int argc, char *argv[])
   
   /* ================ FIM DO TRATAMENTO DE LINHA DE COMANDO ========= */
  
-  resPtr = (double *) malloc (n * sizeof(double));
-  resRow = (double *) malloc (n * sizeof(double));
-  
   srand(20202);
       
-  mPtr = geraMatPtr (n, n);
-  mRow = geraMatRow (n, n);
-  vet = geraVetor (n);
+  resPtr = (double *) calloc (n, sizeof(double));
+  resRow = (double *) calloc (n, sizeof(double));
+  resMatPtr = geraMatPtr(n, n, 1);
+  resMatRow = geraMatRow(n, n, 1);
+    
+  mPtr_1 = geraMatPtr (n, n, 0);
+  mPtr_2 = geraMatPtr (n, n, 0);
+
+  mRow_1 = geraMatRow (n, n, 0);
+  mRow_2 = geraMatRow (n, n, 0);
+
+  vet = geraVetor (n, 0);
     
 #ifdef DEBUG
-    prnMatPtr (mPtr, n, n);
-    prnMatRow (mRow, n, n);
+    prnMatPtr (mPtr_1, n, n);
+    prnMatPtr (mPtr_2, n, n);
+    prnMatRow (mRow_1, n, n);
+    prnMatRow (mRow_2, n, n);
     prnVetor (vet, n);
     printf ("=================================\n\n");
 #endif /* DEBUG */
 
-  multMatPtrVet (mPtr, vet, n, n, resPtr);
+  multMatPtrVet (mPtr_1, vet, n, n, resPtr);
+    
+  multMatRowVet (mRow_1, vet, n, n, resRow);
+    
+  multMatMatPtr (mPtr_1, mPtr_2, n, resMatPtr);
     
-  multMatRowVet (mRow, vet, n, n, resRow);
+  multMatMatRow (mRow_1, mRow_2, n, resMatRow);
     
 #ifdef DEBUG
     prnVetor (resPtr, n);
     prnVetor (resRow, n);
+    prnMatRow (resMatRow, n, n);
+    prnMatPtr (resMatPtr, n, n);
 #endif /* DEBUG */
 
-  liberaMatPtr (mPtr, n);
-  liberaVetor ((void*)mRow);
+  liberaMatPtr (mPtr_1, n);
+  liberaMatPtr (mPtr_2, n);
+  liberaMatPtr (resMatPtr, n);
+  liberaVetor ((void*)mRow_1);
+  liberaVetor ((void*)mRow_2);
+  liberaVetor ((void*)resMatRow);
   liberaVetor ((void*)vet);
     
   free(resRow);
diff --git a/matriz.c b/matriz.c
index 8f7508ae9dc500e03a68aa9c1b86d386f7359eb2..9c9395f461efb6097bc893f849602f9ce6a1ca3c 100644
--- a/matriz.c
+++ b/matriz.c
@@ -35,19 +35,23 @@ static inline double generateRandomB( )
  * 
  *  @param m  número de linhas da matriz
  *  @param n  número de colunas da matriz
+ *  @param zerar se 0, matriz  tem valores aleatórios, caso contrário,
+ *               matriz tem valores todos nulos
  *  @return  ponteiro para a matriz gerada
  *
  */
 
-MatPtr geraMatPtr (int m, int n)
+MatPtr geraMatPtr (int m, int n, int zerar)
 {
   MatPtr matriz = (double **) malloc(m*sizeof(double));
 
   if (matriz) {
     for (int i=0; i < m; ++i) {
       if (matriz[i] = (double *) malloc(n*sizeof(double)))
-        for (int j=0; matriz[i] && j < n; ++j)
-          matriz[i][j] = generateRandomA(i, j);
+        for (int j=0; matriz[i] && j < n; ++j) {
+          if (zerar) matriz[i][j] = 0.0;
+	  else       matriz[i][j] = generateRandomA(i, j);
+	}
       else
           return NULL;
     }
@@ -77,20 +81,24 @@ void liberaMatPtr (MatPtr matriz, int m)
 /**
  *  Funcao geraMatRow: gera matriz como vetor único, 'row-oriented'
  * 
- *  @param m  número de linhas da matriz
- *  @param n  número de colunas da matriz
+ *  @param m     número de linhas da matriz
+ *  @param n     número de colunas da matriz
+ *  @param zerar se 0, matriz  tem valores aleatórios, caso contrário,
+ *               matriz tem valores todos nulos
  *  @return  ponteiro para a matriz gerada
  *
  */
 
-MatRow geraMatRow (int m, int n)
+MatRow geraMatRow (int m, int n, int zerar)
 {
   MatRow matriz = (double *) malloc(m*n*sizeof(double));
 
   if (matriz) {
     for (int i=0; i < m; ++i) {
-      for (int j=0; j < n; ++j)
-        matriz[i*m + j] = generateRandomA(i, j);
+      for (int j=0; j < n; ++j) {
+	if (zerar) matriz[i*m + j] = 0.0;
+        else       matriz[i*m + j] = generateRandomA(i, j);
+      }
     }
   }
   
@@ -102,17 +110,21 @@ MatRow geraMatRow (int m, int n)
  *  Funcao geraVetor: gera vetor de tamanho 'n'
  * 
  *  @param n  número de elementos do vetor
+ *  @param zerar se 0, vetor  tem valores aleatórios, caso contrário,
+ *               vetor tem valores todos nulos
  *  @return  ponteiro para vetor gerado
  *
  */
 
-Vetor geraVetor (int n)
+Vetor geraVetor (int n, int zerar)
 {
   Vetor vetor = (double *) malloc(n*sizeof(double));
 
   if (vetor)
-    for (int i=0; i < n; ++i)
-      vetor[i] = generateRandomB();
+    for (int i=0; i < n; ++i) {
+      if (zerar) vetor[i] = 0.0;
+      else       vetor[i] = generateRandomB();
+    }
   
   return (vetor);
 }
@@ -135,8 +147,8 @@ void liberaVetor (void *vet)
  *  @param mat matriz 'mxn'
  *  @param m número de linhas da matriz
  *  @param n número de colunas da matriz
- *  @param res vetor que guarda o resultado. Deve estar previamente alocado e com
- *             seus elementos inicializados em 0.0 (zero)
+ *  @param  res vetor  que guarda  o resultado.  Deve estar  previamente
+ *              alocado e com seus elementos inicializados em 0.0 (zero)
  *  @return vetor de 'm' elementos
  *
  */
@@ -152,23 +164,6 @@ void multMatPtrVet (MatPtr mat, Vetor v, int m, int n, Vetor res)
   }
 }
 
-/**
- *  Funcao prnMatPtr:  Imprime o conteudo de uma matriz em stdout
- *  @param mat matriz
- *  @param m número de linhas da matriz
- *  @param n número de colunas da matriz
- *
- */
-
-void prnMatPtr (MatPtr mat, int m, int n)
-{
-  for (int i=0; i < m; ++i) {
-    for (int j=0; j < n; ++j)
-      printf(DBL_FIELD, mat[i][j]);
-    printf("\n");
-  }
-  printf(SEP_RES);
-}
 
 /**
  *  Funcao multMatRowVet:  Efetua multiplicacao entre matriz 'mxn' por vetor
@@ -193,6 +188,67 @@ void multMatRowVet (MatRow mat, Vetor v, int m, int n, Vetor res)
   }
 }
 
+
+/**
+ *  Funcao multMatMatPtr: Efetua multiplicacao de duas matrizes 'n x n' 
+ *  @param A matriz 'n x n'
+ *  @param B matriz 'n x n'
+ *  @param n ordem da matriz quadrada
+ *  @param C   matriz que guarda o resultado. Deve ser previamente gerada com 'geraMatPtr()'
+ *             e com seus elementos inicializados em 0.0 (zero)
+ *
+ */
+
+void multMatMatPtr (MatPtr A, MatPtr B, int n, MatPtr C)
+{
+
+  /* Efetua a multiplicação */
+  for (int i=0; i < n; ++i)
+    for (int j=0; j < n; ++j)
+      for (int k=0; k < n; ++k)
+	C[i][j] += A[i][k] * B[k][j];
+}
+
+
+/**
+ *  Funcao multMatMatPtr: Efetua multiplicacao de duas matrizes 'n x n' 
+ *  @param A matriz 'n x n'
+ *  @param B matriz 'n x n'
+ *  @param n ordem da matriz quadrada
+ *  @param C   matriz que guarda o resultado. Deve ser previamente gerada com 'geraMatPtr()'
+ *             e com seus elementos inicializados em 0.0 (zero)
+ *
+ */
+
+void multMatMatRow (MatRow A, MatRow B, int n, MatRow C)
+{
+
+  /* Efetua a multiplicação */
+  for (int i=0; i < n; ++i)
+    for (int j=0; j < n; ++j)
+      for (int k=0; k < n; ++k)
+	C[i*n+j] += A[i*n+k] * B[k*n+j];
+}
+
+
+/**
+ *  Funcao prnMatPtr:  Imprime o conteudo de uma matriz em stdout
+ *  @param mat matriz
+ *  @param m número de linhas da matriz
+ *  @param n número de colunas da matriz
+ *
+ */
+
+void prnMatPtr (MatPtr mat, int m, int n)
+{
+  for (int i=0; i < m; ++i) {
+    for (int j=0; j < n; ++j)
+      printf(DBL_FIELD, mat[i][j]);
+    printf("\n");
+  }
+  printf(SEP_RES);
+}
+
 /**
  *  Funcao prnMatRow:  Imprime o conteudo de uma matriz em stdout
  *  @param mat matriz
@@ -211,6 +267,20 @@ void prnMatRow (MatRow mat, int m, int n)
   printf(SEP_RES);
 }
 
+/**
+ *  Funcao prnVetor:  Imprime o conteudo de vetor em stdout
+ *  @param vet vetor com 'n' elementos
+ *  @param n número de elementos do vetor
+ *
+ */
+
+void prnVetor (Vetor vet, int n)
+{
+  for (int i=0; i < n; ++i)
+    printf(DBL_FIELD, vet[i]);
+  printf(SEP_RES);
+}
+
 /**
  *  Funcao prodEscalar:  Calcula o produto escalar entre 2 vetores
  *  @param v1 vetor com 'n' elementos
@@ -230,17 +300,3 @@ double prodEscalar (Vetor v1, Vetor v2, int n)
 }
 
 
-/**
- *  Funcao prnVetor:  Imprime o conteudo de vetor em stdout
- *  @param vet vetor com 'n' elementos
- *  @param n número de elementos do vetor
- *
- */
-
-void prnVetor (Vetor vet, int n)
-{
-  for (int i=0; i < n; ++i)
-    printf(DBL_FIELD, vet[i]);
-  printf(SEP_RES);
-}
-
diff --git a/matriz.h b/matriz.h
index 11a20253d672d6ada1c277e7985b26158d4eec15..a468bbd126b8d5a6faf814ebb03cb2e5786d1d51 100644
--- a/matriz.h
+++ b/matriz.h
@@ -17,9 +17,9 @@ typedef double * Vetor;
 
 /* ----------- FUNÇÕES ---------------- */
 
-MatPtr geraMatPtr (int m, int n);
-MatRow geraMatRow (int m, int n);
-Vetor geraVetor (int n);
+MatPtr geraMatPtr (int m, int n, int zerar);
+MatRow geraMatRow (int m, int n, int zerar);
+Vetor geraVetor (int n, int zerar);
 
 void liberaMatPtr (MatPtr mPtr, int n);
 void liberaVetor (void *vet);
@@ -30,6 +30,8 @@ void prnMatPtr (MatPtr mat, int m, int n);
 void multMatRowVet (MatRow mat, Vetor v, int m, int n, Vetor res);
 void prnMatRow (MatRow mat, int m, int n);
 
-double prodEscalar (Vetor v1, Vetor v2, int n);
+void multMatMatPtr (MatPtr A, MatPtr B, int n, MatPtr C);
+void multMatMatRow (MatRow A, MatRow B, int n, MatRow C);
+
 void prnVetor (Vetor vet, int n);