punteros en C ejercicios resueltos chuletario

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.


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 = vec antes 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 por valor
  • multiplicar_pares(int *vec, int n, int factor) — multiplica todos los pares por factor
  • normalizar(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 = vec para inicializar el puntero antes del bucle — nunca lo uses sin inicializar
  • Para normalizar necesitas dos recorridos — primero encontrar el mínimo, luego restar a todos
  • Las modificaciones son permanentes — al modificar *ptr está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, pb y pc avanzando 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 */

Publicaciones Similares

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *