Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: patilanz en 22 Abril 2014, 07:51 am



Título: Duda con matrices y paso por parametro
Publicado por: patilanz en 22 Abril 2014, 07:51 am
Hola se que para pasar matrices hay que indicar la longitud de la columna pero no se porque ya que en la memoria están organizados uno a continuación del otro. Mi pregunta es como sabe c++ o el compilador el tamaño de las filas ?

Saludos


Título: Re: Duda con matrices y paso por parametro
Publicado por: engel lex en 22 Abril 2014, 07:57 am
por el tipo de variable....

columna = memoria_inicial + tamaño_de_la_variable*posicion

fila = memoria_inicial +  tamaño_de_la_variable*cantidad_de_columnas*posicion

esa es la teoria, creo...


Título: Re: Duda con matrices y paso por parametro
Publicado por: eferion en 22 Abril 2014, 08:50 am
El motivo es porque la memoria en el caso de las matrices se alinea por columnas ( o filas, depende de cómo se mire ). Me explico.

Si defines una matriz tal que int matriz[3][2]; en memoria se crea el siguiente mapa:

Código:
[0,0][1,0][2,0][0,1][1,1][2,1]

Como se ve, el tamaño de cada "bloque" se corresponde con el primer valor ( filas o columnas a gusto del consumidor )... el segundo valor determina el número de bloques.

Al compilador le da igual (por que no lo va a comprobar) cual es el tamaño real del buffer. Únicamente necesita conocer el tamaño de cada "bloque" para poder calcular el desplazamiento ... el número de bloques es irrelevante para él... si te pasas ya se encargará el SO de darte un par de collejas.


Título: Re: Duda con matrices y paso por parametro
Publicado por: vangodp en 22 Abril 2014, 15:49 pm
a ver jeje cada vez que veo algo sobre matrices me lio mas y eso que ja lo tengo entendio  ;D

El orden es el tuyo o es este por que en el vídeo este el la pinta así y ahora me lio XD:
https://www.youtube.com/watch?v=TEyLHaTFGEU
[0,0][0,1]
[1,0][1,1]
[2,0][2,1]

[col][fil]
[col][fil]
[col][fil]

[0,0][0,1][1,0][1,1][2,0][2,1]
|------------------------------>

¿No?

[0,0][0,1]
               [1,0][1,1]
                             [2,0][2,1]

así no??  :huh:
o puede que lo aya entendió mal no se XDD


Título: Re: Duda con matrices y paso por parametro
Publicado por: eferion en 22 Abril 2014, 16:31 pm
Cierto, me confundí con fortran.

En cualquier caso, el fundamento es el mismo... en el caso de una matriz bidimensional tienes que proporcionar el tamaño del bloque, da igual que sea filas o columnas.

En el caso de un vector no es necesario indicar ningún tamaño porque no hay bloques... solo un buffer de tamaño desconocido para el compilador ( no olvidemos que el parámetro que se pasa no deja de ser un puntero, independientemente de que el argumento sea un vector o una matriz )


Título: Re: Duda con matrices y paso por parametro
Publicado por: rir3760 en 22 Abril 2014, 16:46 pm
para pasar matrices hay que indicar la longitud de la columna pero no se porque
Porque es parte del tipo.

Lo que tu llamas matriz es un array donde cada uno de sus elementos es también un array. Por ejemplo con la sentencia:
Código
  1. int mat[N][M];
Se declara el array "mat" de N elementos cada uno de tipo "int [M]".

Mi pregunta es como sabe c++ o el compilador el tamaño de las filas ?
No lo sabe. Si declaras una función en cualquiera de las dos formas:
Código
  1. /* A */ int fn(int a[N]);
  2. /* B */ int fn(int a[ ]);
La declaración en realidad es:
Código
  1. /* C */ int fn(int *a);
Ello porque los arrays no se pasan por valor, en su lugar el argumento es la dirección en memoria del primer elemento.

Un saludo


Título: Re: Duda con matrices y paso por parametro
Publicado por: amchacon en 22 Abril 2014, 17:28 pm
Te pide el tamaño de la fila para que el compilador pueda hacer la conversión matriz -> array internamente.


Título: Re: Duda con matrices y paso por parametro
Publicado por: vangodp en 22 Abril 2014, 17:54 pm
A ver compañeros :) gracias por aclarar que hasta yo me lio con eso XDD

Si creo una matriz que digamos así: int matriz [][];

Y quiero que la columna sea matriz [columna][] y la fila matriz[][fila] tal que quede matriz[columna][fila];

¿a la funcion como le paso eso?

¿asi?   int funcion ( int matriz[ ][tamaño de la fila], int columna){...}

Por que tengo un lio de copón como los demás aquí, con tanta filafila columna columna y cada uno lo llama como le gusta XDD :laugh:


Título: Re: Duda con matrices y paso por parametro
Publicado por: amchacon en 22 Abril 2014, 18:22 pm
Tamaño fila debe conocerse durante la compilación. Por lo que no puede ser una variable global que tengas por ahi (aunque una constante si valdria).

Si estas en C++. Puedes hacer un vector de vector. Asi no te lias ;)


Título: Re: Duda con matrices y paso por parametro
Publicado por: ivancea96 en 22 Abril 2014, 22:04 pm
Si os sirve de algo,
Código
  1. int funcion ( int matriz[][], int fila, int columna){...}

es lo mismo que


Código
  1. int funcion ( int **matriz, int fila, int columna){...}


Título: Re: Duda con matrices y paso por parametro
Publicado por: amchacon en 22 Abril 2014, 23:43 pm
La primera linea no va a compilar...

Y si compila no va a aceptar matrices estaticas. Solo las que se han creado dinámicamente.


Título: Re: Duda con matrices y paso por parametro
Publicado por: rir3760 en 23 Abril 2014, 02:40 am
Si os sirve de algo,
Código
  1. int funcion ( int matriz[][], int fila, int columna){...}

es lo mismo que
Código
  1. int funcion ( int **matriz, int fila, int columna){...}
No. Como ya te indico amchacon la primera declaración:
Código
  1. int funcion ( int matriz[][], int fila, int columna){...}
Se procesa como si fuera:
Código
  1. int funcion ( int (*matriz)[], int fila, int columna){...}
Y el compilador debe quejarse ya que el tipo apuntado esta incompleto: "int []".

Para que pueda compilarse se debe completar el tipo, por ejemplo:
Código
  1. int funcion ( int matriz[][10], int fila, int columna){...}
La cual se procesa como si fuera:
Código
  1. int funcion ( int (*matriz)[10], int fila, int columna){...}

Un saludo


Título: Re: Duda con matrices y paso por parametro
Publicado por: vangodp en 23 Abril 2014, 04:44 am
int **matriz, Esto es un puntero que apunta otro puntero ¿verdad señores? No lo entiendo muy bien ese mecanismo aun  :laugh:

¿Que efecto tiene poner () en (*matriz)?
As veces veo cosas como *(matriz). No digo que sea en caso de matrices ni de tablas por que no me acuerdo :), solo se que as veces lo veo como ahora y no se muy bien cual es el mecanismo que tiene eso.
¡Gracias maestros! Que fieras soys =D


Título: Re: Duda con matrices y paso por parametro
Publicado por: Blaster en 23 Abril 2014, 14:00 pm
int **matriz, Esto es un puntero que apunta otro puntero ¿verdad señores? No lo entiendo muy bien ese mecanismo aun  :laugh:

En efecto eso seria un puntero a puntero.

¿Que efecto tiene poner () en (*matriz)?
As veces veo cosas como *(matriz). No digo que sea en caso de matrices ni de tablas por que no me acuerdo :), solo se que as veces lo veo como ahora y no se muy bien cual es el mecanismo que tiene eso.

En realidad no tiene ningun efecto pasarlo de esta manera

Código
  1. int funcion ( int matriz[][10], int fila, int columna)

Es totalmente equivalente al pasarlo de esta forma

Código
  1. int funcion ( int (*matriz)[10], int fila, int columna)

Tal vez sean distintas sintaxticamete pero conceptualmente son equivalentes, indicando que el parametro es un puntero a matriz de 10 int

Saludos..



Título: Re: Duda con matrices y paso por parametro
Publicado por: rir3760 en 23 Abril 2014, 14:17 pm
¿Que efecto tiene poner () en (*matriz)?
En el caso de una declaración primero se consideran los paréntesis y corchetes (para indicar función y array, respectivamente) y solo después el '*', por ejemplo:
Código
  1. /* Array de <10 elementos de tipo "int *"> */
  2. int *matriz[10];

Si se desea utilizar otro orden (primero el asterisco) se deben utilizar paréntesis:
Código
  1. /* Puntero a <array de 10 elementos de tipo "int"> */
  2. int (*matriz)[10];

Un saludo


Título: Re: Duda con matrices y paso por parametro
Publicado por: ivancea96 en 23 Abril 2014, 15:02 pm
Código
  1. int funcion ( int matriz[][], int fila, int columna){...}

Código
  1. int funcion ( int **matriz, int fila, int columna){...}

Fallo mío.



En verdad, no le veo la utilidad a un parámetro del tipo:
Código
  1. int funcion ( int matriz[][9]){...}

Pudiendo pasar:
Código
  1. int funcion ( int **matriz){...}

Hay alguna ganancia? Se puede pasar una matriz a cualquiera de ellos. Es más, se detecta como una redefinición en caso de poner:

Código
  1. void f(int *m[5]){
  2. }
  3. void f(int **m){
  4. }

No se sobrecarga.


Título: Re: Duda con matrices y paso por parametro
Publicado por: vangodp en 23 Abril 2014, 15:07 pm
madre mía que verde estoy con las matrices, jeje gracias chicos  :laugh:
voy a tener que ponerme a 100 con ellas que me tienen algo desconcertado  :-(


Título: Re: Duda con matrices y paso por parametro
Publicado por: ivancea96 en 23 Abril 2014, 15:32 pm
Quizás te ayude verlo como punteros, y como punteros de punteros, no como "matrices".


Título: Re: Duda con matrices y paso por parametro
Publicado por: amchacon en 23 Abril 2014, 16:19 pm
En verdad, no le veo la utilidad a un parámetro del tipo:
Código
  1. int funcion ( int matriz[][9]){...}

Pudiendo pasar:
Código
  1. int funcion ( int **matriz){...}

Hay alguna ganancia? Se puede pasar una matriz a cualquiera de ellos. Es más, se detecta como una redefinición en caso de poner:

Código
  1. void f(int *m[5]){
  2. }
  3. void f(int **m){
  4. }

No se sobrecarga.
La diferencia en que una definición espera una matriz estatica y otra definición espera punteros de punteros.

A la seguna definición no le puedes pasar una matriz estatica:
Citar
error: cannot convert 'int (*)[9]' to 'int**' for argument '1' to 'void f(int**)'|

Las matrices estáticas no se almacenan como punteros de punteros, sino como un array muy largo. Es el compilador quien traduce los dos [] [] por uno solo []. Para hacer eso necesita saber el tamaño del primero.


Título: Re: Duda con matrices y paso por parametro
Publicado por: vangodp en 23 Abril 2014, 17:38 pm
Si que puntero de puntero tiene que apuntar a puntero, y la otra pues es estática.
Algo me queda lo que me falla es lo de las () que me explicasteis antes. XDD
¡Gracias compañeros!
Voy a repasar un poco los punteros, y las matrices. Si tengo dudas y me podéis ayudar luego pues se los agradezco  ;)


Título: Re: Duda con matrices y paso por parametro
Publicado por: leosansan en 24 Abril 2014, 15:27 pm
Hola se que para pasar matrices hay que indicar la longitud de la columna pero no se porque ya que en la memoria están organizados uno a continuación del otro. Mi pregunta es como sabe c++ o el compilador el tamaño de las filas ?


El tamaño de las filas no lo sabe el compilador ¡!!¡. Como indicó eferion, es problema del programador atenerse a las dimensiones que previamente se han introducido y, por lo tanto los bloques de memoria que se han reservado para el array,  bien de forma estática o dinámica.

Aquí me surge una duda con el código que pongo a continuación y en el que las posiciones de memoria son consecutivas en el caso de una matriz estática, pero no así con una matriz dinámica. Además la diferencia de 16  es para este compilador, ya que en otros me da 24. ¿Es normal o estoy haciendo algo mal?:


Citar

                MAIN DECLARACION


        1 Direcciones en MAIN Estatico

        &=2686688       &=2686692       &=2686696
        &=2686700       &=2686704       &=2686708
        &=2686712       &=2686716       &=2686720
        &=2686724       &=2686728       &=2686732

        2 Direcciones en MAIN Dinamico

        &=4069016       &=4069020       &=4069024
        &=4069040       &=4069044       &=4069048
        &=4069064       &=4069068       &=4069072
        &=4069088       &=4069092       &=4069096


Y el código dedicado al amigo vangodp con el paso a una función de una matriz estática, observa que tengo dos posibilidades, y de una matriz dinámica, también con dos posibilidades. Tiene la impresión de las direcciones de memoria, con una opción variable, para aclarar ¿? como por un lado se reservan las direcciones de memoria, con la sola declaración de la matriz, y por otro lado como esas posiciones justamente son las que se rellenan y siempre que nos atengamos a las dimensiones correctas en el relleno, si no nos podemos ir más allá de las posiciones de memoria reservadas o machacar las posiciones anteriores de la matriz:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define FIL   4
  5. #define COL   3
  6. #define   N   0 /*prueba y dale un valor positivo o negativo inferior a COL
  7.                  y observa que si es positivo de COL te vas mas alla de las
  8.                  direcciones que estaban reservadas, malo, malo, y si es
  9.                  negativo observa como sobreescribes las posiciones
  10.                  ateriores del array*/
  11.  
  12.  
  13. void matriz ( int a0[]/*[FIL]*/[COL-N]){ /* dos opciones*/
  14.  int i=0, j;
  15.  printf ("\n\t\tFUNCION COL(%d)-N(%d)=%d\n\n",COL,N,COL-N);
  16.  for (i=0;i<FIL;i++){
  17.    for (j=0;j<COL;j++){
  18.      printf ("a0[%d][%d]=%2d  &=%d  ",i,j,a0[i][j],/**(a0+i)+j*/(int)&a0[i][j]);
  19.    }
  20.    putchar('\n');
  21.  }
  22. }
  23.  
  24. void matriz1 ( int **a1){
  25.  int i=0, j;
  26.  puts ("\n\t\tFUNCION 1\n");
  27.  for (i=0;i<FIL;i++){
  28.    for (j=0;j<COL;j++){
  29.      printf ("a1[%d][%d]=%2d  &=%d  ",i,j,a1[i][j],(int)&a1[i][j]);
  30.    }
  31.    putchar('\n');
  32.  }
  33. }
  34.  
  35. void matriz2 ( int *a2[COL]){
  36.  int i=0, j;
  37.  puts ("\n\t\tFUNCION 2\n");
  38.  for (i=0;i<FIL;i++){
  39.    for (j=0;j<COL;j++){
  40.      printf ("a2[%d][%d]=%2d  &=%d  ",i,j,a2[i][j],(int)&a2[i][j]);
  41.    }
  42.    putchar('\n');
  43.  }
  44. }
  45.  
  46. int main(){
  47.  int i=0, j,k=0,**a_ ,a[FIL][COL];
  48.  puts ("\n\t\tMAIN DECLARACION\n");
  49.  puts ("\n\t1 Direcciones en MAIN Estatico\n");
  50.  for (i=0;i<FIL;i++){
  51.    for (j=0;j<COL;j++)
  52.      printf ("\t&=%d  ",(int)&a[i][j]);
  53.    putchar('\n');
  54.  }
  55.  a_ = malloc( FIL * sizeof *a_ );
  56.  for( i = 0; i < FIL; i++ )
  57.    a_[i] = malloc( COL * sizeof **a_ );
  58.  
  59.  puts ("\n\t2 Direcciones en MAIN Dinamico\n");
  60.  for (i=0;i<FIL;i++){
  61.    for (j=0;j<COL;j++)
  62.      printf ("\t&=%d  ",(int)&a_[i][j]);
  63.    putchar('\n');
  64.  }
  65.  putchar('\n');
  66.  printf ("\n\t\tMAIN RELLENO COL=%d\n\n",COL);
  67.  for (i=0;i<FIL;i++){
  68.    for (j=0;j<COL;j++,k++){
  69.    a[i][j]=k;
  70.    printf ("a[%d][%d]=%2d  &=%d  ",i,j,a[i][j],(int)&a[i][j]);
  71.    }
  72.    putchar('\n');
  73.  }
  74.  putchar('\n');
  75.  for (i=0;i<FIL;i++){
  76.    for (j=0;j<COL;j++,k++){
  77.    a_[i][j]=k;
  78.    printf ("a_[%d][%d]=%2d  &=%d  ",i,j,a_[i][j],(int)&a_[i][j]);
  79.    }
  80.    putchar('\n');
  81.  }
  82.  matriz (a);
  83.  putchar('\n');
  84.  matriz1 (a_);
  85.  putchar('\n');
  86.  matriz2 (a_);
  87.  for( i= 0; i<FIL; ++i )
  88.    free(a_[i]);
  89.  free(a_);
  90.  a_ = NULL;
  91.  return 0;
  92. }

Espero no haber metido la pata, al menos he logrado que  no me lance ningún warning y si no ha sido así comprensión por vuestro lado que  la intención ha sido la mejor. ;)


¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)



Título: Re: Duda con matrices y paso por parametro
Publicado por: vangodp en 24 Abril 2014, 17:08 pm
voy a estudiarlo leo =D
que fiera jeje, me has dedicado un tutorial entero  ;-)
¡Luego te lo comento muchas gracias!