Recorrido de arrays utilizando punteros

CCBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

La aritmética de punteros es una característica poderosa en C que te permite manipular direcciones de memoria sumando o restando valores. Una de las aplicaciones más comunes de la aritmética de punteros es el recorrido de arrays. Utilizando punteros, podemos recorrer eficientemente arrays tanto en dirección hacia adelante como hacia atrás.

En este laboratorio (LabEx), aprenderás cómo crear e inicializar arrays, configurar punteros para acceder a los elementos de un array y utilizar la aritmética de punteros para recorrer arrays. Esta técnica es fundamental en la programación en C y es la base de muchas operaciones avanzadas de manipulación de datos.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL c(("C")) -.-> c/UserInteractionGroup(["User Interaction"]) c(("C")) -.-> c/CompoundTypesGroup(["Compound Types"]) c(("C")) -.-> c/PointersandMemoryGroup(["Pointers and Memory"]) c/CompoundTypesGroup -.-> c/arrays("Arrays") c/PointersandMemoryGroup -.-> c/pointers("Pointers") c/UserInteractionGroup -.-> c/output("Output") subgraph Lab Skills c/arrays -.-> lab-123301{{"Recorrido de arrays utilizando punteros"}} c/pointers -.-> lab-123301{{"Recorrido de arrays utilizando punteros"}} c/output -.-> lab-123301{{"Recorrido de arrays utilizando punteros"}} end

Creación de un programa básico en C

Comencemos creando un nuevo archivo C en el editor de VSCode. Este archivo contendrá nuestro programa principal para el recorrido de arrays utilizando punteros.

  1. En el WebIDE, localiza el panel del Explorador en el lado izquierdo y navega hasta el directorio ~/project.

  2. Haz clic derecho en la carpeta project y selecciona "Nuevo archivo". Nombrar el archivo main.c.

  3. Copia la siguiente estructura básica de un programa en C en el archivo:

#include <stdio.h>

int main() {
    printf("Array Traversal using Pointers\n");

    return 0;
}
  1. Guarda el archivo presionando Ctrl+S o utilizando Archivo > Guardar desde el menú.

  2. Compilaremos y ejecutaremos este programa para asegurarnos de que todo esté configurado correctamente. Abre una terminal en el WebIDE seleccionando Terminal > Nueva Terminal desde el menú, y ejecuta:

cd ~/project
gcc main.c -o main
./main

Deberías ver la siguiente salida:

Array Traversal using Pointers

Esto confirma que tu entorno de desarrollo en C está funcionando correctamente. En los siguientes pasos, modificaremos este programa para trabajar con arrays y punteros.

Declaración e inicialización de arrays y punteros

En este paso, aprenderemos cómo declarar un array y un puntero, que son los componentes fundamentales para el recorrido de arrays utilizando punteros.

Comprensión de arrays y punteros

Un array en C es una colección de elementos del mismo tipo almacenados en ubicaciones de memoria contiguas. Por ejemplo, un array de enteros con 5 elementos reservará espacio para 5 enteros en memoria, uno después de otro.

Un puntero es una variable que almacena la dirección de memoria de otra variable. Podemos utilizar punteros para acceder indirectamente al valor almacenado en una dirección de memoria particular.

Modifiquemos nuestro archivo main.c para incluir un array y un puntero:

#include <stdio.h>

int main() {
    printf("Array Traversal using Pointers\n\n");

    // Declare and initialize an array of 5 integers
    int arr[5] = {10, 20, 30, 40, 50};

    // Declare a pointer of integer type
    int *ptr;

    // Print the array elements using array notation
    printf("Array elements using array notation:\n");
    for(int i = 0; i < 5; i++) {
        printf("arr[%d] = %d\n", i, arr[i]);
    }

    return 0;
}

En este código:

  • Declaramos un array de enteros arr con 5 elementos y lo inicializamos con los valores 10, 20, 30, 40 y 50.
  • Declaramos un puntero de tipo entero ptr que se utilizará más adelante para apuntar a los elementos del array.
  • Imprimimos los elementos del array utilizando la notación de array tradicional.

Compila y ejecuta el programa para ver los elementos del array:

gcc main.c -o main
./main

Deberías ver la siguiente salida:

Array Traversal using Pointers

Array elements using array notation:
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
arr[4] = 50

En el siguiente paso, conectaremos el puntero al array y accederemos a los elementos del array utilizando el puntero.

Vinculación de punteros con arrays y recorrido hacia adelante

En este paso, estableceremos la conexión entre nuestro puntero y el array, y luego utilizaremos el puntero para recorrer el array en dirección hacia adelante.

Conectar un puntero a un array

En C, el nombre de un array sin un índice representa la dirección del primer elemento del array. Esto significa que podemos asignar directamente esta dirección a una variable puntero.

Modifiquemos nuestro archivo main.c para vincular el puntero con el array y recorrerlo:

#include <stdio.h>

int main() {
    printf("Array Traversal using Pointers\n\n");

    // Declare and initialize an array of 5 integers
    int arr[5] = {10, 20, 30, 40, 50};

    // Declare a pointer of integer type
    int *ptr;

    // Assign the address of the first element of the array to the pointer
    ptr = arr;  // This is equivalent to ptr = &arr[0]

    // Print the array elements using array notation
    printf("Array elements using array notation:\n");
    for(int i = 0; i < 5; i++) {
        printf("arr[%d] = %d\n", i, arr[i]);
    }

    // Print the array elements using pointer notation
    printf("\nArray elements using pointer notation (forward traversal):\n");
    for(int i = 0; i < 5; i++) {
        printf("*(ptr + %d) = %d\n", i, *(ptr + i));
    }

    return 0;
}

En este código actualizado:

  • Asignamos la dirección del primer elemento del array arr al puntero ptr.
  • Añadimos un nuevo bucle que recorre el array utilizando aritmética de punteros.
  • La expresión *(ptr + i) accede al valor en la ubicación de memoria ptr + i. Cuando i es 0, este es el primer elemento del array; cuando i es 1, es el segundo elemento, y así sucesivamente.

Compila y ejecuta el programa para ver los resultados:

gcc main.c -o main
./main

Deberías ver la siguiente salida:

Array Traversal using Pointers

Array elements using array notation:
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
arr[4] = 50

Array elements using pointer notation (forward traversal):
*(ptr + 0) = 10
*(ptr + 1) = 20
*(ptr + 2) = 30
*(ptr + 3) = 40
*(ptr + 4) = 50

Observa que ambos métodos producen la misma salida. Esto demuestra que la aritmética de punteros se puede utilizar para acceder a los elementos de un array al igual que el índice de array tradicional.

Implementación del incremento de punteros para el recorrido de arrays

En el paso anterior, accedimos a los elementos de un array utilizando la expresión *(ptr + i). Aunque esto funciona perfectamente, C ofrece una forma más concisa de recorrer un array utilizando punteros: el operador de incremento (++).

Cuando incrementamos un puntero, se mueve a la siguiente ubicación de memoria en función del tamaño del tipo de datos al que apunta. Para un puntero a entero, incrementarlo lo mueve al siguiente entero en memoria.

Modifiquemos nuestro archivo main.c para utilizar el incremento de punteros para recorrer el array:

#include <stdio.h>

int main() {
    printf("Array Traversal using Pointers\n\n");

    // Declare and initialize an array of 5 integers
    int arr[5] = {10, 20, 30, 40, 50};

    // Declare and initialize a pointer to the first element of the array
    int *ptr = arr;  // Same as ptr = &arr[0]

    // Print the array elements using pointer incrementation
    printf("Array elements using pointer incrementation:\n");
    for(int i = 0; i < 5; i++) {
        printf("*ptr = %d\n", *ptr);
        ptr++;  // Move the pointer to the next element
    }

    // Reset the pointer to the beginning of the array
    ptr = arr;

    // Print all elements in a single line using pointer incrementation
    printf("\nAll elements in a single line: ");
    for(int i = 0; i < 5; i++) {
        printf("%d ", *ptr++);  // Print and then increment
    }
    printf("\n");

    return 0;
}

En este código actualizado:

  • Inicializamos el puntero ptr directamente cuando lo declaramos.
  • Dentro del primer bucle, usamos *ptr para acceder al elemento actual y luego usamos ptr++ para mover el puntero al siguiente elemento.
  • Después del primer bucle, restablecemos ptr para que apunte al inicio del array nuevamente.
  • En el segundo bucle, usamos el operador de post-incremento *ptr++, que primero utiliza el valor actual de ptr y luego lo incrementa.

Compila y ejecuta el programa para ver los resultados:

gcc main.c -o main
./main

Deberías ver la siguiente salida:

Array Traversal using Pointers

Array elements using pointer incrementation:
*ptr = 10
*ptr = 20
*ptr = 30
*ptr = 40
*ptr = 50

All elements in a single line: 10 20 30 40 50

Esto demuestra cómo utilizar el incremento de punteros para recorrer un array. El punto clave es que ptr++ tiene en cuenta automáticamente el tamaño del tipo de datos cuando se mueve al siguiente elemento.

Implementación del recorrido hacia atrás utilizando el decremento de punteros

En los pasos anteriores, recorrimos el array en dirección hacia adelante. Ahora, aprendamos cómo recorrer el array en dirección inversa utilizando el decremento de punteros.

Para el recorrido hacia atrás, necesitamos:

  1. Inicializar el puntero para que apunte al último elemento del array.
  2. Decrementar el puntero para moverse hacia atrás a través del array.

Modifiquemos nuestro archivo main.c para implementar el recorrido hacia atrás:

#include <stdio.h>

int main() {
    printf("Array Traversal using Pointers\n\n");

    // Declare and initialize an array of 5 integers
    int arr[5] = {10, 20, 30, 40, 50};

    // Forward traversal using pointer increment
    int *ptr = arr;
    printf("Forward traversal using pointer increment:\n");
    for(int i = 0; i < 5; i++) {
        printf("%d ", *ptr);
        ptr++;
    }
    printf("\n\n");

    // Backward traversal using pointer decrement
    // Point to the last element of the array
    ptr = &arr[4];  // or ptr = arr + 4

    printf("Backward traversal using pointer decrement:\n");
    for(int i = 0; i < 5; i++) {
        printf("%d ", *ptr);
        ptr--;  // Move the pointer to the previous element
    }
    printf("\n\n");

    // Alternative approach: Start from the last element and decrement in the loop condition
    printf("Alternative backward traversal approach:\n");
    for(ptr = &arr[4]; ptr >= arr; ptr--) {
        printf("%d ", *ptr);
    }
    printf("\n");

    return 0;
}

En este código actualizado:

  • Primero realizamos un recorrido hacia adelante utilizando el incremento de punteros.
  • Para el recorrido hacia atrás, establecemos el puntero en el último elemento del array utilizando ptr = &arr[4].
  • Dentro del bucle, imprimimos el elemento actual y luego decrementamos el puntero utilizando ptr--.
  • También mostramos un método alternativo donde el decremento es parte de la declaración de actualización del bucle for.

Compila y ejecuta el programa para ver los resultados:

gcc main.c -o main
./main

Deberías ver la siguiente salida:

Array Traversal using Pointers

Forward traversal using pointer increment:
10 20 30 40 50

Backward traversal using pointer decrement:
50 40 30 20 10

Alternative backward traversal approach:
50 40 30 20 10

Esto demuestra cómo recorrer un array tanto en dirección hacia adelante como hacia atrás utilizando la aritmética de punteros. La capacidad de incrementar y decrementar punteros facilita el recorrido de arrays en cualquier dirección.

Resumen

En este laboratorio, has aprendido cómo recorrer arrays utilizando punteros en programación C. Aquí están los conceptos clave que cubrimos:

  1. Conceptos básicos de arrays y punteros:

    • Los arrays en C almacenan elementos en ubicaciones de memoria contiguas.
    • Los punteros almacenan direcciones de memoria y se pueden utilizar para acceder a esas ubicaciones.
  2. Relación entre punteros y arrays:

    • El nombre del array (sin índice) representa la dirección del primer elemento.
    • Podemos asignar esta dirección a un puntero para establecer una conexión con el array.
  3. Técnicas de recorrido hacia adelante:

    • Utilizando aritmética de punteros: *(ptr + i)
    • Utilizando incremento de punteros: *ptr seguido de ptr++
    • Combinando desreferenciación e incremento: *ptr++
  4. Técnicas de recorrido hacia atrás:

    • Inicializar el puntero al último elemento: ptr = &arr[size-1]
    • Utilizar decremento de punteros: ptr-- para moverse hacia atrás.
    • La condición del bucle puede comprobar cuándo el puntero alcanza el inicio del array.

La aritmética de punteros es una característica poderosa en C que permite una manipulación eficiente de la memoria y brinda flexibilidad al trabajar con arrays y otras estructuras de datos. Esta técnica forma la base para conceptos de programación más avanzados, como la asignación dinámica de memoria, las listas enlazadas y otras estructuras de datos complejas.