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.
Desafio
FácilVamos 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 structProductcom três membros:char name[50],double priceeint quantity. Declare também duas funções:display_by_value: recebe umaProductpor valor e exibe suas informaçõesdisplay_by_pointer: recebe umaconst Product *e exibe as mesmas informações
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: 5Experimente 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;
}
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çalhoInclude GuardsArquivos-FonteFunções EstáticasRecapitulação: Calculadora Modular4Encapsulamento
Conceito de Ponteiros OpacosDefinindo Structs OpacasGetters e SettersValidação em SettersRecapitulação: Caixa Secreta2Objetos e Métodos
Structs como ObjetosO Ponteiro 'Self'Const CorrectnessPonteiro vs ValorMétodos AuxiliaresRecapitulação: Point Manager5Projeto: Conta Bancária Simples
Configuração do ProjetoImplementação da Conta3Ciclo de Vida de Objetos
Padrão de ConstrutorPadrão de DestrutorInicialização na StackCópia ProfundaRecapitulação: String Wrapper6Herança via Composição
Incorporação de StructsA Regra do Primeiro MembroAcessando Membros PaiUpcastingRecapitulação: Hierarquia de Formas9Projeto: Desenhador de Formas
Visão Geral do ProjetoImplementação do CírculoImplementação do RetânguloUso PolimórficoContainer de FormasPratique por conta própria: Compilador de C online