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.
Desafío
FácilCrea un programa en C que demuestre el paso de punteros a estructuras a funciones para una modificación eficiente de datos. Tu programa debe:
- Definir un
structllamadoBankAccountcon los siguientes miembros:- Un entero
accountNumberpara almacenar el número de cuenta - Un arreglo de caracteres
ownerNamecon tamaño 30 para almacenar el nombre del propietario de la cuenta - Un float
balancepara almacenar el saldo de la cuenta - Un entero
transactionCountpara almacenar el número de transacciones
- Un entero
- Escribir una función llamada
depositMoneyque:- Reciba un puntero a una estructura
BankAccounty 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]
- Reciba un puntero a una estructura
- Escribir una función llamada
withdrawMoneyque:- Reciba un puntero a una estructura
BankAccounty 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]
- Reciba un puntero a una estructura
- Escribir una función llamada
displayAccountque:- Reciba un puntero a una estructura
BankAccountcomo parámetro - Imprima la información de la cuenta en este formato exacto:
Account Information:Account Number: [accountNumber]Owner: [ownerName]Balance: [balance]Transactions: [transactionCount]
- Reciba un puntero a una estructura
- En la función main:
- Cree una variable
BankAccountllamadaaccount - 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
displayAccountpara 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
displayAccountpara mostrar el estado final de la cuenta
- Cree una variable
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;
}Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Logic & Flow
1Fundamentos de Punteros
¿Qué es un puntero?Declaración de punterosEl operador de dirección (&)El operador de desreferencia (*)Punteros NULLResumen: Conceptos básicos de punteros4Proyecto: Utilidad de texto simple
Descripción general del proyectoContar caracteres2Punteros y Arrays
Nombres de Arrays como PunterosElementos de un Array - PunterosAritmética de PunterosComparación de PunterosResumen: Recorrido de Arrays con Punteros5Punteros y funciones
Paso por valorPasar punteros a funcionesModificar variables mediante punterosUn ejemplo clásico: Intercambio (Swap)Pasar arrays a funcionesResumen: Argumentos de punteros a funciones8Estructuras y Punteros
Punteros a estructurasEl operador flecha (->)Pasar estructuras por valorPasar punteros a estructurasAsignación dinámica de estructurasResumen: Modificar estructuras - Ptr3Arreglos de caracteres y cadenas
Cadenas como arreglos de charEl terminador nuloEntrada de cadenas con scanfUso de strlen()Uso de strcpy()Uso de strcat()Uso de strcmp()Resumen: Funciones básicas de cadenas