Pasar punteros a estructuras
Parte de la sección Lógica y Flujo 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 una estructura en lugar de la estructura misma, la función recibe la dirección de memoria de la estructura original. Este enfoque ofrece dos ventajas clave: es más eficiente (no se realiza ninguna copia) 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, usas el operador flecha para acceder a los miembros de la estructura y modificarlos. Cualquier cambio realizado mediante el puntero afectará directamente a la estructura original en la función que realiza la llamada, lo que hace que este enfoque sea perfecto para las funciones que necesitan actualizar o transformar datos de estructuras.
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 cómo pasar punteros a estructuras a funciones para modificar datos de manera eficiente. Tu programa debe:
- Definir una
structllamadaBankAccountcon los siguientes miembros:- Un entero
accountNumberpara almacenar el número de cuenta - Un arreglo de caracteres
ownerNamede tamaño 30 para almacenar el nombre del titular de la cuenta - Un número de punto flotante
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 como parámetros un puntero a una estructura
BankAccounty un monto de tipo float - Agregue el monto al saldo de la cuenta mediante el operador flecha
- Incremente el número de transacciones en 1
- Imprima
Deposit successful. New balance: [balance]
- Reciba como parámetros un puntero a una estructura
- Escribir una función llamada
withdrawMoneyque:- Reciba como parámetros un puntero a una estructura
BankAccounty un monto de tipo float - Compruebe si el monto del retiro es mayor que el saldo actual
- Si los fondos son insuficientes, imprima
Insufficient funds. Current balance: [balance] - Si los fondos son suficientes, reste el monto del saldo, incremente el número de transacciones e imprima
Withdrawal successful. New balance: [balance]
- Reciba como parámetros un puntero a una estructura
- Escribir una función llamada
displayAccountque:- Reciba como parámetro un puntero a una estructura
BankAccount - Imprima la información de la cuenta con este formato exacto:
Account Information:Account Number: [accountNumber]Owner: [ownerName]Balance: [balance]Transactions: [transactionCount]
- Reciba como parámetro un puntero a una estructura
- En la función main:
- Crear una variable
BankAccountllamadaaccount - Leer de la entrada el número de cuenta, el nombre del titular y el saldo inicial
- Establecer el número de transacciones en 0
- Llamar a
displayAccountpara mostrar el estado inicial de la cuenta - Leer un monto de depósito y llamar a
depositMoney - Leer un monto de retiro y llamar a
withdrawMoney - Llamar a
displayAccountpara mostrar el estado final de la cuenta
- Crear una variable
Este desafío demuestra el poder de pasar punteros a estructuras a las 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 (no requiere copiar) y permite que las funciones cambien permanentemente los valores de la estructura en la función que realiza la llamada.
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 Lógica y Flujo
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 cadenasPractica por tu cuenta: Compilador de C online