3.04 · Arreglos Bidimensionales (Matrices)
🧠 Teoría y conceptos — 🟦 1. ¿Qué es una matriz?

Figura: Matriz 3x4 con índices y valores
Una matriz es un arreglo de arreglos:
// Matriz de 3 filas x 4 columnas
int matriz[3][4] = {
{1, 2, 3, 4}, // fila 0
{5, 6, 7, 8}, // fila 1
{9, 10, 11, 12} // fila 2
};
cout << matriz[1][2] << endl; // 7 (fila 1, columna 2)
Acceso: [fila][columna]
matriz[0][0] = 1; // esquina superior izquierda
matriz[0][3] = 4; // esquina superior derecha
matriz[2][0] = 9; // esquina inferior izquierda
matriz[2][3] = 12; // esquina inferior derecha
⚠️ Trampa mental: orden de índices
matriz[fila][columna] — la fila primero. Es como notación matemática: a_{i,j} donde i es fila y j es columna. Si los volteas, accedes a otro elemento (o fuera de rango).
🧠 2. Cómo se guarda en memoria

Concepto clave: una matriz es lineal en memoria. El compilador la guarda fila por fila:
Índice lineal: 0 1 2 3 4 5 6 7 8 9 10 11
Valor: 1 2 3 4 5 6 7 8 9 10 11 12
└─ fila 0 ─┘└─ fila 1 ─┘└─ fila 2 ─┘
Fórmula: matriz[i][j] está en la posición lineal i * numColumnas + j.
int matriz[3][4];
// matriz[1][2] = posición 1*4 + 2 = 6
¿Por qué importa esto? Porque cuando recorres mal la matriz (por columnas en vez de filas), el patrón de acceso a memoria es ineficiente — la CPU "salta" y tarda más. No lo vas a notar con 12 elementos; con una imagen de 1920×1080 sí.
📏 3. Inicialización

Completa con valores
int matriz[2][3] = {{1, 2, 3}, {4, 5, 6}};
Con ceros
int matriz[3][3] = {}; // todo en 0
int matriz[3][3] = {0}; // también
Sin valores específicos (c++11+)
int matriz[3][3] = {{1, 2}, {4}}; // completa con 0
// {{1, 2, 0}, {4, 0, 0}, {0, 0, 0}}
Tamaño variable con constantes
const int FILAS = 3;
const int COLS = 4;
int matriz[FILAS][COLS];
Regla: usa `const int` para tamaños. Te protege de typos y el compilador puede optimizar.
🔄 4. Recorrido: por filas vs por columnas

Por filas (patrón recomendado en C++)
Figura: Recorrido por filas
int m[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
for (int i = 0; i < 3; i++) { // filas
for (int j = 0; j < 4; j++) { // columnas
cout << m[i][j] << "\t";
}
cout << endl;
}
Salida: 1 2 3 4 / 5 6 7 8 / 9 10 11 12 — una fila por línea.
Por columnas
Figura: Recorrido por columnas
for (int j = 0; j < 4; j++) { // columnas primero
for (int i = 0; i < 3; i++) { // filas
cout << m[i][j] << "\t";
}
cout << endl;
}
Salida: 1 5 9 / 2 6 10 / 3 7 11 / 4 8 12 — una columna por línea.
Lección: con matrices pequeñas ambas funcionan. Con matrices grandes, recorre por filas (es el orden natural de la memoria en C++).
➕ 5. Operaciones básicas

Suma de todos los elementos
int suma = 0;
for (int i = 0; i < FILAS; i++) {
for (int j = 0; j < COLS; j++) {
suma += matriz[i][j];
}
}
Suma por fila
for (int i = 0; i < FILAS; i++) {
int sumaFila = 0;
for (int j = 0; j < COLS; j++) {
sumaFila += matriz[i][j];
}
cout << "Suma fila " << i << ": " << sumaFila << endl;
}
Suma por columna
for (int j = 0; j < COLS; j++) {
int sumaCol = 0;
for (int i = 0; i < FILAS; i++) {
sumaCol += matriz[i][j];
}
cout << "Suma col " << j << ": " << sumaCol << endl;
}
🔁 6. Transpuesta

La transpuesta intercambia filas por columnas: B[i][j] = A[j][i].
int A[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
int B[4][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
B[j][i] = A[i][j]; // índices invertidos
}
}
// B es de 4x3 ahora
Verificación: la fila 0 de A (1 2 3 4) se convierte en la columna 0 de B.
🔍 7. Búsqueda en matriz
Problema: encontrar un valor y reportar su posición.
Figura: Acceso a un elemento específico
int buscar(int matriz[][MAX_COLS], int filas, int cols, int objetivo) {
for (int i = 0; i < filas; i++) {
for (int j = 0; j < cols; j++) {
if (matriz[i][j] == objetivo) {
cout << "Encontrado en [" << i << "][" << j << "]" << endl;
return 1; // encontrado
}
}
}
return 0; // no encontrado
}
Nota: en la firma, la segunda dimensión debe tener tamaño. El compilador la necesita para calcular el offset.
🏆 8. Ejemplo aplicado: calificaciones
Figura: Matriz de calificaciones por alumno y materia
const int ALUMNOS = 4;
const int MATERIAS = 3;
// cal[alumno][materia]
float cal[ALUMNOS][MATERIAS] = {
{8.5, 9.0, 7.5}, // Alumno 0
{6.0, 7.5, 8.0}, // Alumno 1
{9.5, 8.5, 9.0}, // Alumno 2
{7.0, 8.0, 6.5} // Alumno 3
};
// Promedio por alumno
for (int i = 0; i < ALUMNOS; i++) {
float suma = 0;
for (int j = 0; j < MATERIAS; j++) suma += cal[i][j];
cout << "Alumno " << i << " promedio: " << suma/MATERIAS << endl;
}
// Promedio por materia
for (int j = 0; j < MATERIAS; j++) {
float suma = 0;
for (int i = 0; i < ALUMNOS; i++) suma += cal[i][j];
cout << "Materia " << j << " promedio: " << suma/ALUMNOS << endl;
}
🔲 9. Caso especial: matriz identidad
Figura: Matriz identidad 4x4
La matriz identidad tiene 1 en la diagonal y 0 en el resto. Es el "1" de la multiplicación de matrices: A × I = A.
const int N = 4;
int I[N][N] = {};
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
I[i][j] = (i == j) ? 1 : 0;
}
}
Salida:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
🧪 12. LAB 3.4 — Sistema de Calificaciones con Matriz (4 h)
Descripción
Crea un programa que gestione las calificaciones de 5 alumnos en 4 materias:
- Captura la matriz de calificaciones (valida que estén entre 0 y 10).
- Calcula e imprime:
- Promedio por alumno (con su estado: aprobado ≥ 6, reprobado < 6).
- Promedio por materia.
- Promedio general del grupo.
- Encuentra al alumno con el mejor promedio y al de peor promedio.
- Genera la transpuesta de la matriz y muéstrala (materias como filas, alumnos como columnas).
- Búsqueda: pide una calificación al usuario y muestra en qué posiciones aparece.
Rúbrica de evaluación
Bonus XP
- +30 XP si usas struct Alumno { string nombre; float calificaciones[4]; } para que cada alumno tenga nombre.
- +20 XP si la búsqueda muestra el nombre del alumno, no solo el índice.
- +20 XP si generas un histograma en consola del rendimiento del grupo (cuántos sacaron 0-5, 6-7, 8-9, 10).
🔚 14. Cierre — Cuaderno del programador
- Dibuja la matriz 4×5 del LAB. Escribe la fórmula para la posición lineal de cada elemento (i, j).
- Reflexiona: ¿por qué el IPN (y la mayoría de planes de estudio) enseña primero arreglos 1D y luego 2D? ¿Qué analogía de la vida real sustenta esta progresión?
- Anota una pregunta que aún tengas sobre matrices. Compártela con tu grupo o con la IA — pero primero formula tu propia hipótesis.
🏅 Insignia y XP del tema
🔗 ¿Qué sigue?
Tema 3.5 — Búsqueda: Secuencial vs Binaria. Dos algoritmos para el mismo problema (encontrar un elemento): uno vale para todo, el otro es ridículamente más rápido pero requiere datos ordenados. Aquí el Big O se vuelve tangible: verás la diferencia en tiempo real.
Antes de avanzar:
- [ ] LAB 3.4 entregado y funcionando
- [ ] Quest mixto respondido en el cuaderno
- [ ] Reflexión escrita
*"Una matriz no es una tabla. Es memoria lineal que tu cerebro lee en 2D. Entender eso es entender la computación."*
⚠️ Errores típicos — ⚠️ 11. Errores típicos del razonamiento
Error 1: Confundir [i][j] con [j][i]
cout << matriz[2][1] << endl; // fila 2, columna 1
cout << matriz[1][2] << endl; // fila 1, columna 2
// Son elementos DIFERENTES
Aclaración: si matriz[2][1] = 8, entonces matriz[1][2] puede ser cualquier otra cosa.
Error 2: Olvidar el tamaño de la segunda dimensión en funciones
void imprimir(int m[][]) { ... } // ERROR de compilación
void imprimir(int m[][10]) { ... } // BIEN
El compilador necesita saber el ancho de columna para calcular la posición en memoria.
Error 3: Índices fuera de rango
int m[3][4];
cout << m[3][0] << endl; // fila 3 NO EXISTE (válidas: 0, 1, 2)
cout << m[0][4] << endl; // columna 4 NO EXISTE (válidas: 0, 1, 2, 3)
Compila y ejecuta, pero lee/escribe basura o crashea. Aprende a contar desde 0.
Error 4: Recorrer con <= en vez de <
for (int i = 0; i <= 3; i++) { ... } // i vale 0, 1, 2, 3 → fuera de rango en [3][?]
Siempre `<`, nunca <=, a menos que sepas exactamente por qué.
Error 5: Asumir que toda matriz es cuadrada
int A[3][3];
int B[3][3];
int C[3][4] = A; // ERROR: no se puede asignar matrices en C++
No existe asignación directa de matrices en C++. Debes copiar elemento por elemento con un loop.
🤖 IA como copiloto — 🤖 10. AI Mission — "Genera la operación, no el LAB"
Objetivo: usar la IA para operaciones mecánicas, no para la lógica central.
Escenario: tienes una matriz 4×4 y necesitas la traza (suma de la diagonal principal).
Prompt sugerido:
"Dame una función en C++ que calcule la traza de una matriz cuadrada NxN. La función debe recibir la matriz y N, y retornar un `long long`. Incluye un ejemplo de uso con una matriz 4x4."
Lo que NO debes hacer:
- Pedirle que resuelva el LAB 3.4.
- Aceptar el código sin trazarlo: ejecútalo con 3 matrices y verifica.
Lo que SÍ debes hacer:
- Escribir primero la fórmula mental: traza = m[0][0] + m[1][1] + m[2][2] + m[3][3].
- Comparar tu versión con la de la IA: ¿cuál es más clara?
Ritual de 3 min: si la IA te da una versión que no entiendes, pídele que te la explique con una analogía, no que te dé otra versión.
📝 Quest · Cuestionario — 📝 Quest — Reactivos para autoevaluación
Las siguientes preguntas te sirven para autoevaluarte después de leer el tema. Responde en tu cuaderno o mentalmente, y luego revisa las Respuestas modelo (disponibles en libre acceso, sin iniciar sesión).
Sección A · Opción múltiple
Elige la opción correcta (A, B, C o D). Las respuestas están en la sección Respuestas modelo.
- ¿Cómo se declara una matriz 3x4 en C++?
- int m[3,4];
- int m[3][4];
- matrix m(3,4);
- int m(3)(4);
- ¿Cómo acceder al elemento fila 2 columna 3?
- m(2,3)
- m[1][2]
- m[2][3]
- m{2}{3}
- ¿Cómo se recorre una matriz 2D?
- Un for
- Dos for anidados (filas, columnas)
- Un while
- Un switch
- ¿Qué es una matriz triangular?
- Cuadrada
- Solo tiene valores en o por encima/debajo de la diagonal
- 1x1
- Vacía
- Para una matriz de 3x3, ¿cuántos elementos tiene?
- 6
- 9
- 3
- 12
- ¿Cómo se inicializa una matriz?
- int m[2][3] = {{1,2,3},{4,5,6}};
- int m[2,3] = 1,2,3,4,5,6;
- m = [[1,2,3],[4,5,6]]
- Solo en tiempo de ejecución
- ¿Qué representa la diagonal principal de una matriz?
- m[0][0], m[0][1]...
- m[0][0], m[1][1], m[2][2]...
- Solo m[0][0]
- La última fila
- ¿Cómo sumar dos matrices?
- m1 + m2
- Bucles anidados: resultado[i][j] = m1[i][j] + m2[i][j]
- Solo en una función
- No se puede
- ¿Qué es una matriz identidad?
- Todos 0
- 1s en la diagonal, 0s en el resto
- Todos 1s
- Aleatoria
- ¿Cómo se pasa una matriz a una función?
- Como valor
- Con declaración del tamaño: void f(int m[][MAX])
- No se puede
- Solo puntero
Sección B · Preguntas abiertas
Desarrolla tu respuesta en al menos 3 líneas. Compara con la respuesta modelo después de escribir.
- Diseña un algoritmo que encuentre el número más grande de una matriz 3x3 y su posición.→ Escribe tu respuesta aquí (en tu cuaderno o mentalmente)…
- ¿Cómo sumarías dos matrices? Escribe el pseudocódigo.→ Escribe tu respuesta aquí (en tu cuaderno o mentalmente)…
- Explica la diferencia entre una matriz y un vector de vectores. ¿Cuándo usar cada uno?→ Escribe tu respuesta aquí (en tu cuaderno o mentalmente)…
🟢 Cuando termines, revisa las Respuestas modelo y compáralas con las tuyas. La mejor forma de aprender es discutir cada respuesta contigo mismo o con un compañero.