Ejercicio 07 — Funcion invertir(int *arr, int n) que invierte el array in-place con…

Dificultad: rojo · Módulo 07 (Punteros)

Enunciado

Funcion invertir(int *arr, int n) que invierte el array in-place con dos punteros (inicio y fin) avanzando hacia el centro con swap.

Diagrama de flujo

Diagrama de flujo del ejercicio 07

Cómo se resuelve

Este ejercicio junta casi todo el módulo: paso por referencia, relación puntero-array y aritmética de punteros. La idea es invertir el array in-place (sin array auxiliar) con dos punteros que se acercan desde los extremos.

  • int *izq = arr; apunta al primer elemento y int *der = arr + n - 1; al último (n - 1 porque el índice del último es el tamaño menos uno).
  • El bucle while (izq < der) intercambia los extremos con swap(izq, der) y luego acerca ambos: izq++ avanza y der-- retrocede. Cuando se cruzan (izq >= der) el array ya está invertido; el elemento central, si n es impar, se queda en su sitio, que es lo correcto.
  • Se reutiliza el swap del ejercicio 03. Como izq y der ya son punteros, se pasan directamente (swap(izq, der)), sin &: ya contienen las direcciones que swap espera.
  • imprimir recorre con un puntero y un centinela fin = arr + n, la misma técnica del ejercicio 04.

Trampa habitual: equivocar el arranque de der poniendo arr + n (que apunta pasado el último y leería fuera del array), o usar while (izq <= der), que en arrays impares haría un swap de más del centro consigo mismo (inofensivo aquí, pero conceptualmente sobra). Con dos punteros, la condición correcta para parar es que se crucen: izq < der.

Para practicar — cópialo en Dev-C++

Pega este esqueleto y completa los TODO. Es la mejor forma de aprender: inténtalo antes de mirar la solución.

/*
 * Curso de C — Modulo 07: Punteros
 * Ejercicio 07 — PRACTICA (rellena los TODO)
 * Enunciado: Funcion invertir(int *arr, int n) que invierte el array in-place
 *            con dos punteros (inicio y fin) avanzando hacia el centro con swap.
 * Dificultad: rojo
 * Compilar: gcc -std=c11 -Wall ej07_practica.c -o ej07 && ./ej07
 */
 
#include <stdio.h>
 
/*
 * TODO 1: Define void swap(int *a, int *b).
 *         (Igual que en ej03, la necesitamos aqui tambien)
 */
 
/*
 * TODO 2: Define void invertir(int *arr, int n).
 *
 *   Idea: dos punteros que se acercan desde los extremos.
 *   a) int *izq = arr;          <- apunta al primer elemento
 *   b) int *der = arr + n - 1;  <- apunta al ultimo
 *   c) while (izq < der):
 *      - swap(izq, der)
 *      - izq++
 *      - der--
 *   Cuando izq >= der hemos terminado (centro alcanzado).
 */
 
/*
 * TODO 3: Define void imprimir(int *arr, int n).
 *         Recorre con un puntero e imprime cada elemento separado por espacio.
 *         Al final imprime '\n'.
 */
 
int main(void) {
    int n;
    scanf("%d", &n);
 
    int arr[100];
    int i;
    for (i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
 
    // TODO 4: Imprime "Original:  " y llama a imprimir.
 
    // TODO 5: Llama a invertir.
 
    // TODO 6: Imprime "Invertido: " y llama a imprimir de nuevo.
 
    return 0;
}

Solución — cópiala y ejecútala

/*
 * Curso de C — Modulo 07: Punteros
 * Ejercicio 07 — MODELO (resuelto)
 * Enunciado: Funcion invertir(int *arr, int n) que invierte el array in-place
 *            con dos punteros (inicio y fin) avanzando hacia el centro con swap.
 * Dificultad: rojo
 * Compilar: gcc -std=c11 -Wall ej07_modelo.c -o ej07 && ./ej07
 */
 
#include <stdio.h>
 
/* Intercambia los valores de *a y *b */
void swap(int *a, int *b) {
    int tmp = *a;
    *a = *b;
    *b = tmp;
}
 
/*
 * Invierte el array arr de n elementos sin array auxiliar.
 * Usa dos punteros: izq apunta al inicio, der al ultimo elemento.
 * Intercambia y acerca los punteros hasta que se cruzan.
 */
void invertir(int *arr, int n) {
    int *izq = arr;          // puntero al primer elemento
    int *der = arr + n - 1;  // puntero al ultimo elemento
 
    while (izq < der) {
        swap(izq, der);  // intercambia los extremos actuales
        izq++;           // avanza desde el inicio
        der--;           // retrocede desde el final
    }
}
 
/* Imprime los n elementos de arr separados por espacios */
void imprimir(int *arr, int n) {
    int *p = arr;
    int *fin = arr + n;
    while (p < fin) {
        printf("%d", *p);
        if (p + 1 < fin) printf(" ");
        p++;
    }
    printf("\n");
}
 
int main(void) {
    int n;
    scanf("%d", &n);
 
    int arr[100];  // tamano maximo razonable
    int i;
    for (i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
 
    printf("Original:  ");
    imprimir(arr, n);
 
    invertir(arr, n);
 
    printf("Invertido: ");
    imprimir(arr, n);
 
    return 0;
}

Cómo usarlo

Dev-C++ (Windows): Archivo → Nuevo → Código fuente, pega el código y pulsa F11 (compilar y ejecutar). Si ves los acentos raros en la consola, escribe chcp 65001 y vuelve a ejecutar.

Conexiones