Actualizado el
Código de Examen C Fundamentos de programación Nivel examen Código probado
Examen de matrices en C resuelto: sumas de filas y columnas, traza, antidiagonal, simetría y traspuesta, con pistas y traza paso a paso.

Una cooperativa de regadío divide cada parcela en una cuadrícula de N×N sectores. En cada sector hay un sensor que registra la variación diaria de humedad como un número entero: positivo si el sector ha ganado humedad y negativo si la ha perdido. El técnico necesita un informe que resuma la cuadrícula por filas, por columnas y por sus dos diagonales. También quiere saber si la distribución es simétrica respecto a la diagonal principal y ver la cuadrícula traspuesta, porque el plano del sistema de riego está dibujado con los ejes intercambiados.
Entrada. La entrada estándar contiene primero un entero N y a continuación N·N enteros dados por filas: los N primeros forman la fila 0, los N siguientes la fila 1, y así sucesivamente. Los números pueden estar separados por espacios o por saltos de línea, en cualquier combinación. Cada valor de la cuadrícula está entre -1000 y 1000, y el orden máximo admitido es 10.
Errores. Si no se puede leer N (por ejemplo, porque la entrada está vacía) o si N no está entre 1 y 10, el programa escribe la línea N invalido y termina sin leer nada más. Si N es válido pero la entrada se acaba antes de completar los N·N valores, escribe la línea Datos incompletos y termina. En ninguno de los dos casos se escribe nada más.
Salida. Si todo es correcto, la salida tiene estas líneas en este orden. Primero, Filas: seguido de las N sumas de fila. Después, Columnas: seguido de las N sumas de columna. A continuación, Traza: T, donde T es la suma de los elementos m[i][i], y Antidiagonal: A, donde A es la suma de los elementos m[i][N-1-i]. Luego, Simetrica: SI o Simetrica: NO. Por último, la línea Traspuesta: y, debajo, N líneas con las filas de la matriz traspuesta.
Formato exacto. En las líneas Filas: y Columnas: cada valor va precedido de exactamente un espacio, también el primero, que así queda separado de los dos puntos. En las filas de la traspuesta los valores van separados por un único espacio, sin espacio al principio ni al final. Todas las líneas terminan en salto de línea, y las palabras se escriben sin tilde.
Requisitos. Organiza el programa en funciones sin variables globales: una para leer la matriz, otra para la suma de una fila, otra para la de una columna, otra para la traza, otra para la antidiagonal, otra que construya la traspuesta en una segunda matriz y otra que decida si la matriz es simétrica. El caso de ejemplo que acompaña a este enunciado es una cuadrícula de orden 3 no simétrica. Calcula a mano su informe antes de programar y compáralo con la salida que se muestra junto a él.
Entrada de ejemplo
3
5 -2 7
0 4 1
3 6 -1Salida esperada
Filas: 10 5 8
Columnas: 8 8 7
Traza: 8
Antidiagonal: 14
Simetrica: NO
Traspuesta:
5 0 3
-2 4 6
7 1 -1- Lectura de N y de la matriz comprobando el valor de retorno de scanf, con los dos mensajes de error tal como se piden
- 0,5
- Sumas de filas y de columnas correctas, cada una en su función y con el acumulador reiniciado
- 0,75
- Traza y antidiagonal con un único bucle y con los índices correctos
- 0,5
- Traspuesta en una segunda matriz y comprobación de simetría que termina en la primera diferencia
- 0,5
- Formato de salida exacto: espacios, orden de las líneas y saltos de línea
- 0,25
Pistas
Pista 1 · ¿Qué relación cumplen los índices de cada diagonal?
En la diagonal principal la fila y la columna coinciden (i == j). En la antidiagonal suman N-1, así que la columna es N-1-i. Por eso basta un único bucle en i para cada diagonal. Recorrer las N² celdas con dos bucles anidados y un if funciona, pero hace N veces más trabajo y en un examen se penaliza como solución torpe.
Pista 2 · ¿En qué se diferencia recorrer una fila de recorrer una columna?
Para sumar la fila i se deja i fija y se mueve j. Para sumar la columna j se deja j fija y se mueve i. La traspuesta usa el mismo intercambio de papeles: el elemento m[i][j] pasa a t[j][i]. Para la simetría solo hace falta comparar m[i][j] con m[j][i] en las celdas con j > i, y en cuanto aparece una diferencia ya se sabe la respuesta.
Pista 3 · ¿Cómo se obtiene el formato exacto sin casos especiales?
En las líneas de sumas, escribe primero la etiqueta ("Filas:") y después cada valor con el formato " %d". Todos los valores llevan un espacio delante, y el del primero es justo el que debe ir tras los dos puntos. En las filas de la traspuesta la regla es otra: el espacio solo va entre valores, así que se escribe antes de cada valor cuyo índice sea mayor que cero. Para los errores, comprueba lo que devuelve scanf: distingue la lectura de N de la lectura de la matriz.
Solución
Solución explicada
La solución separa cada cálculo en una función pequeña que recibe la matriz y su orden real n. La matriz se declara con el tamaño máximo MAXN, pero todos los bucles se detienen en n. Así nunca se tocan celdas sin inicializar y el programa sirve para cualquier orden entre 1 y 10.
main se limita a validar, llamar a las funciones e imprimir. Este reparto es el que se suele valorar en un parcial: cada función se puede razonar y probar por separado, y los errores de formato quedan concentrados en un único sitio.
#include <stdio.h>
#define MAXN 10
/* Lee n*n enteros por filas. Devuelve 1 si los ha leido todos
y 0 si la entrada se acaba antes. */
static int leerMatriz(int m[MAXN][MAXN], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (scanf("%d", &m[i][j]) != 1) {
return 0;
}
}
}
return 1;
}
static int sumaFila(int m[MAXN][MAXN], int n, int i)
{
int suma = 0;
for (int j = 0; j < n; j++) {
suma += m[i][j];
}
return suma;
}
static int sumaColumna(int m[MAXN][MAXN], int n, int j)
{
int suma = 0;
for (int i = 0; i < n; i++) {
suma += m[i][j];
}
return suma;
}
static int traza(int m[MAXN][MAXN], int n)
{
int suma = 0;
for (int i = 0; i < n; i++) {
suma += m[i][i];
}
return suma;
}
static int antidiagonal(int m[MAXN][MAXN], int n)
{
int suma = 0;
for (int i = 0; i < n; i++) {
suma += m[i][n - 1 - i];
}
return suma;
}
static void trasponer(int m[MAXN][MAXN], int n, int t[MAXN][MAXN])
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
t[j][i] = m[i][j];
}
}
}
static int esSimetrica(int m[MAXN][MAXN], int n)
{
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (m[i][j] != m[j][i]) {
return 0;
}
}
}
return 1;
}
int main(void)
{
int m[MAXN][MAXN];
int t[MAXN][MAXN];
int n;
if (scanf("%d", &n) != 1 || n < 1 || n > MAXN) {
printf("N invalido\n");
return 0;
}
if (!leerMatriz(m, n)) {
printf("Datos incompletos\n");
return 0;
}
printf("Filas:");
for (int i = 0; i < n; i++) {
printf(" %d", sumaFila(m, n, i));
}
printf("\n");
printf("Columnas:");
for (int j = 0; j < n; j++) {
printf(" %d", sumaColumna(m, n, j));
}
printf("\n");
printf("Traza: %d\n", traza(m, n));
printf("Antidiagonal: %d\n", antidiagonal(m, n));
printf("Simetrica: %s\n", esSimetrica(m, n) ? "SI" : "NO");
trasponer(m, n, t);
printf("Traspuesta:\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j > 0) {
printf(" ");
}
printf("%d", t[i][j]);
}
printf("\n");
}
return 0;
}Validación. La primera condición de main es scanf("%d", &n) != 1 || n < 1 || n > MAXN. Si la entrada está vacía, scanf devuelve EOF, que es distinto de 1. Gracias a la evaluación en cortocircuito, n no llega a consultarse sin haber recibido valor. Por eso los casos «Entrada vacia» y «N fuera de rango» (con N = 11) imprimen N invalido y nada más. Si N es válido, se llama a leerMatriz, que devuelve 0 en cuanto un scanf falla. Es lo que ocurre en «Matriz incompleta», donde se anuncia N = 2 pero solo llegan tres valores, y el programa responde Datos incompletos.
Paso de la matriz a las funciones. Todas las funciones reciben int m[MAXN][MAXN]. En realidad, C no copia la matriz: pasa un puntero a su primera fila, de tipo int (*)[MAXN]. La segunda dimensión es obligatoria porque el compilador calcula la dirección de m[i][j] saltando i*MAXN + j enteros desde el inicio. Por la misma razón, cuando trasponer escribe en t, el cambio se ve en main. Si quieres repasar esta diferencia, consulta los ejercicios de paso por valor y por referencia.
Sumas de filas y columnas. sumaFila fija i y recorre j. sumaColumna hace lo contrario. En ambas, el acumulador suma es una variable local que vale 0 en cada llamada, de modo que es imposible arrastrar la suma de una fila a la siguiente. En el caso «Ejemplo 3x3» la matriz tiene las filas 5 -2 7, 0 4 1 y 3 6 -1. Las sumas de fila son 10, 5 y 8, y las de columna 8, 8 y 7. Son exactamente las dos primeras líneas de la salida esperada.
Diagonales. traza suma m[i][i] y antidiagonal suma m[i][n - 1 - i], cada una con un único bucle. En el ejemplo, la traza es 5 + 4 + (-1) = 8 y la antidiagonal es 7 + 4 + 3 = 14. La traza paso a paso que acompaña a la solución muestra 24 pasos sobre esta matriz: nueve para las filas, nueve para las columnas, tres para la diagonal principal y tres para la antidiagonal. En cada paso se resalta la celda visitada y se ve cómo crece suma.
Simetría. esSimetrica recorre solo el triángulo superior (j empieza en i + 1) y compara cada celda con su reflejada. La diagonal no hace falta mirarla, porque siempre coincide consigo misma. En el ejemplo, la primera comparación ya encuentra que m[0][1] vale -2 y m[1][0] vale 0, así que la función devuelve 0 y la salida dice NO. En el caso «Simetrica 4x4» las seis parejas coinciden, la respuesta es SI y, como debe ser, la traspuesta impresa es idéntica a la matriz de entrada.
Traspuesta y formato. trasponer asigna t[j][i] = m[i][j], de modo que la fila i de t es la columna i de m. En el ejemplo, la primera fila de la traspuesta es 5 0 3. Las líneas de sumas usan " %d" y las filas de la traspuesta escriben el espacio solo si j > 0, que son justo las dos reglas del enunciado. El caso «Un solo elemento» comprueba el borde N = 1: el único valor, -7, es a la vez fila, columna, traza y antidiagonal, y la matriz es trivialmente simétrica.
Traza paso a paso · generada ejecutando el código
| Paso | fase | i | j | valor | suma | Celda |
|---|---|---|---|---|---|---|
| 1 | fila | 0 | 0 | 5 | 5 | (0,0) |
| 2 | fila | 0 | 1 | -2 | 3 | (0,1) |
| 3 | fila | 0 | 2 | 7 | 10 | (0,2) |
| 4 | fila | 1 | 0 | 0 | 0 | (1,0) |
| 5 | fila | 1 | 1 | 4 | 4 | (1,1) |
| 6 | fila | 1 | 2 | 1 | 5 | (1,2) |
| 7 | fila | 2 | 0 | 3 | 3 | (2,0) |
| 8 | fila | 2 | 1 | 6 | 9 | (2,1) |
| 9 | fila | 2 | 2 | -1 | 8 | (2,2) |
| 10 | columna | 0 | 0 | 5 | 5 | (0,0) |
| 11 | columna | 1 | 0 | 0 | 5 | (1,0) |
| 12 | columna | 2 | 0 | 3 | 8 | (2,0) |
| 13 | columna | 0 | 1 | -2 | -2 | (0,1) |
| 14 | columna | 1 | 1 | 4 | 2 | (1,1) |
| 15 | columna | 2 | 1 | 6 | 8 | (2,1) |
| 16 | columna | 0 | 2 | 7 | 7 | (0,2) |
| 17 | columna | 1 | 2 | 1 | 8 | (1,2) |
| 18 | columna | 2 | 2 | -1 | 7 | (2,2) |
| 19 | traza | 0 | 0 | 5 | 5 | (0,0) |
| 20 | traza | 1 | 1 | 4 | 9 | (1,1) |
| 21 | traza | 2 | 2 | -1 | 8 | (2,2) |
| 22 | antidiagonal | 0 | 2 | 7 | 7 | (0,2) |
| 23 | antidiagonal | 1 | 1 | 4 | 11 | (1,1) |
| 24 | antidiagonal | 2 | 0 | 3 | 14 | (2,0) |
Casos de prueba
| Caso | Entrada | Salida esperada | Salida real | Resultado |
|---|---|---|---|---|
| Ejemplo 3x3 | 3
5 -2 7
0 4 1
3 6 -1 | Filas: 10 5 8
Columnas: 8 8 7
Traza: 8
Antidiagonal: 14
Simetrica: NO
Traspuesta:
5 0 3
-2 4 6
7 1 -1 | Filas: 10 5 8
Columnas: 8 8 7
Traza: 8
Antidiagonal: 14
Simetrica: NO
Traspuesta:
5 0 3
-2 4 6
7 1 -1 | OK |
| Simetrica 4x4 | 4
1 2 3 4
2 0 -5 6
3 -5 7 8
4 6 8 -2 | Filas: 10 3 13 16
Columnas: 10 3 13 16
Traza: 6
Antidiagonal: -2
Simetrica: SI
Traspuesta:
1 2 3 4
2 0 -5 6
3 -5 7 8
4 6 8 -2 | Filas: 10 3 13 16
Columnas: 10 3 13 16
Traza: 6
Antidiagonal: -2
Simetrica: SI
Traspuesta:
1 2 3 4
2 0 -5 6
3 -5 7 8
4 6 8 -2 | OK |
| Un solo elemento | 1
-7 | Filas: -7
Columnas: -7
Traza: -7
Antidiagonal: -7
Simetrica: SI
Traspuesta:
-7 | Filas: -7
Columnas: -7
Traza: -7
Antidiagonal: -7
Simetrica: SI
Traspuesta:
-7 | OK |
| N fuera de rango | 11 | N invalido | N invalido | OK |
| Entrada vacia | (vacía) | N invalido | N invalido | OK |
| Matriz incompleta | 2
1 2 3 | Datos incompletos | Datos incompletos | OK |
Salidas reales: código compilado con gcc 14.4.0 (C17) y ejecutado en un contenedor aislado el 5 de octubre de 2026.
Complejidad
Tiempo. La lectura recorre las N² celdas. Las N llamadas a sumaFila cuestan N operaciones cada una, en total N², y lo mismo ocurre con las columnas. La traza y la antidiagonal son lineales, O(N). trasponer es O(N²), y esSimetrica hace como mucho N(N-1)/2 comparaciones, que también es O(N²). El coste total es O(N²), es decir, lineal en el tamaño de la entrada: no se puede bajar, porque hay que leer cada dato al menos una vez.
Memoria. El programa usa dos matrices fijas de 10×10 enteros, 200 int, unos 800 bytes en la pila, más unas pocas variables escalares. Como el orden máximo está acotado, esa memoria es constante. Si se generalizara a matrices dinámicas, sería O(N²). La matriz t duplica el espacio: la primera variante muestra cómo prescindir de ella trasponiendo en el sitio.
Errores típicos
- Escribir la antidiagonal como
m[i][n - i]. Parai = 0se accede a la columnan, que no existe: en C no hay error, se lee basura o la celda de otra fila. - Usar
MAXNen lugar dencomo límite de los bucles. Las sumas incluyen celdas sin inicializar y el resultado cambia de una ejecución a otra. - Declarar un único acumulador fuera del bucle de filas y no reiniciarlo, de forma que cada fila arrastra la suma de las anteriores. Con una variable local dentro de
sumaFilaeste error es imposible. - En la simetría, devolver 1 dentro del bucle en cuanto una pareja coincide. Solo se puede afirmar que la matriz es simétrica después de haber revisado todas las parejas sin encontrar diferencias.
- Declarar el parámetro como
int m[][]. No compila, porque el compilador necesita la segunda dimensión para calcular la posición dem[i][j]. - No comprobar el valor que devuelve
scanf. Con una entrada vacía o incompleta, el programa trabaja con valores indeterminados en lugar de escribirN invalidooDatos incompletos.
Variantes
Trasponer en el sitio, sin matriz auxiliar
Se intercambia m[i][j] con m[j][i], pero solo para j > i. Si el bucle interno empezara en 0, cada pareja se intercambiaría dos veces y la matriz quedaría como estaba. Como la matriz original deja de existir, todas las sumas y la simetría deben calcularse antes de trasponer. La memoria extra pasa a ser una sola variable auxiliar. El programa siguiente produce exactamente la misma salida en todas las pruebas.
#include <stdio.h>
#define MAXN 10
static int leerMatriz(int m[MAXN][MAXN], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (scanf("%d", &m[i][j]) != 1) {
return 0;
}
}
}
return 1;
}
static int sumaFila(int m[MAXN][MAXN], int n, int i)
{
int suma = 0;
for (int j = 0; j < n; j++) {
suma += m[i][j];
}
return suma;
}
static int sumaColumna(int m[MAXN][MAXN], int n, int j)
{
int suma = 0;
for (int i = 0; i < n; i++) {
suma += m[i][j];
}
return suma;
}
static int traza(int m[MAXN][MAXN], int n)
{
int suma = 0;
for (int i = 0; i < n; i++) {
suma += m[i][i];
}
return suma;
}
static int antidiagonal(int m[MAXN][MAXN], int n)
{
int suma = 0;
for (int i = 0; i < n; i++) {
suma += m[i][n - 1 - i];
}
return suma;
}
static int esSimetrica(int m[MAXN][MAXN], int n)
{
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (m[i][j] != m[j][i]) {
return 0;
}
}
}
return 1;
}
static void trasponerEnSitio(int m[MAXN][MAXN], int n)
{
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int aux = m[i][j];
m[i][j] = m[j][i];
m[j][i] = aux;
}
}
}
int main(void)
{
int m[MAXN][MAXN];
int n;
if (scanf("%d", &n) != 1 || n < 1 || n > MAXN) {
printf("N invalido\n");
return 0;
}
if (!leerMatriz(m, n)) {
printf("Datos incompletos\n");
return 0;
}
printf("Filas:");
for (int i = 0; i < n; i++) {
printf(" %d", sumaFila(m, n, i));
}
printf("\n");
printf("Columnas:");
for (int j = 0; j < n; j++) {
printf(" %d", sumaColumna(m, n, j));
}
printf("\n");
printf("Traza: %d\n", traza(m, n));
printf("Antidiagonal: %d\n", antidiagonal(m, n));
printf("Simetrica: %s\n", esSimetrica(m, n) ? "SI" : "NO");
trasponerEnSitio(m, n);
printf("Traspuesta:\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j > 0) {
printf(" ");
}
printf("%d", m[i][j]);
}
printf("\n");
}
return 0;
}Indicar qué fila tiene la mayor suma
Se reutiliza sumaFila. Se toma como referencia la fila 0, con mejor = sumaFila(m, n, 0) y fila = 0, y se recorren las filas 1 a n-1, actualizando ambas variables solo si la nueva suma es estrictamente mayor. Así, en caso de empate gana la primera fila. El error clásico es inicializar mejor a 0: con valores negativos, como los que admite este enunciado, ninguna fila superaría ese valor y la respuesta sería incorrecta. La versión por columnas es idéntica usando sumaColumna.
Historial de cambios
- Reescrito con la plantilla de Código de Examen: enunciado de examen, pistas, solución explicada, casos de prueba y código compilado y ejecutado; versión en inglés enlazada.
- Publicación original.
Elaborado con apoyo de IA y revisado por la redacción


