Módulo 06: Matrices (arrays 2D)

Idea central

Un array 1D guarda una fila de valores. Una matriz (array 2D) guarda una cuadrícula de valores: filas × columnas. El problema que resuelve es organizar datos con dos índices naturales (píxeles de imagen, celdas de hoja de cálculo, tablero de juego, resultados de alumnos por asignatura).


Qué aprendes

ConceptoPara qué sirve
Declarar int m[F][C]Reservar una cuadrícula fija en memoria
Doble bucle for (i) for (j)Recorrer todas las celdas fila a fila
Leer con scanf en 2DIntroducir datos celda a celda
Imprimir con formatoMostrar la cuadrícula alineada
Suma de matricesSumar elemento a elemento
Suma por filas / columnasReducir la matriz a vectores
TranspuestaIntercambiar filas y columnas
Diagonal principalRecorrer solo donde i == j
Máximo globalBuscar el mayor valor en la cuadrícula
Matriz identidadConstruir una cuadrícula con patrón

Explicación

Categoría: estructura de datos 2D

Una matriz en C es un array de arrays. La memoria es contigua: primero toda la fila 0, luego toda la fila 1, etc.

m[0][0]  m[0][1]  m[0][2]
m[1][0]  m[1][1]  m[1][2]
m[2][0]  m[2][1]  m[2][2]

Patrón: declarar y recorrer

#define FILAS 3
#define COLS  4
 
int m[FILAS][COLS];          // declaracion
 
// Recorrer TODAS las celdas
for (int i = 0; i < FILAS; i++) {
    for (int j = 0; j < COLS; j++) {
        // usar m[i][j]
    }
}

El índice exterior i selecciona la fila, el interior j selecciona la columna.

Sintaxis: leer e imprimir

// Leer
scanf("%d", &m[i][j]);   // OBLIGATORIO el &
 
// Imprimir con separacion
printf("%4d", m[i][j]);  // %4d: campo de 4 caracteres, queda alineado
printf("\n");             // salto de linea al acabar cada fila (bucle exterior)

Patrón: suma de matrices

for (int i = 0; i < F; i++)
    for (int j = 0; j < C; j++)
        r[i][j] = a[i][j] + b[i][j];

Patrón: suma por filas

for (int i = 0; i < F; i++) {
    int suma = 0;
    for (int j = 0; j < C; j++)
        suma += m[i][j];
    printf("Fila %d: %d\n", i, suma);
}

Patrón: transpuesta (requiere matriz destino de dimensiones invertidas)

// m es F x C  ->  t es C x F
for (int i = 0; i < F; i++)
    for (int j = 0; j < C; j++)
        t[j][i] = m[i][j];

Patrón: diagonal principal (solo cuadradas, i == j)

int diag = 0;
for (int i = 0; i < N; i++)
    diag += m[i][i];

Patrón: máximo global

int max = m[0][0];
for (int i = 0; i < F; i++)
    for (int j = 0; j < C; j++)
        if (m[i][j] > max)
            max = m[i][j];

Worked example

Problema: leer una matriz 3×3 de enteros e imprimir la suma de cada columna.

Paso 1 — entender la tarea

Tenemos 3 columnas. Para la columna j hay que sumar m[0][j] + m[1][j] + m[2][j], es decir, el bucle exterior recorre columnas y el interior filas.

Paso 2 — código

#include <stdio.h>
 
#define N 3
 
int main(void) {
    int m[N][N];
 
    // Paso A: leer la matriz
    printf("Introduce los %d valores fila a fila:\n", N * N);
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            scanf("%d", &m[i][j]);   // <- & es obligatorio
 
    // Paso B: imprimir la matriz para confirmar
    printf("\nMatriz introducida:\n");
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++)
            printf("%4d", m[i][j]);
        printf("\n");
    }
 
    // Paso C: suma por columnas (bucle exterior = columna)
    printf("\nSuma por columnas:\n");
    for (int j = 0; j < N; j++) {
        int suma = 0;
        for (int i = 0; i < N; i++)
            suma += m[i][j];
        printf("  Col %d: %d\n", j, suma);
    }
 
    return 0;
}

Paso 3 — traza con entrada 1 2 3 / 4 5 6 / 7 8 9

Matriz:
   1   2   3
   4   5   6
   7   8   9

Col 0: 1+4+7 = 12
Col 1: 2+5+8 = 15
Col 2: 3+6+9 = 18

Por qué funciona

  • El & en scanf("%d", &m[i][j]) pasa la dirección de la celda, no su valor.
  • Invertir el orden de los bucles (j exterior, i interior) es la clave para iterar por columnas en vez de por filas.
  • Inicializar suma = 0 dentro del bucle de columna la resetea para cada columna.

Errores típicos en C

#ErrorConsecuenciaCorrección
1scanf("%d", m[i][j]) sin &Comportamiento indefinido, casi siempre segfaultSiempre &m[i][j]
2Declarar int m[3][3] y acceder a m[3][0]Buffer overflow, datos corruptosLos índices van de 0 a N-1
3int suma; sin inicializar antes del bucleSuma basura (valor indeterminado)int suma = 0;
4Confundir filas y columnas al pasar a funciónLa función recibe dimensiones cruzadasDocumentar siempre cuál es F y cuál es C
5Usar == con float en la diagonalComparación inexacta para floatsUsar enteros o comparar con tolerancia fabs(a-b) < EPS

Ejercicios

Practica lo de este módulo. Cada enlace abre el ejercicio con su enunciado, diagrama de flujo, explicación y el código listo para copiar.

Conexiones