Recorrer una tabla entera
Dos ciclos, uno dentro del otro: filas por fuera, columnas por dentro.
1Por qué
En la lección 15 armaste una tabla y pusiste un número en una casilla. Eso demuestra que la estructura existe, pero ningún programa trabaja así: las tablas se llenan y se recorren enteras.
Y para recorrer algo con filas y columnas hacen falta dos ciclos, uno dentro del otro. El de fuera elige la fila; el de dentro pasa por todas sus columnas antes de que el de fuera avance. Por eso, si imprimes dentro del ciclo interior, sale fila por fila y no columna por columna.
Lo que confunde al principio es el orden de los corchetes. m[i][j] es primero la fila, después la columna, y no al revés. Ya viste por qué en la lección 15: el primer corchete elige uno de los punteros de arriba, y el segundo se mueve dentro de la fila a la que ese puntero apunta. Dos saltos, en ese orden.
Si los cambias sin querer, con una tabla cuadrada el programa no se queja —simplemente hace otra cosa—, y con una que no lo sea te sales de la fila. Es de los errores más difíciles de ver leyendo, y de los más fáciles de encontrar mirando el dibujo de la memoria.
Un detalle práctico: i * cols + j convierte una posición de dos dimensiones en un número corrido. Es la misma cuenta que hace el computador por dentro cuando la tabla está toda junta.
2Míralo andar
Este programa funciona. Léelo, y después ejecútalo sin cambiar nada.
#include <stdio.h>#include <stdlib.h>int main(void){int filas = 2;int cols = 3;int **m = calloc(filas, sizeof(int *));for (int i = 0; i < filas; i++)m[i] = calloc(cols, sizeof(int));for (int i = 0; i < filas; i++){for (int j = 0; j < cols; j++)printf("%d ", m[i][j]);printf("\n");}for (int i = 0; i < filas; i++)free(m[i]);free(m);return 0;}
- línea 13
El de fuera elige la fila. Hace una vuelta por cada una. - línea 15
El de dentro recorre esa fila entera antes de que el de fuera avance. Por eso sale fila por fila. - línea 16
El salto de línea va DESPUÉS del ciclo interior: cuando se acabó una fila, no cuando se acabó una casilla. - línea 20
callocdejó todo en cero, así que salen ceros. La lección siguiente es llenarla.
3Ahora tú
Esta tabla se recorre pero nadie la llenó, así que suma 0. Escribe la línea que pone en cada casilla su posición corrida, para que sume: 15
#include <stdio.h>#include <stdlib.h>int main(void){int filas = 2;int cols = 3;int **m = calloc(filas, sizeof(int *));for (int i = 0; i < filas; i++)m[i] = calloc(cols, sizeof(int));for (int i = 0; i < filas; i++)for (int j = 0; j < cols; j++){}int suma = 0;for (int i = 0; i < filas; i++)for (int j = 0; j < cols; j++)suma = suma + m[i][j];printf("%d\n", suma);for (int i = 0; i < filas; i++)free(m[i]);free(m);return 0;}
↖︎ Tu línea va aquí: lo que se hace una vez por cada casilla.
Ejecutar
Lo que dice tu programa
↖︎ Escribe tu parte y dale a Ejecutar
Qué pasó
Aquí te aviso si tu programa hace algo raro.
4Qué guarda tu programa
Memoria
↖︎ Ejecuta el programa para ver qué pasa por dentro