Ver Mensaje Individual
  #2 (permalink)  
Antiguo 10/09/2015, 01:01
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 10 años, 2 meses
Puntos: 204
Respuesta: Limpiar columna en matriz de dos dimensiones

El código que aparece a continuación se entiende, no? una matriz declarada en la pila del programa:

Código C:
Ver original
  1. int mat[num_filas][num_columnas];

Esta matriz, en memoria, se almacena por filas: 1ªfila, 2ªfila, ... esto quiere decir que cada fila va a estar compuesta por num_columnas elementos. C no necesita saber el tamaño final de la matriz... únicamente necesita saber el tamaño de cada bloque para poder calcular los saltos correctamente. Es responsabilidad del programador no leer fuera de los límites de la matriz, por lo que el programa, simplemente, pasa de hacer chequeos.

Ejemplo:
Sabiendo que cada fila se compone de n columnas, si yo pongo:

Código C:
Ver original
  1. mat[3][4] = 50;

El programa realizará la siguiente operación:

Código C:
Ver original
  1. mat[ 3 * n + 4 ] = 50

Y tiene su sentido... si queremos acceder a la 4ª fila se entiende que tenemos que saltar del tirón las 3 primeras; teniendo en cuenta que cada una de estas filas está compuesta de n elementos... al final la posición [3][4] se encontrará haciendo el cálculo 3*n+4.

¿Y esto a qué viene? ahora lo vamos a ver... ahora llega la siguiente variable:

Código C:
Ver original
  1. int (*p)[num_columnas];

Esta variable tiene un asterisco, luego es, al menos, un puntero, pero además luego tiene los corchetes por lo que se trata de un puntero doble. La peculiaridad de este puntero doble es que especifica el tamaño de cada bloque... justo lo que te he explicado antes.

Inicialmente este puntero no hace nada útil ya que no apunta a nada, sin embargo después se hace:

Código C:
Ver original
  1. for(p = &mat[0];

En esa inicialización del for se hace que nuestro puntero doble apunte al inicio de mat. Y ¡sorpresa! ambas variables tienen el mismo tamaño de bloque. ¿Ves a dónde quiero ir a parar?

Bueno, seguimos con el programa...

En la condición del for se especifica que el bucle se repetirá hasta que p apunte fuera de la matriz. &mat[num_filas] devuelve la posición de memoria del inicio de lo que sería la fila que seguiría a la última fila, o, dicho de otra forma, devuelve la primera posición de memoria que ya no pertenece a la matriz, por lo que si p apunta a una posición de memoria igual o superior es que nos hemos pasado y el bucle se dará por finalizado:

Código C:
Ver original
  1. p < &mat[num_filas]

Y bueno, en los incrementos del bucle nos encontramos con esto:

Código C:
Ver original
  1. p++

p hemos dicho que es un puntero que apunta a bloques de num_columnas elementos, luego cada incremento hará que p avance de un bloque al siguiente. Es decir, en cada incremento p avanzara num_columnas elementos

Ahora la parte final del código:

Código C:
Ver original
  1. (*p)[i] = 0;

Es incorrecta... i no está inicializada, luego tendrá un valor completamente aleatorio.

Al final el programa no funciona símplemente por esa línea. ¿Qué falta? falta un segundo for dentro del primero que haga que i recorra el intervalo [0,num_columnas). Por cierto, nota que el intervalo es abierto por la derecha. Con código quedaría tal que:

Código C:
Ver original
  1. for(p = &mat[0]; p < &mat[num_filas]; p++)
  2.     for(i=0;i<num_columnas;++i)
  3.       *p[i] = 0;

Espero haberte aclarado la duda con esta respuesta.

Un saludo.