Menu
Coddy logo textTech

A Regra do Primeiro Membro

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

Quando você incorpora uma struct como o primeiro membro de outra struct, algo poderoso acontece: o endereço de memória da struct externa é idêntico ao endereço de memória de seu primeiro membro. Isso é garantido pelo padrão C.

Considere nosso exemplo anterior:

typedef struct {
    int id;
} Parent;

typedef struct {
    Parent parent;  // Primeiro membro
    int grade;
} Child;

Quando você cria uma variável Child, o membro Parent fica exatamente no início da memória de Child. Isso significa que um ponteiro para Child aponta para o mesmo endereço exato que um ponteiro para seu membro Parent.

Child c;
Child* child_ptr = &c;
Parent* parent_ptr = (Parent*)child_ptr;  // Cast seguro!

Ambos os ponteiros contêm o mesmo endereço. Isso permite passar um Child* para qualquer função que espere um Parent*:

void print_id(Parent* p) {
    printf("ID: %d\n", p->id);
}

// No main:
Child c;
c.parent.id = 42;
print_id((Parent*)&c);  // Funciona perfeitamente

Essa técnica é a base da herança em C. Uma função escrita para o tipo base pode operar em qualquer tipo derivado, desde que a base seja incorporada primeiro. A conversão é segura porque os layouts de memória se alinham perfeitamente.

challenge icon

Desafio

Fácil

Vamos explorar a regra do primeiro membro construindo uma hierarquia simples de animais. Você criará uma struct base Animal e uma struct derivada Dog e, em seguida, demonstrará como um ponteiro para Dog pode ser convertido com segurança em um ponteiro para Animal.

A principal ideia que você aplicará é: quando Animal é o primeiro membro de Dog, ambas as structs compartilham o mesmo endereço inicial de memória. Isso significa que você pode passar um Dog* para qualquer função que espere um Animal* convertendo o ponteiro.

Você organizará seu código em três arquivos:

  • animal.h: Defina ambas as structs com guardas de inclusão. Sua struct Animal deve ter um único campo: legs (um inteiro que representa o número de pernas). Sua struct Dog deve incorporar Animal como seu primeiro membro e adicionar um campo name (um array de caracteres com 50 caracteres). Também declare uma função print_animal que recebe um parâmetro Animal*.
  • animal.c: Implemente a função print_animal. Essa função trabalha com o tipo base. Ela conhece apenas Animal e exibe quantas pernas o animal tem.
  • main.c: Crie uma variável Dog e preencha seus campos (tanto as pernas do animal incorporado quanto o nome do cachorro). Em seguida, demonstre a regra do primeiro membro convertendo seu Dog* em um Animal* e passando-o para print_animal. Exiba também o nome do cachorro separadamente para mostrar o quadro completo.

Você receberá duas entradas: o nome do cachorro (uma string) e o número de pernas (um inteiro).

Sua saída deve ser semelhante a esta:

Dog: Buddy
Legs: 4

Em que Buddy é o nome do cachorro e 4 é o número de pernas. Exiba primeiro o nome do cachorro a partir de main.c e, em seguida, chame print_animal com o ponteiro convertido para exibir as pernas.

Isso demonstra como uma função escrita para o tipo base (Animal) pode trabalhar perfeitamente com um tipo derivado (Dog) por meio da conversão de ponteiros: a base da herança em C.

Experimente você mesmo

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

int main() {
    // Ler entrada
    char name[50];
    int legs;
    scanf("%s", name);
    scanf("%d", &legs);
    
    // TODO: Crie uma variável Dog
    
    // TODO: Defina o nome do dog usando strcpy
    
    // TODO: Defina o número de pernas (acesse através do Animal embutido)
    
    // TODO: Imprima o nome do dog no formato: "Dog: <name>"
    
    // TODO: Faça cast de Dog* para Animal* e chame print_animal
    // Isso demonstra a regra do primeiro membro!
    
    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