Passagem de Structs por Valor
Parte da seção Logic & Flow do Journey de C da Coddy — lição 46 de 63.
Agora que você sabe como trabalhar com structs e ponteiros para structs, é hora de aprender como passar structs inteiras para funções. Quando você passa uma struct para uma função como um parâmetro, o C usa passagem por valor, o que significa que a função recebe uma cópia completa da struct.
Aqui está a sintaxe para uma função que aceita um parâmetro struct:
void functionName(struct StructureName parameterName) {
// Corpo da função
}Usando nossa conhecida struct Point como exemplo:
void printPoint(struct Point p) {
printf("Point coordinates: (%d, %d)\n", p.x, p.y);
}O conceito principal a ser entendido é que quaisquer alterações que você fizer na struct dentro da função não afetarão a struct original na função de chamada. Isso ocorre porque a função trabalha com sua própria cópia dos dados.
Esta abordagem é útil quando você deseja ler ou exibir dados de uma struct sem o risco de modificações acidentais no original. No entanto, tenha em mente que copiar structs grandes pode ser ineficiente em termos de memória e desempenho.
Desafio
FácilCrie um programa em C que demonstre a passagem de structs para funções por valor. Seu programa deve:
- Definir uma
structchamadaRectanglecom os seguintes membros:- Um inteiro
widthpara armazenar a largura do retângulo - Um inteiro
heightpara armazenar a altura do retângulo - Um array de caracteres
colorcom tamanho 15 para armazenar a cor do retângulo
- Um inteiro
- Escrever uma função chamada
displayRectangleque:- Recebe uma struct
Rectanglecomo parâmetro (passagem por valor) - Imprime as informações do retângulo exatamente neste formato:
Rectangle Details:Width: [width]Height: [height]Color: [color]Area: [area]
- Calcula e imprime a área (width × height)
- Recebe uma struct
- Escrever uma função chamada
modifyRectangleque:- Recebe uma struct
Rectanglecomo parâmetro (passagem por valor) - Dobra tanto a largura quanto a altura do retângulo
- Altera a cor para "Modified"
- Imprime
Inside modifyRectangle function: - Chama
displayRectanglepara mostrar o retângulo modificado
- Recebe uma struct
- Na função principal:
- Cria uma variável
Rectanglechamadarect - Lê a largura, altura e cor da entrada e as atribui aos membros da struct
- Imprime
Original rectangle: - Chama
displayRectanglepara mostrar o retângulo original - Chama
modifyRectanglecom o retângulo - Imprime
After modifyRectangle call: - Chama
displayRectanglenovamente para mostrar que o retângulo original permanece inalterado
- Cria uma variável
Este desafio demonstra o conceito fundamental de passagem por valor com structs: quando você passa uma struct para uma função, a função recebe uma cópia completa da struct. Quaisquer modificações feitas dentro da função afetam apenas a cópia, não a struct original na função chamadora.
Folha de consulta
Ao passar structs para funções, a linguagem C utiliza passagem por valor, o que significa que a função recebe uma cópia completa da struct.
Sintaxe da função para aceitar um parâmetro struct:
void functionName(struct StructureName parameterName) {
// Corpo da função
}Exemplo com uma struct Point:
void printPoint(struct Point p) {
printf("Point coordinates: (%d, %d)\n", p.x, p.y);
}Conceito-chave: Alterações feitas na struct dentro da função não afetam a struct original na função chamadora, uma vez que a função trabalha com sua própria cópia dos dados.
Essa abordagem é útil para ler ou exibir dados de uma struct sem o risco de modificar a original, mas copiar structs grandes pode ser ineficiente.
Experimente você mesmo
#include <stdio.h>
#include <string.h>
// TODO: Defina a struct Rectangle aqui
// TODO: Escreva a função displayRectangle aqui
// TODO: Escreva a função modifyRectangle aqui
int main() {
// Ler entrada
int width, height;
char color[15];
scanf("%d", &width);
scanf("%d", &height);
scanf("%s", color);
// TODO: Criar a variável Rectangle e atribuir os valores de entrada
// TODO: Imprimir "Original rectangle:" e chamar displayRectangle
// TODO: Chamar modifyRectangle
// TODO: Imprimir "After modifyRectangle call:" e chamar displayRectangle novamente
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 Logic & Flow
1Fundamentos de Ponteiros
O que é um Ponteiro?Declarando PonteirosO Operador de Endereço (&)O Operador de Desreferência (*)Ponteiros NULLRecapitulação: Fundamentos de Ponteiros4Projeto: Utilitário de Texto Simples
Visão Geral do ProjetoContando Caracteres2Ponteiros e Arrays
Nomes de Arrays como PonteirosElementos de Array - PonteirosAritmética de PonteirosComparando PonteirosRecapitulação: Percorrendo Arrays com Ponteiros5Ponteiros e Funções
Passagem por ValorPassando Ponteiros para FunçõesModificando Variáveis via PonteirosUm Exemplo Clássico: SwapPassando Arrays para FunçõesRecapitulação: Ponteiros como Argumentos8Structs e Ponteiros
Ponteiros para StructsO Operador Seta (->)Passagem de Structs por ValorPassagem de Ponteiros para StructsAlocação Dinâmica de StructsRecapitulação: Modificando Struct - Ptr3Arrays de Caracteres e Strings
Strings como Arrays de charO Terminador NuloEntrada de Strings com scanfUsando strlen()Usando strcpy()Usando strcat()Usando strcmp()Recapitulação: Funções Básicas de Strings6Gerenciamento de Memória
Memória Stack vs. HeapAlocação Dinâmica - malloc()Usando sizeof() para AlocaçãoVerificando Falhas de AlocaçãoLiberando Memória com free()Alocando com calloc()Recapitulação: Array Dinâmico9Projeto: Cadastro Simples de Contatos
Projeto: Definir a Struct de ContatoFunção para Criar um Contato