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 */
Sigue aprendiendoTodos los artículos de C¿Te ha servido este artículo? Así puedes apoyar SergioLearns →

Un comentario