Menu
Coddy logo textTech

Pasar punteros a estructuras

Parte de la sección Logic & Flow del Journey de C de Coddy — lección 47 de 63.

Si bien pasar estructuras por valor funciona bien para leer datos, se vuelve ineficiente con estructuras grandes porque se copia toda la estructura. Más importante aún, no puedes modificar la estructura original desde dentro de la función. Aquí es donde pasar punteros a estructuras se vuelve esencial.

Cuando pasas un puntero a un struct en lugar del struct mismo, la función recibe la dirección de memoria del struct original. Este enfoque ofrece dos ventajas clave: es más eficiente (sin copias) y permite que la función modifique los datos originales.

La sintaxis para una función que acepta un puntero a una estructura es:

void functionName(struct StructureName *ptr) {
    // Cuerpo de la función usando ptr->member
}

Dentro de la función, utilizas el operador de flecha para acceder y modificar los miembros de la struct. Cualquier cambio realizado a través del puntero afectará directamente a la struct original en la función que realiza la llamada, lo que hace que este enfoque sea perfecto para funciones que necesitan actualizar o transformar datos de la struct.

Esta técnica es fundamental para construir programas en C eficientes que trabajen con estructuras de datos complejas, ya que combina la potencia de los punteros con la organización de los structs.

challenge icon

Desafío

Fácil

Crea un programa en C que demuestre el paso de punteros a estructuras a funciones para una modificación eficiente de datos. Tu programa debe:

  1. Definir un struct llamado BankAccount con los siguientes miembros:
    • Un entero accountNumber para almacenar el número de cuenta
    • Un arreglo de caracteres ownerName con tamaño 30 para almacenar el nombre del propietario de la cuenta
    • Un float balance para almacenar el saldo de la cuenta
    • Un entero transactionCount para almacenar el número de transacciones
  2. Escribir una función llamada depositMoney que:
    • Reciba un puntero a una estructura BankAccount y una cantidad float como parámetros
    • Sume la cantidad al saldo de la cuenta utilizando el operador de flecha
    • Incremente el recuento de transacciones en 1
    • Imprima Deposit successful. New balance: [balance]
  3. Escribir una función llamada withdrawMoney que:
    • Reciba un puntero a una estructura BankAccount y una cantidad float como parámetros
    • Verifique si la cantidad a retirar es mayor que el saldo actual
    • Si los fondos son insuficientes, imprima Insufficient funds. Current balance: [balance]
    • Si hay fondos suficientes, reste la cantidad del saldo, incremente el recuento de transacciones e imprima Withdrawal successful. New balance: [balance]
  4. Escribir una función llamada displayAccount que:
    • Reciba un puntero a una estructura BankAccount como parámetro
    • Imprima la información de la cuenta en este formato exacto:
      • Account Information:
      • Account Number: [accountNumber]
      • Owner: [ownerName]
      • Balance: [balance]
      • Transactions: [transactionCount]
  5. En la función main:
    • Cree una variable BankAccount llamada account
    • Lea el número de cuenta, el nombre del propietario y el saldo inicial desde la entrada
    • Establezca el recuento de transacciones en 0
    • Llame a displayAccount para mostrar el estado inicial de la cuenta
    • Lea una cantidad de depósito y llame a depositMoney
    • Lea una cantidad de retiro y llame a withdrawMoney
    • Llame a displayAccount para mostrar el estado final de la cuenta

Este desafío demuestra el poder de pasar punteros a estructuras a funciones. A diferencia del paso por valor, las funciones reciben la dirección de memoria de la estructura original, lo que les permite modificar directamente los datos originales. Este enfoque es más eficiente (sin copias) y permite que las funciones cambien permanentemente los valores de la estructura en la función que las llama.

Hoja de referencia

Al pasar estructuras por valor, se copia la estructura completa, lo cual es ineficiente para estructuras grandes y evita modificar los datos originales. Pasar punteros a estructuras resuelve ambos problemas al pasar la dirección de memoria en su lugar.

Sintaxis de la función para aceptar un puntero a una estructura:

void functionName(struct StructureName *ptr) {
    // Cuerpo de la función usando ptr->member
}

Dentro de la función, use el operador de flecha (->) para acceder y modificar los miembros de la estructura a través del puntero. Cualquier cambio realizado afectará directamente a la estructura original en la función que realiza la llamada.

Este enfoque ofrece dos ventajas clave:

  • Más eficiente (sin copia de la estructura completa)
  • Permite que las funciones modifiquen los datos de la estructura original

Pruébalo tú mismo

#include <stdio.h>
#include <string.h>

// TODO: Define la estructura BankAccount aquí

// TODO: Escribe la función depositMoney aquí

// TODO: Escribe la función withdrawMoney aquí

// TODO: Escribe la función displayAccount aquí

int main() {
    // Leer entrada
    int accountNum;
    char ownerName[30];
    float initialBalance;
    float depositAmount;
    float withdrawAmount;
    
    scanf("%d", &accountNum);
    scanf("%s", ownerName);
    scanf("%f", &initialBalance);
    scanf("%f", &depositAmount);
    scanf("%f", &withdrawAmount);
    
    // TODO: Crear la variable BankAccount e inicializarla
    
    // TODO: Llamar a displayAccount para mostrar el estado inicial
    
    // TODO: Llamar a depositMoney con el monto de depósito
    
    // TODO: Llamar a withdrawMoney con el monto de retiro
    
    // TODO: Llamar a displayAccount para mostrar el estado final
    
    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Logic & Flow