Menu
Coddy logo textTech

Ponteiro vs Valor

Parte da seção Programação Orientada a Objetos do Journey de C da Coddy. Lição 9 de 61.

Quando você passa uma struct para uma função, C oferece duas opções: passá-la por valor (copiar a struct inteira) ou passá-la por ponteiro (copiar apenas o endereço). A escolha é significativamente importante para o desempenho.

Passar por valor cria uma cópia completa da struct na pilha. Para uma struct pequena com alguns inteiros, isso não é um problema. Mas imagine uma struct com centenas de bytes: cada chamada de função copia todos esses dados:

typedef struct {
    char name[100];
    int scores[50];
    double average;
} Student;

// Por valor: copia ~308 bytes a cada chamada
void print_by_value(Student s) {
    printf("%s: %.2f\n", s.name, s.average);
}

// Por ponteiro: copia apenas 8 bytes (o endereço)
void print_by_pointer(const Student *s) {
    printf("%s: %.2f\n", s->name, s->average);
}

A sintaxe também é diferente. Com um parâmetro de valor, você usa o operador ponto (s.name). Com um ponteiro, você usa o operador seta (s->name).

A versão com ponteiro é mais eficiente porque passa apenas um endereço de memória, normalmente 8 bytes, independentemente do tamanho da struct.

É por isso que os programadores de C quase sempre passam structs por ponteiro. Use const quando a função não deve modificar os dados e um ponteiro comum quando deve. Você obtém eficiência e uma intenção clara.

challenge icon

Desafio

Fácil

Vamos criar um módulo Product que demonstra a diferença entre passar structs por valor e por ponteiro. Você criará duas funções de exibição: uma que recebe a struct inteira como uma cópia e outra que recebe apenas um ponteiro para ela.

Você criará três arquivos:

  • product.h: declare uma struct Product com três membros: char name[50], double price e int quantity. Declare também duas funções:
    • display_by_value: recebe uma Product por valor e exibe suas informações
    • display_by_pointer: recebe uma const Product * e exibe as mesmas informações
    Use guardas de inclusão com o símbolo PRODUCT_H.
  • product.c: implemente ambas as funções. Observe a diferença de sintaxe: a versão por valor usa o operador ponto (p.name), enquanto a versão por ponteiro usa o operador seta (p->name). Ambas as funções devem exibir as informações no mesmo formato.
  • main.c: crie uma Product e, em seguida, chame ambas as funções de exibição para mostrar que elas produzem uma saída idêntica, apesar de usarem estilos diferentes de parâmetros.

Você receberá três entradas: o nome do produto (uma string), o preço (um double) e a quantidade (um inteiro).

No seu arquivo principal, inicialize uma Product com esses valores e, em seguida, chame display_by_value seguido de display_by_pointer.

Ambas as funções devem exibir neste formato:

Product: {name}, Price: {price}, Qty: {quantity}

Use %.2f para o preço, a fim de exibir duas casas decimais.

Por exemplo, com as entradas Laptop, 999.99 e 5, a saída seria:

Product: Laptop, Price: 999.99, Qty: 5
Product: Laptop, Price: 999.99, Qty: 5

Experimente você mesmo

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

int main() {
    char name[50];
    double price;
    int quantity;
    
    // Ler entradas
    scanf("%s", name);
    scanf("%lf", &price);
    scanf("%d", &quantity);
    
    // TODO: Crie uma variável Product e inicialize-a com os valores de entrada
    // Dica: Use strcpy para copiar o name para o campo name da struct
    
    // TODO: Chame display_by_value com o Product
    
    // TODO: Chame display_by_pointer com um ponteiro para o Product
    
    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 Programação Orientada a Objetos

Pratique por conta própria: Compilador de C online