Sí, acabo de probar en Visual C++ la versión 2010 y tienes razón; sale un mensaje similar al de Borland. Así que es preferible hacerlo en forma dinámica.
Para ello hice un pequeño programa que tal vez le sirva a milly. Lo que hace es sumar y multiplicar matrices. También implementé el algoritmo de Strassen, que lo mencioné recientemente en este
.
Matriz.h (módulo de definición)
#ifndef _MATRIZ_H
#define _MATRIZ_H
typedef int **Matriz;
Matriz crearMatriz(char nombre, int m, int n);
// Crea una matriz a partir de los datos introducidos por el usuario.
// Por ejemplo, si nombre='A':
// >A(1,1) = _
// >A(1,2) = _
// >...
// >A(1,n) = _
// >
// >A(2,1) = _
// >A(2,2) = _
// >...
// >A(2,n) = _
// >
// >...
// >A(m,1) = _
// >A(m,2) = _
// >...
// >A(m,n) = _
Matriz suma(Matriz A, Matriz B, int m, int n);
// Pre: A y B son matrices m x n.
// Devuelve la matriz A+B.
// Obs.: este procedimiento pide memoria.
Matriz resta(Matriz A, Matriz B, int m, int n);
// Pre: A y B son matrices m x n.
// Devuelve la matriz A-B.
// Obs.: este procedimiento pide memoria.
Matriz multiplicacionConvencional(Matriz A, Matriz B, int m, int n, int p);
// Pre: -Las matrices A y B son conformables.
// -A tiene dimension m x n.
// -B tiene dimension n x p.
// Devuelve el producto matricial A*B.
// Obs.: este procedimiento pide memoria.
Matriz multiplicacionPorStrassen(Matriz A, Matriz B, int m, int n, int p);
// Pre: -Las matrices A y B son conformables.
// -A tiene dimension m x n.
// -B tiene dimension n x p.
// Devuelve el producto matricial A*B calculado mediante el algorimo de Strassen.
// Obs.: este procedimiento pide memoria.
void imprimirMatriz(Matriz A, int m, int n);
// Imprime la matriz A en el formato:
// >A[1][1] A[1][2] ... A[1][n]
// >A[2][1] A[2][2] ... A[2][n]
// >...
// >A[m][1] A[m][2] ... A[m][n]
void borrarMatriz(Matriz &A, int m);
// Libera la memoria reservada para la matriz A (de m filas).
// No se necesita pasar como parametro el numero de columnas.
#endif /* _MATRIZ_H */
Matriz.cpp (módulo de implementación)
#include <iostream>
#include <math.h>
using namespace std;
#include "Matriz.h"
Matriz crearMatriz(char nombre, int m, int n){
// Crea una matriz a partir de los datos introducidos por el usuario.
// Por ejemplo, si nombre='A':
// >A(1,1) = _
// >A(1,2) = _
// >...
// >A(1,n) = _
// >
// >A(2,1) = _
// >A(2,2) = _
// >...
// >A(2,n) = _
// >
// >...
// >A(m,1) = _
// >A(m,2) = _
// >...
// >A(m,n) = _
Matriz M=new int*[m];
for(int i=0; i<m; i++){
M[i]=new int[n];
for(int j=0; j<n; j++){
cout << nombre << "(" << i+1 << "," << j+1 << ")" << " = "; cin >> M[i][j];
}
cout << endl;
}
return M;
}
//----------------------------------------
Matriz suma(Matriz A, Matriz B, int m, int n){
// Pre: A y B son matrices m x n.
// Devuelve la matriz A+B.
// Obs.: este procedimiento pide memoria.
Matriz C=new int*[m];
for(int i=0; i<m; i++){
C[i]=new int[n];
for(int j=0; j<n; j++)
C[i][j]=A[i][j]+B[i][j];
}
return C;
}
//----------------------------------------
Matriz resta(Matriz A, Matriz B, int m, int n){
// Pre: A y B son matrices m x n.
// Devuelve la matriz A-B.
// Obs.: este procedimiento pide memoria.
Matriz C=new int*[m];
for(int i=0; i<m; i++){
C[i]=new int[n];
for(int j=0; j<n; j++)
C[i][j]=A[i][j]-B[i][j];
}
return C;
}
//----------------------------------------
Matriz multiplicacionConvencional(Matriz A, Matriz B, int m, int n, int p){
// Pre: -Las matrices A y B son conformables.
// -A tiene dimension m x n.
// -B tiene dimension n x p.
// Devuelve el producto matricial A*B.
// Obs.: este procedimiento pide memoria.
Matriz C=new int*[m];
for(int i=0; i<m; i++){
C[i]=new int[p];
for(int j=0; j<p; j++){
C[i][j]=0;
for(int k=0; k<n; k++)
C[i][j]+=A[i][k]*B[k][j];
}
}
return C;
}
//----------------------------------------
int max(int a, int b){
// Retorna el maximo del conjunto {a,b}.
if (a >= b)
return a;
else
return b;
}
Matriz completarConCeros(Matriz A, int m, int n, int N){
// Devuelve una matriz que se obtiene a partir de A
// rellenando con ceros hasta completar el tamaño N x N.
// Pre: N >= m=nroFilas(A)
// Pre: N >= n=nroColumnas(A)
Matriz Ampliada=new int*[N];
for(int i=0; i<m; i++){
Ampliada[i]=new int[N];
for(int j=0; j<n; j++)
Ampliada[i][j]=A[i][j];
for(int j=n; j<N; j++)
Ampliada[i][j]=0;
}
for(int i=m; i<N; i++){
Ampliada[i]=new int[N];
for(int j=0; j<N; j++)
Ampliada[i][j]=0;
}
return Ampliada;
}
Matriz strassen(Matriz M1, Matriz M2, int num){
// Devuelve la matriz resultante de multiplicar M1*M2.
// Pre: Ambas matrices son cuadradas de tamaño num que es potencia de 2.
Matriz A[2][2],B[2][2],C[2][2],M[7],S1,S2,sol,aux1,aux2;
int r,s,f,c;
sol=new int*[num]; // Reservo memoria para la matriz solucion.
for(int i=0; i<num; i++)
sol[i]=new int[num];
if(num==1){
sol[0][0]=M1[0][0]*M2[0][0];
return sol;
}
else
{
// Creo las submatrices de A y B.
for(r=0; r<2; r++){
for(s=0; s<2; s++){
A[r][s]=new int*[num/2];
for(f=0; f<num/2; f++){
A[r][s][f]=new int[num/2];
for(c=0;c<num/2;c++)
A[r][s][f][c]=M1[f+(num/2)*r][c+(num/2)*s];
}
B[r][s]=new int*[num/2];
for(f=0; f<num/2; f++){
B[r][s][f]=new int[num/2];
for(c=0;c<num/2;c++)
B[r][s][f][c]=M2[f+(num/2)*r][c+(num/2)*s];
}
}
}
// A[0][0] --> cuadrante I de M1
// A[0][1] --> cuadrante II de M1
// A[1][0] --> cuadrante III de M1
// A[1][1] --> cuadrante IV de M1
// B[0][0] --> cuadrante I de M2
// B[0][1] --> cuadrante II de M2
// B[1][0] --> cuadrante III de M2
// B[1][1] --> cuadrante IV de M2
// Creo las matrices M.
//----------
// Matriz M[0]
//----------
S1=suma(A[0][0],A[1][1],num/2,num/2); // S1=A11+A22
S2=suma(B[0][0],B[1][1],num/2,num/2); // S2=B11+B22
M[0]=strassen(S1,S2,num/2); // M1=(A11+A22)(B11+B22)
borrarMatriz(S1,num/2);
borrarMatriz(S2,num/2);
//----------
// Matriz M[1]
//----------
S1=suma(A[1][0],A[1][1],num/2,num/2); // S1=A21+A22
M[1]=strassen(S1,B[0][0],num/2); // M2=(A21+A22)B11
borrarMatriz(S1,num/2);
//----------
// Matriz M[2]
//----------
S2=resta(B[0][1],B[1][1],num/2,num/2); // S2=B12-B22
M[2]=strassen(A[0][0],S2,num/2); // M3=A11(B12-B22)
borrarMatriz(S2,num/2);
//----------
// Matriz M[3]
//----------
S2=resta(B[1][0],B[0][0],num/2,num/2); // S2=B21-B11
M[3]=strassen(A[1][1],S2,num/2); // M3=A22(B21-B11)
borrarMatriz(S2,num/2);
//----------
// Matriz M[4]
//----------
S1=suma(A[0][0],A[0][1],num/2,num/2); // S1=A11+A12
M[4]=strassen(S1,B[1][1],num/2); // M5=(A11+A12)B22
borrarMatriz(S1,num/2);
//----------
// Matriz M[5]
//----------
S1=resta(A[1][0],A[0][0],num/2,num/2); // S2=A21-A11
S2=suma(B[0][0],B[0][1],num/2,num/2); // S2=B11+B12
M[5]=strassen(S1,S2,num/2); // M6=(A21-A11)(B11+B12)
borrarMatriz(S1,num/2);
borrarMatriz(S2,num/2);
//----------
// Matriz M[6]
//----------
S1=resta(A[0][1],A[1][1],num/2,num/2); // S2=A12-A22
S2=suma(B[1][0],B[1][1],num/2,num/2); // S2=B21+B22
M[6]=strassen(S1,S2,num/2); // M7=(A12-A22)(B21+B22)
borrarMatriz(S1,num/2);
borrarMatriz(S2,num/2);
// Hallo submatrices de C=A*B.
//--------------------------------
// C11=M1+M4-M5+M7
//--------------------------------
C[0][0]=suma(M[0],M[3],num/2,num/2);
aux1=C[0][0];
C[0][0]=resta(C[0][0],M[4],num/2,num/2);
aux2=C[0][0];
C[0][0]=suma(C[0][0],M[6],num/2,num/2);
borrarMatriz(aux1,num/2);
borrarMatriz(aux2,num/2);
//--------------------------------
// C12=M3+M5
//--------------------------------
C[0][1]=suma(M[2],M[4],num/2,num/2);
//--------------------------------
// C21=M2+M4
//--------------------------------
C[1][0]=suma(M[1],M[3],num/2,num/2);
//--------------------------------
// C22=M1-M2+M3+M6
//--------------------------------
C[1][1]=resta(M[0],M[1],num/2,num/2);
aux1=C[1][1];
C[1][1]=suma(C[1][1],M[2],num/2,num/2);
aux2=C[1][1];
C[1][1]=suma(C[1][1],M[5],num/2,num/2);
borrarMatriz(aux1,num/2);
borrarMatriz(aux2,num/2);
for(int j=0; j<7; j++)
borrarMatriz(M[j],num/2);
// Combino las submatrices de C para formar sol.
for(f=0; f<num; f++){
for(c=0; c<num; c++){
sol[f][c]=C[f/(num/2)][c/(num/2)][f%(num/2)][c%(num/2)];
}
}
// Borro todas las estructuras auxiliares.
for(r=0; r<2; r++){
for(s=0; s<2; s++){
borrarMatriz(A[r][s],num/2);
borrarMatriz(B[r][s],num/2);
borrarMatriz(C[r][s],num/2);
}
}
return sol;
}
}
void ajustarDimensiones(Matriz &sol, int N, int nroFilas, int nroColumnas){
// Ajusta la matriz sol de tamaño N (siendo N una potencia de 2) a las
// dimensiones especificadas: nroFilas x nroColumnas.
Matriz ajustada=new int*[nroFilas];
for(int i=0; i<nroFilas; i++){
ajustada[i]=new int[nroColumnas];
for(int j=0; j<nroColumnas; j++)
ajustada[i][j]=sol[i][j];
}
borrarMatriz(sol,N);
sol=ajustada;
}
Matriz multiplicacionPorStrassen(Matriz A, Matriz B, int m, int n, int p){
// Pre: -Las matrices A y B son conformables.
// -A tiene dimension m x n.
// -B tiene dimension n x p.
// Devuelve el producto matricial A*B calculado mediante el algorimo de Strassen.
// Obs.: este procedimiento pide memoria.
int maximo=max(m,max(n,p));
int exp=int(ceil(log10(double(maximo))/log10(double(2))));
int N=int(pow(2,exp)); // calcula N=2^exp
Matriz A0=completarConCeros(A,m,n,N);
Matriz B0=completarConCeros(B,n,p,N);
Matriz sol=strassen(A0,B0,N);
ajustarDimensiones(sol,N,m,p);
borrarMatriz(A0,N);
borrarMatriz(B0,N);
return sol;
}
//----------------------------------------
void imprimirMatriz(Matriz A, int m, int n){
// Imprime la matriz A en el formato:
// >A[1][1] A[1][2] ... A[1][n]
// >A[2][1] A[2][2] ... A[2][n]
// >...
// >A[m][1] A[m][2] ... A[m][n]
for(int i=0; i<m; i++){
for(int j=0; j<n; j++)
cout << A[i][j] << " ";
cout << endl;
}
cout << endl;
}
//----------------------------------------
void borrarMatriz(Matriz &A, int m){
// Libera la memoria reservada para la matriz A (de m filas).
// No se necesita pasar como parametro el numero de columnas.
for(int i=0; i<m; i++)
delete[] A[i];
delete[] A;
}
main.cpp
#include <iostream>
using namespace std;
#include "Matriz.h"
/* Calcula la suma y el producto (en caso de ser posible)
de dos matrices ingresadas desde la entrada estandar. */
int main(){
cout << "Algebra matricial basica - 2012 - Rincon matematico\n" << endl;
char matriz1,matriz2;
cout << "NOMBRE MATRIZ 1: ";
cin >> matriz1;
int m1,n1;
cout << "Nro. de filas: "; cin >> m1;
cout << "Nro. de columnas: "; cin >> n1;
Matriz R1=crearMatriz(matriz1,m1,n1);
imprimirMatriz(R1,m1,n1);
cout << "NOMBRE MATRIZ 2: ";
cin >> matriz2;
int m2,n2;
cout << "Nro. de filas: "; cin >> m2;
cout << "Nro. de columnas: "; cin >> n2;
Matriz R2=crearMatriz(matriz2,m2,n2);
imprimirMatriz(R2,m2,n2);
if(m1==m2 && n1==n2){ // (si las matrices tienen las mismas dimensiones)
cout << "La matriz " << matriz1<<"+"<<matriz2 << " es:\n";
Matriz S=suma(R1,R2,m1,n1);
imprimirMatriz(S,m1,n1);
borrarMatriz(S,m1);
}
else
cout << "Las matrices no pueden sumarse.\n\n";
if(n1==m2){ // (si las matrices son conformables)
cout << "La matriz " << matriz1 << "*" << matriz2 << " es:\n";
Matriz P=multiplicacionConvencional(R1,R2,m1,n1,n2);
imprimirMatriz(P,m1,n2);
borrarMatriz(P,m1);
cout << endl;
cout << "La matriz " << matriz1 << "*" << matriz2 << " calculada mediante el algoritmo de Strassen es:\n";
P=multiplicacionPorStrassen(R1,R2,m1,n1,n2);
imprimirMatriz(P,m1,n2);
borrarMatriz(P,m1);
}
else
cout << "Las matrices no pueden multiplicarse.\n\n";
borrarMatriz(R1,m1);
borrarMatriz(R2,m2);
return 0;
}