Punteros en C — ejercicios para dominar la memoria
Los punteros en C ejercicios con solución cierran este bloque. Ya viste la teoría y practicaste con programas reales. Ahora toca resolver por tu cuenta con gedit y gcc en Fedora. Cuatro ejercicios en tres niveles con especial atención al error más peligroso de todos, usar un puntero sin inicializar. Revisa tus códigos con pythontutor.com.
Tabla de Contenidos
Punteros en C ejercicios — Nivel Básico
Ejercicio 1 — Copiar un vector en otro usando punteros
Escribe un programa que tenga dos vectores de 6 enteros, uno con valores y otro vacío. Copia el contenido del primero al segundo usando solo punteros, sin índices. Luego verifica que la copia es correcta comparando elemento a elemento.
La salida debe ser:
Vector original: 10 25 8 42 17 33 Copiando con punteros... Vector copia: 10 25 8 42 17 33 Verificación elemento a elemento: [0] 10 == 10 ✓ [1] 25 == 25 ✓ [2] 8 == 8 ✓ [3] 42 == 42 ✓ [4] 17 == 17 ✓ [5] 33 == 33 ✓ Copia correcta: 6/6 elementos iguales
💡 Pista — el error del puntero sin inicializar:
/* MAL — puntero sin inicializar */
int *origen, *destino;
*destino = *origen; /* PELIGRO — ambos apuntan a basura */
/* BIEN — siempre inicializa antes de usar */
int vec_origen[6] = {10, 25, 8, 42, 17, 33};
int vec_destino[6];
int *origen = vec_origen;
int *destino = vec_destino;
Para la copia usa un bucle for con dos punteros avanzando a la vez:
for (origen = vec_origen, destino = vec_destino;
origen < vec_origen + n;
origen++, destino++) {
*destino = *origen;
}
Ejercicio 2 — Contar elementos que cumplen una condición
Escribe un programa que pida 8 números enteros al usuario, los guarde en un vector y luego cuente usando punteros cuántos son: positivos, negativos, pares, impares y mayores que la media.
La salida debe ser:
Introduce 8 números: Número 1: 15 Número 2: -3 Número 3: 8 Número 4: -12 Número 5: 0 Número 6: 7 Número 7: -5 Número 8: 22 Vector: 15 -3 8 -12 0 7 -5 22 --- Estadísticas --- Positivos: 4 (15, 8, 7, 22) Negativos: 3 (-3, -12, -5) Ceros: 1 Pares: 4 (8, -12, 0, 22) Impares: 4 (15, -3, 7, -5) Media: 4.00 Mayores que media: 3 (15, 8, 22)
💡 Pistas:
- Usa un puntero para recorrer el vector en cada conteo
- Para la media calcula primero la suma con un recorrido y luego divides
- El error del puntero sin inicializar aparece si declaras el puntero fuera del bucle y lo usas sin apuntarlo al vector primero — siempre
int *ptr = vecantes del bucle - Un número es par si
*ptr % 2 == 0— funciona igual con valores negativos
Punteros en C ejercicios — Nivel Intermedio
Ejercicio 3 — Reemplazar valores en un vector a través de punteros
Escribe un programa con un vector de 10 enteros y tres funciones que lo modifiquen usando punteros:
reemplazar_negativos(int *vec, int n, int valor)— sustituye todos los negativos porvalormultiplicar_pares(int *vec, int n, int factor)— multiplica todos los pares porfactornormalizar(int *vec, int n)— resta el mínimo a todos los elementos para que el mínimo sea 0
La salida debe ser:
Vector inicial: 15 -3 8 -12 6 7 -5 22 4 -8 Reemplazando negativos por 0: Vector: 15 0 8 0 6 7 0 22 4 0 Multiplicando pares por 2: Vector: 15 0 16 0 12 7 0 44 8 0 Normalizando (mínimo → 0): Mínimo actual: 0 Vector: 15 0 16 0 12 7 0 44 8 0 (ya normalizado)
💡 Pistas:
- Cada función recibe
int *vec— el vector ya es un puntero, no necesitas&al llamarla - Dentro de cada función usa
int *ptr = vecpara inicializar el puntero antes del bucle — nunca lo uses sin inicializar - Para
normalizarnecesitas dos recorridos — primero encontrar el mínimo, luego restar a todos - Las modificaciones son permanentes — al modificar
*ptrestás modificando el vector original directamente
Punteros en C ejercicios — Desafío Final
Ejercicio 4 — Biblioteca de operaciones con vectores
Escribe un programa completo que implemente una pequeña biblioteca de operaciones sobre vectores usando exclusivamente punteros. Las operaciones son:
- Suma de dos vectores elemento a elemento → resultado en un tercero
- Producto escalar de dos vectores (suma de productos elemento a elemento)
- Encontrar si dos vectores son iguales
- Rotar el vector un puesto a la derecha (el último pasa al primero)
=== BIBLIOTECA DE VECTORES === Vector A: 1 2 3 4 5 Vector B: 5 4 3 2 1 Suma A+B: 6 6 6 6 6 Producto escalar: 35 ¿Son iguales?: No Rotando A un puesto a la derecha: Vector A rotado: 5 1 2 3 4 Rotando otra vez: Vector A rotado: 4 5 1 2 3
💡 Pistas:
- Para la suma usa tres punteros a la vez —
pa,pbypcavanzando simultáneamente - Para el producto escalar acumula
suma += (*pa) * (*pb)en cada iteración - Para la rotación guarda el último elemento, desplaza todos un puesto con un puntero que va de atrás hacia adelante, y pon el guardado en la primera posición
- El error del puntero sin inicializar es especialmente peligroso aquí si declaras los punteros de resultado sin apuntarlos al vector de resultado primero
Soluciones Comentadas
Solución Ejercicio 1:
#include <stdio.h>
int main() {
int vec_origen[6] = {10, 25, 8, 42, 17, 33};
int vec_destino[6];
int n = 6;
int *origen, *destino;
int i, iguales = 0;
/* Mostrar original */
printf("Vector original: ");
for (origen = vec_origen; origen < vec_origen + n; origen++) {
printf("%d ", *origen);
}
printf("\n\nCopiando con punteros...\n\n");
/* Copia con dos punteros simultáneos */
for (origen = vec_origen, destino = vec_destino;
origen < vec_origen + n;
origen++, destino++) {
*destino = *origen;
}
/* Mostrar copia */
printf("Vector copia: ");
for (destino = vec_destino; destino < vec_destino + n; destino++) {
printf("%d ", *destino);
}
printf("\n\n");
/* Verificación */
printf("Verificación elemento a elemento:\n");
for (i = 0; i < n; i++) {
if (vec_origen[i] == vec_destino[i]) {
printf("[%d] %d == %d ✓\n", i, vec_origen[i], vec_destino[i]);
iguales++;
} else {
printf("[%d] %d != %d ✗\n", i, vec_origen[i], vec_destino[i]);
}
}
printf("Copia correcta: %d/%d elementos iguales\n", iguales, n);
return 0;
}
Solución Ejercicio 2:
#include <stdio.h>
int main() {
int vec[8];
int n = 8;
int *ptr;
int i;
int positivos = 0, negativos = 0, ceros = 0;
int pares = 0, impares = 0, mayores_media = 0;
int suma = 0;
float media;
/* Lectura con validación */
printf("Introduce 8 números:\n");
for (i = 0; i < n; i++) {
printf("Número %d: ", i + 1);
scanf("%d", &vec[i]);
}
/* Mostrar vector */
printf("\nVector: ");
for (ptr = vec; ptr < vec + n; ptr++) {
printf("%d ", *ptr);
}
printf("\n\n--- Estadísticas ---\n");
/* Calcular suma para la media */
for (ptr = vec; ptr < vec + n; ptr++) {
suma += *ptr;
}
media = (float)suma / n;
/* Contar con punteros */
printf("Positivos: ");
for (ptr = vec; ptr < vec + n; ptr++) {
if (*ptr > 0) { positivos++; printf("%d ", *ptr); }
}
printf("(%d)\n", positivos);
printf("Negativos: ");
for (ptr = vec; ptr < vec + n; ptr++) {
if (*ptr < 0) { negativos++; printf("%d ", *ptr); }
}
printf("(%d)\n", negativos);
for (ptr = vec; ptr < vec + n; ptr++) {
if (*ptr == 0) ceros++;
}
printf("Ceros: %d\n", ceros);
printf("Pares: ");
for (ptr = vec; ptr < vec + n; ptr++) {
if (*ptr % 2 == 0) { pares++; printf("%d ", *ptr); }
}
printf("(%d)\n", pares);
printf("Impares: ");
for (ptr = vec; ptr < vec + n; ptr++) {
if (*ptr % 2 != 0) { impares++; printf("%d ", *ptr); }
}
printf("(%d)\n", impares);
printf("Media: %.2f\n", media);
printf("Mayores que media: ");
for (ptr = vec; ptr < vec + n; ptr++) {
if (*ptr > media) { mayores_media++; printf("%d ", *ptr); }
}
printf("(%d)\n", mayores_media);
return 0;
}
Solución Ejercicio 3:
#include <stdio.h>
void reemplazar_negativos(int *vec, int n, int valor) {
int *ptr;
for (ptr = vec; ptr < vec + n; ptr++) {
if (*ptr < 0) {
*ptr = valor;
}
}
}
void multiplicar_pares(int *vec, int n, int factor) {
int *ptr;
for (ptr = vec; ptr < vec + n; ptr++) {
if (*ptr % 2 == 0) {
*ptr *= factor;
}
}
}
void normalizar(int *vec, int n) {
int *ptr;
int minimo = *vec;
/* Encontrar mínimo */
for (ptr = vec + 1; ptr < vec + n; ptr++) {
if (*ptr < minimo) minimo = *ptr;
}
printf("Mínimo actual: %d\n", minimo);
/* Restar mínimo a todos */
for (ptr = vec; ptr < vec + n; ptr++) {
*ptr -= minimo;
}
}
void mostrar_vector(int *vec, int n) {
int *ptr;
for (ptr = vec; ptr < vec + n; ptr++) {
printf("%d ", *ptr);
}
printf("\n");
}
int main() {
int vec[10] = {15, -3, 8, -12, 6, 7, -5, 22, 4, -8};
int n = 10;
printf("Vector inicial: ");
mostrar_vector(vec, n);
printf("\nReemplazando negativos por 0:\n");
reemplazar_negativos(vec, n, 0);
printf("Vector: ");
mostrar_vector(vec, n);
printf("\nMultiplicando pares por 2:\n");
multiplicar_pares(vec, n, 2);
printf("Vector: ");
mostrar_vector(vec, n);
printf("\nNormalizando (mínimo → 0):\n");
normalizar(vec, n);
printf("Vector: ");
mostrar_vector(vec, n);
return 0;
}
Solución Ejercicio 4:
#include <stdio.h>
void suma_vectores(int *a, int *b, int *resultado, int n) {
int *pa, *pb, *pr;
for (pa = a, pb = b, pr = resultado;
pa < a + n;
pa++, pb++, pr++) {
*pr = *pa + *pb;
}
}
int producto_escalar(int *a, int *b, int n) {
int *pa, *pb;
int suma = 0;
for (pa = a, pb = b; pa < a + n; pa++, pb++) {
suma += (*pa) * (*pb);
}
return suma;
}
int son_iguales(int *a, int *b, int n) {
int *pa, *pb;
for (pa = a, pb = b; pa < a + n; pa++, pb++) {
if (*pa != *pb) return 0;
}
return 1;
}
void rotar_derecha(int *vec, int n) {
int ultimo = *(vec + n - 1);
int *ptr;
for (ptr = vec + n - 1; ptr > vec; ptr--) {
*ptr = *(ptr - 1);
}
*vec = ultimo;
}
void mostrar_vector(int *vec, int n) {
int *ptr;
for (ptr = vec; ptr < vec + n; ptr++) {
printf("%d ", *ptr);
}
printf("\n");
}
int main() {
int a[5] = {1, 2, 3, 4, 5};
int b[5] = {5, 4, 3, 2, 1};
int resultado[5];
int n = 5;
printf("=== BIBLIOTECA DE VECTORES ===\n\n");
printf("Vector A: "); mostrar_vector(a, n);
printf("Vector B: "); mostrar_vector(b, n);
suma_vectores(a, b, resultado, n);
printf("\nSuma A+B: "); mostrar_vector(resultado, n);
printf("Producto escalar: %d\n", producto_escalar(a, b, n));
printf("¿Son iguales?: %s\n", son_iguales(a, b, n) ? "Sí" : "No");
printf("\nRotando A un puesto a la derecha:\n");
rotar_derecha(a, n);
printf("Vector A rotado: "); mostrar_vector(a, n);
printf("\nRotando otra vez:\n");
rotar_derecha(a, n);
printf("Vector A rotado: "); mostrar_vector(a, n);
return 0;
}
Chuletario — Punteros en C
/* ============================================
CHULETARIO — Punteros en C
Sergio Learns · sergiolearns.com
============================================ */
/* DECLARAR UN PUNTERO */
int *ptr; /* puntero a int */
char *ptr; /* puntero a char */
float *ptr; /* puntero a float */
void *ptr; /* puntero genérico */
/* SIEMPRE INICIALIZA ANTES DE USAR */
int x = 5;
int *ptr = &x; /* apunta a x */
int *ptr = NULL; /* puntero nulo — no apunta a nada */
/* OPERADORES CLAVE */
&variable /* dirección de la variable */
*puntero /* valor en la dirección del puntero */
/* EJEMPLO BÁSICO */
int x = 5;
int *ptr = &x;
printf("%d\n", x); /* → 5 */
printf("%p\n", ptr); /* → dirección de x */
printf("%d\n", *ptr); /* → 5 */
*ptr = 33; /* modifica x */
printf("%d\n", x); /* → 33 */
/* ARITMÉTICA DE PUNTEROS */
ptr + 1 /* siguiente elemento del tipo */
ptr - 1 /* elemento anterior */
ptr++ /* avanza al siguiente */
ptr-- /* retrocede */
ptr2 - ptr1 /* diferencia en elementos (no bytes) */
/* Si ptr es int* y int ocupa 4 bytes: */
/* ptr+1 avanza 4 bytes en memoria */
/* PUNTEROS Y VECTORES */
int vec[5] = {1, 2, 3, 4, 5};
int *ptr = vec; /* ptr apunta al primer elemento */
vec[i] == *(vec+i) /* equivalentes */
ptr[i] == *(ptr+i) /* equivalentes */
vec++ /* ILEGAL — vec es constante */
ptr++ /* LEGAL — ptr es variable */
/* RECORRIDO CON PUNTERO */
int *ptr;
for (ptr = vec; ptr < vec + n; ptr++) {
printf("%d ", *ptr);
}
/* DOS PUNTEROS SIMULTÁNEOS */
int *pa, *pb;
for (pa = a, pb = b; pa < a + n; pa++, pb++) {
*pb = *pa; /* copia a en b */
}
/* PUNTERO A NULL — comprobar siempre */
int *ptr = buscar(vec, n, valor);
if (ptr != NULL) {
printf("%d\n", *ptr); /* seguro */
}
/* nunca: *ptr sin comprobar NULL */
/* FUNCIÓN QUE DEVUELVE PUNTERO */
int* encontrar_max(int *vec, int n) {
int *ptr, *max = vec;
for (ptr = vec+1; ptr < vec+n; ptr++) {
if (*ptr > *max) max = ptr;
}
return max;
}
/* FUNCIÓN QUE MODIFICA VARIABLES EXTERNAS */
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
swap(&x, &y); /* & obligatorio al llamar */
/* POSICIÓN DE UN ELEMENTO */
int *ptr = encontrar_max(vec, n);
int posicion = ptr - vec; /* resta de punteros */
/* ERRORES TÍPICOS */
/* 1. Puntero sin inicializar → comportamiento indefinido */
int *ptr;
*ptr = 5; /* PELIGRO */
/* 2. Acceso fuera de rango */
ptr = vec + n;
*ptr = 5; /* PELIGRO */
/* 3. Olvidar & al llamar funciones */
swap(x, y); /* MAL — pasa valores */
swap(&x, &y); /* BIEN — pasa direcciones */
/* 4. vec++ → ilegal */
vec++; /* error de compilación */
/* 5. Usar NULL sin comprobar */
*ptr = 5; /* si ptr es NULL → crash */
/* 6. %d en vez de %p para direcciones */
printf("%d\n", ptr); /* MAL */
printf("%p\n", ptr); /* BIEN */
Pointers in C — exercises to master memory
Basic Level
Exercise 1 — Copy an array using pointers
Two arrays of 6 integers, one with values, one empty. Copy using only pointers, no index notation. Verify element by element.
💡 Hint — uninitialised pointer mistake:
/* WRONG — uninitialised pointers */ int *src, *dst; *dst = *src; /* DANGER — both point to garbage */ /* RIGHT — always initialise first */ int *src = vec_origin; int *dst = vec_dest;
Use two simultaneous pointers advancing together:
for (src = origin, dst = dest;
src < origin + n;
src++, dst++) {
*dst = *src;
}
Exercise 2 — Count elements meeting a condition
Ask for 8 integers, store in array, count using pointers: positives, negatives, zeros, even, odd and greater than average.
💡 Hints: Always int *ptr = vec before each loop, never use uninitialized. Even check: *ptr % 2 == 0 works for negatives too.
Intermediate Level
Exercise 3 — Replace values through pointers
Three functions modifying a 10-element array: replace_negatives(vec, n, value), multiply_evens(vec, n, factor), normalise(vec, n) (subtract minimum so minimum becomes 0).
💡 Hints: Array already is a pointer — no & needed when calling. Inside each function int *ptr = vec before the loop. Normalise needs two passes — find minimum first, then subtract.
Final Challenge
Exercise 4 — Vector operations library
Four functions using only pointers: vector sum, dot product, equality check, rotate right one position.
💡 Hints: Three simultaneous pointers for sum. Rotate: save last, shift all right with backward pointer, place saved at first position.
(Solutions same as Spanish version above)
Cheat sheet — Pointers in C
/* ============================================
CHEAT SHEET — Pointers in C
Sergio Learns · sergiolearns.com
============================================ */
/* DECLARE */
int *ptr; /* pointer to int */
char *ptr; /* pointer to char */
void *ptr; /* generic pointer */
/* ALWAYS INITIALISE BEFORE USE */
int x = 5;
int *ptr = &x; /* points to x */
int *ptr = NULL; /* null pointer */
/* KEY OPERATORS */
&variable /* address of variable */
*pointer /* value at address */
/* BASIC USE */
int x = 5;
int *ptr = &x;
printf("%d\n", *ptr); /* → 5 */
*ptr = 33; /* modifies x */
/* ARITHMETIC */
ptr + 1 /* next element */
ptr++ /* advance */
ptr2-ptr1 /* difference in elements */
/* ARRAYS AND POINTERS */
int *ptr = vec;
vec[i] == *(vec+i) == ptr[i] == *(ptr+i)
vec++ /* ILLEGAL */
ptr++ /* LEGAL */
/* TRAVERSAL */
for (ptr = vec; ptr < vec + n; ptr++) {
printf("%d ", *ptr);
}
/* TWO SIMULTANEOUS POINTERS */
for (pa = a, pb = b; pa < a+n; pa++, pb++) {
*pb = *pa;
}
/* NULL CHECK — always */
if (ptr != NULL) { printf("%d\n", *ptr); }
/* FUNCTION RETURNING POINTER */
int* find_max(int *vec, int n) {
int *ptr, *max = vec;
for (ptr=vec+1; ptr<vec+n; ptr++)
if (*ptr > *max) max = ptr;
return max;
}
/* POSITION FROM POINTER */
int pos = ptr - vec;
/* MODIFYING EXTERNAL VARIABLES */
void swap(int *a, int *b) {
int t = *a; *a = *b; *b = t;
}
swap(&x, &y); /* & mandatory */
/* COMMON MISTAKES */
/* 1. Uninitialised pointer → undefined behaviour */
/* 2. Out of bounds access → undefined behaviour */
/* 3. Missing & in function call */
/* 4. vec++ → compile error */
/* 5. Using NULL without checking → crash */
/* 6. %d instead of %p for addresses */
