suma matrices

Iniciado por ALONSOQ, 18 Agosto 2012, 11:07 AM

0 Miembros y 1 Visitante están viendo este tema.

ALONSOQ

Hola,
como se suman estas dos matrices?

#include <stdlib.h>
#include<stdio.h>
#include <time.h>
#include<conio.h>

int n,d, i, j;

void  generar_matriz1 ();
void generar_matriz2 ();

 
int   main()
{
     
    srand (time(NULL));
   
       printf("dimensi\xA2n de la matriz1:");
    scanf("%d",&n);
   
       int matriz1[n][n];
             
        generar_matriz1 ();
       
        printf("dimensi\xA2n de la matriz2:");
    scanf("%d",&n);
   
       int matriz2[n][n];
             
        generar_matriz2 ();
         
        printf ("Presione una tecla para salir.....");
        getch();
       
}
/*********************************************/

void generar_matriz1 ()
{
   
    int matriz1[d][d];
   
    for (i=0;i<n;i++)
        {
            for (j=0;j<n;j++)
                {
                    matriz1[i][j]=(rand()%16);
                    printf("%d\t",matriz1[i][j]);
                }
            printf("\n\n");
        }
}

void generar_matriz2 ()
{
   
    int matriz2[d][d];
   
    for (i=0;i<n;i++)
        {
            for (j=0;j<n;j++)
                {
                    matriz2[i][j]=(rand()%16);
                    printf("%d\t",matriz2[i][j]);
                }
            printf("\n\n");
        }
}


muchas gracias pr vuestra ayuda

xiruko

#1
para sumar 2 matrices deben tener la misma dimension. luego en tu codigo usas la libreria conio.h, algo que no se recomienda por el foro mas que nada porque no es una libreria estandar (diria, yo no uso windows y la verdad no lo se seguro, pero diria que es eso). ademas, creo que la usas para la funcion getch(), y es que tienes una equivalente en la libreria estandar stdio.h que es getchar(). luego yo no estoy muy a favor de usar variables globales, y menos para contadores y demas. si es imprescindible pues si... pero en este caso no lo veo asi. ademas, tus 2 funciones de generar matrices son exactamente la misma, solo cambia el nombre de la variable. por que no haces una solo un poco mas generica y la aplicas a las variables que quieras?

para acabar, no sabia que se podia pedir la dimension de un arreglo y luego declarar la variable estaticamente en medio del codigo. si alguien experto puede aclararme esta duda se lo agradeceria, ya que yo en estos casos suelo usar memoria dinamica.

te dejo el codigo probado:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int** GenerarMatriz(int n); //funcion que devuelve un apuntador a un array de apuntadores
void SumarMatrices(int** m1, int** m2, const int n); //funcion que toma como parametros un apuntador a un array de apunt.

int main() {

int **matriz1=NULL, **matriz2=NULL, n; //se inicializan los apuntadores a apuntadores con NULL para evitar posibles problemas
srand(time(NULL));

printf("Dimension de las matrices: ");
scanf("%d", &n);
printf("\n");
while (getchar() != '\n'); //limpiamos el bufer stdin de basura, es buen habito ponerlo despues del scanf

matriz1=GenerarMatriz(n); //primera matriz
matriz2=GenerarMatriz(n); //segunda matriz
SumarMatrices(matriz1, matriz2, n);

free(matriz1); //siempre que se reserva memoria hay que liberarla al final
free(matriz2);
printf("Pulse enter para salir...");
getchar();
return 0;
}

int** GenerarMatriz(const int n) {

int** matriz=NULL, i, j;

//se reserva memoria
matriz=(int**)malloc(n*sizeof(int*)); //reservamos memoria para el array de apuntadores (seran las filas abc en el caso del ejemplo de abajo)
for (i=0; i<n; i++)
*(matriz+i)=(int*)malloc(n*sizeof(int)); //para cada apuntador en el array, le asignamos memoria (los vectores 123, 456, 789, o columnas de la matriz)

//aqui rellenamos cada elemento con un numero aleatorio
for (i=0; i<n; i++) {
for (j=0; j<n; j++) {
*(*(matriz+i)+j)=rand()%16;
printf("%d\t", *(*(matriz+i)+j));
}
printf("\n");
}
printf("\n");
return matriz; //con esto hacemos que matriz1 (variable del main y primera matriz) apunte al mismo sitio que "matriz", la creada en esta funcion
}

void SumarMatrices(int** m1, int** m2, const int n) {

int i, j;

for (i=0; i<n; i++) {
for (j=0; j<n; j++) {
printf("%d\t", (*(*(m1+i)+j))+(*(*(m2+i)+j)));
}
printf("\n");
}
printf("\n");
}


un saludo!

0xDani

Yo estoy casi seguro de que no se puede declarar un arreglo con tamaño variable, hay que usar una expresion constant, para eso debes usar memoria dinamica.

Saludos.
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

xiruko

ya y yo tambien creia eso, pero cogi su codigo y lo copie, compile solo cambiando un par de cosas por no estar en windows, y corria perfectamente, de ahi que dude. sabes por que funciona aunque recomienden no hacerlo?

gracias y un saludo!

ALONSOQ

Muchas gracias por tu ayuda xiruco. La verdad es que me cuesta muchísimo entender lo que has redactado. ¿ sería muy dificil sumar a partir de mi código?

gracias de nuevo

xiruko

a ver... para sumar 2 matrices tienen que tener la misma dimension. asi que en tu codigo, con pedir 1 vez la dimension es suficiente. y luego, el trozo de codigo para sumar no es mas que recorrer la matriz igual que lo haces para inicializarla con rand(), pero en vez de eso pones un printf() que muestre matriz1[ i][j]+matriz2[ i][j].

todo el resto del codigo de antes es para solucionar varios errores que cometes en toda la otra parte de codigo, tambien para solucionar el desorden y estructurarlo un poco, y para que sea mas entendible al leerlo.

si ya has estudiado funciones y apuntadores, si quieres modifico mi mensaje anterior añadiendo explicaciones en el codigo para que asi puedas seguirlo y entenderlo; si no, no le hagas mucho caso ya que te sonara a chino y primero deberias leerte la teoria antes de dedicarte a la practica.

un saludo!

rir3760

Cita de: daniyo en 18 Agosto 2012, 23:37 PMYo estoy casi seguro de que no se puede declarar un arreglo con tamaño variable, hay que usar una expresion constant, para eso debes usar memoria dinamica.
En C una declaración como esta:
printf("dimensi\xA2n de la matriz1:");
scanf("%d",&n);

int matriz1[n][n];

No es valida si se compila según el estándar C90, este requiere que el numero de elementos en un array se indique mediante una expresión constante.

Pero en los dos siguientes estándares de C (C99 y C11) si es posible, a esos arrays donde el numero de elementos se calcula en tiempo de ejecución se les conoce como "variable length arrays" o "VLAs".

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

ALONSOQ

Cita de: xiruko en 19 Agosto 2012, 23:24 PM
a ver... para sumar 2 matrices tienen que tener la misma dimension. asi que en tu codigo, con pedir 1 vez la dimension es suficiente. y luego, el trozo de codigo para sumar no es mas que recorrer la matriz igual que lo haces para inicializarla con rand(), pero en vez de eso pones un printf() que muestre matriz1[ i][j]+matriz2[ i][j].

todo el resto del codigo de antes es para solucionar varios errores que cometes en toda la otra parte de codigo, tambien para solucionar el desorden y estructurarlo un poco, y para que sea mas entendible al leerlo.

si ya has estudiado funciones y apuntadores, si quieres modifico mi mensaje anterior añadiendo explicaciones en el codigo para que asi puedas seguirlo y entenderlo; si no, no le hagas mucho caso ya que te sonara a chino y primero deberias leerte la teoria antes de dedicarte a la practica.

un saludo!

Hola Xiruco, sí me he estudiado las funciones y apuntadores, de hecho el problema es que no entiendo bien el tema de apuntadores y paso de argumentos por referencia a las matrices; si no te es mucha molestia, a lo mejor añadiendo las explicaciones al código me sirven de ayuda.

un saludo

xiruko

#8
si no entiendes bien el tema apuntadores repasalos en este enlace que no es muy largo y esta bien explicado:

http://c.conclase.net/curso/?cap=012

en cuanto a las matrices, estas no son mas que un apuntador a un array de apuntadores a entero (en este caso).  en el code que te deje tendriamos esto:

                i           j
matriz -> | a | -> | 1 | 2 | 3 |
              | b | -> | 4 | 5 | 6 |
              | c | -> | 7 | 8 | 9 |

donde los vectores 123, 456, 789 son un array de enteros, y representan las filas de la matriz. el vector abc es un array de apuntadores a enteros: "a" es un apuntador a entero (int*) y apunta a "1"; "b" es un apuntador a entero y apunta a "4"; etc. y luego "matriz" es un apuntador a un array de apuntadores (int**), y "matriz" apunta, como en toda cadena de cualquier cosa, al primer elemento "a".

entonces, si por ejemplo quieres acceder al numero 4, y cogemos los indices i,j del dibujo, seria: matriz[1][0] (recuerda que los arrays empiezan en la posicion 0), o lo que es lo mismo: *(*(matriz+1)+0). para el numero 8 seria matriz[2][1] o *(*(matriz+2)+1). etc.

si hasta aqui lo entiendes, entonces lo de pasar por referencia a una funcion como parametro no es mas que darle el apuntador de la matriz a la funcion, en este caso "matriz". asi luego dentro de la funcion podras acceder y modificar cualquier elemento de la matriz.

no se si me explique muy bien, ahora comentare un poco el code de antes y si tienes alguna duda en particular intentaremos resolverla.

un saludo!

edito:
CitarNo es valida si se compila según el estándar C90, este requiere que el numero de elementos en un array se indique mediante una expresión constante.

Pero en los dos siguientes estándares de C (C99 y C11) si es posible, a esos arrays donde el numero de elementos se calcula en tiempo de ejecución se les conoce como "variable length arrays" o "VLAs".
gracias por comentarlo, no tenia ni idea y ya me he puesto al dia leyendo sobre ello.

ALONSOQ

Muchísimas gracias de verdad por la explicación tan buena  y detallada que me has dado; realmente me ha servido de mucho.