Menu
Coddy logo textTech

Passagem de Ponteiros para Structs

Parte da seção Logic & Flow do Journey de C da Coddy — lição 47 de 63.

Embora a passagem de structs por valor funcione bem para a leitura de dados, ela se torna ineficiente com structs grandes porque toda a estrutura é copiada. Mais importante ainda, você não pode modificar a struct original de dentro da função. É aqui que a passagem de ponteiros para structs se torna essencial.

Quando você passa um ponteiro para uma struct em vez da própria struct, a função recebe o endereço de memória da struct original. Essa abordagem oferece duas vantagens principais: é mais eficiente (sem cópia) e permite que a função modifique os dados originais.

A sintaxe para uma função que aceita um ponteiro para uma struct é:

void functionName(struct StructureName *ptr) {
    // Corpo da função usando ptr->member
}

Dentro da função, você usa o operador de seta para acessar e modificar os membros da struct. Quaisquer alterações feitas através do ponteiro afetarão diretamente a struct original na função chamadora, tornando esta abordagem perfeita para funções que precisam atualizar ou transformar dados da struct.

Esta técnica é fundamental para a construção de programas em C eficientes que trabalham com estruturas de dados complexas, pois combina o poder dos ponteiros com a organização de structs.

challenge icon

Desafio

Fácil

Crie um programa em C que demonstre a passagem de ponteiros para structs para funções para modificação eficiente de dados. Seu programa deve:

  1. Definir uma struct chamada BankAccount com os seguintes membros:
    • Um inteiro accountNumber para armazenar o número da conta
    • Um array de caracteres ownerName com tamanho 30 para armazenar o nome do proprietário da conta
    • Um float balance para armazenar o saldo da conta
    • Um inteiro transactionCount para armazenar o número de transações
  2. Escrever uma função chamada depositMoney que:
    • Recebe um ponteiro para uma struct BankAccount e um valor float como parâmetros
    • Adiciona o valor ao saldo da conta usando o operador de seta (arrow operator)
    • Incrementa o contador de transações em 1
    • Imprime Deposit successful. New balance: [balance]
  3. Escrever uma função chamada withdrawMoney que:
    • Recebe um ponteiro para uma struct BankAccount e um valor float como parâmetros
    • Verifica se o valor do saque é maior que o saldo atual
    • Se houver fundos insuficientes, imprime Insufficient funds. Current balance: [balance]
    • Se houver fundos suficientes, subtrai o valor do saldo, incrementa o contador de transações e imprime Withdrawal successful. New balance: [balance]
  4. Escrever uma função chamada displayAccount que:
    • Recebe um ponteiro para uma struct BankAccount como parâmetro
    • Imprime as informações da conta neste formato exato:
      • Account Information:
      • Account Number: [accountNumber]
      • Owner: [ownerName]
      • Balance: [balance]
      • Transactions: [transactionCount]
  5. Na função main:
    • Cria uma variável BankAccount chamada account
    • Lê o número da conta, o nome do proprietário e o saldo inicial da entrada
    • Define o contador de transações como 0
    • Chama displayAccount para mostrar o estado inicial da conta
    • Lê um valor de depósito e chama depositMoney
    • Lê um valor de saque e chama withdrawMoney
    • Chama displayAccount para mostrar o estado final da conta

Este desafio demonstra o poder de passar ponteiros para structs para funções. Ao contrário da passagem por valor, as funções recebem o endereço de memória da struct original, permitindo que modifiquem diretamente os dados originais. Essa abordagem é mais eficiente (sem cópia) e permite que as funções alterem permanentemente os valores da struct na função que as chamou.

Folha de consulta

Ao passar structs por valor, toda a estrutura é copiada, o que é ineficiente para structs grandes e impede a modificação dos dados originais. Passar ponteiros para structs resolve ambos os problemas ao passar o endereço de memória em vez disso.

Sintaxe da função para aceitar um ponteiro para uma struct:

void functionName(struct StructureName *ptr) {
    // Corpo da função usando ptr->member
}

Dentro da função, use o operador de seta (->) para acessar e modificar os membros da struct através do ponteiro. Quaisquer alterações feitas afetarão diretamente a struct original na função chamadora.

Esta abordagem oferece duas vantagens principais:

  • Mais eficiente (sem cópia de toda a struct)
  • Permite que as funções modifiquem os dados da struct original

Experimente você mesmo

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

// TODO: Defina a struct BankAccount aqui

// TODO: Escreva a função depositMoney aqui

// TODO: Escreva a função withdrawMoney aqui

// TODO: Escreva a função displayAccount aqui

int main() {
    // Ler 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: Criar a variável BankAccount e inicializá-la
    
    // TODO: Chamar displayAccount para mostrar o estado inicial
    
    // TODO: Chamar depositMoney com o valor do depósito
    
    // TODO: Chamar withdrawMoney com o valor do saque
    
    // TODO: Chamar displayAccount para mostrar o estado final
    
    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Logic & Flow