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 faz uma diferença significativa no desempenho.
A passagem por valor cria uma cópia completa da struct na pilha. Para uma struct pequena com alguns números inteiros, isso não é 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 com 8 bytes, independentemente do tamanho da struct.
É por isso que 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 clareza de intenção.
Desafio
FácilVamos criar um módulo Product que demonstra a diferença entre passar estruturas por valor e por ponteiro. Você criará duas funções de exibição: uma que recebe a estrutura inteira como uma cópia e outra que recebe apenas um ponteiro para ela.
Você criará três arquivos:
product.h: Declare uma estruturaProductcom três membros:char name[50],double priceeint quantity. Declare também duas funções:display_by_value: recebe umProductpor valor e exibe suas informaçõesdisplay_by_pointer: recebe umconst Product *e exibe as mesmas informações
PRODUCT_H.product.c: Implemente as duas funções. Observe a diferença de sintaxe: a versão que recebe por valor usa o operador ponto (p.name), enquanto a versão que recebe um ponteiro usa o operador seta (p->name). As duas funções devem exibir as informações no mesmo formato.main.c: Crie um Product e, em seguida, chame as duas funções de exibição para mostrar que elas produzem uma saída idêntica, apesar de usarem estilos de parâmetro diferentes.
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 um Product com esses valores e, em seguida, chame display_by_value seguido de display_by_pointer.
As duas funções devem exibir as informações neste formato:
Product: {name}, Price: {price}, Qty: {quantity}Use %.2f para exibir o preço com 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: 5Experimente você mesmo
#include <stdio.h>
#include <string.h>
#include "product.h"
int main() {
char name[50];
double price;
int quantity;
// Leia as 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 nome 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;
}
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
1Fundamentos da Programação Modular
Arquivos de cabeçalhoProteções de inclusãoArquivos-fonteFunções estáticasRevisão: calculadora modular4Encapsulamento
Conceito de ponteiros opacosDefinindo structs opacasGetters e settersValidação em settersRevisão: caixa secreta2Objetos e métodos
Structs como objetosO ponteiro 'Self'Correção de constPonteiro vs. valorMétodos auxiliaresRevisão: Gerenciador de pontos5Projeto: Conta Bancária Simples
Configuração do ProjetoImplementação da Conta3Ciclo de vida do objeto
Padrão de construtorPadrão de destrutorInicialização da pilhaCópia profundaRevisão: wrapper de String6Herança por composição
Incorporação de structRegra do primeiro membroAcessando membros do tipo paiUpcastingRevisão: hierarquia de formas9Projeto: Desenhador de Formas
Visão geral do projetoImplementação do círculoImplementação do retânguloUso polimórficoContêiner de formasPratique por conta própria: Compilador de C online