Estruturas Aninhadas

Operações relacionais e lógicas Operações Aritméticas variáveis Tipos de dados Estruturas Aninhadas algoritmos

Oi pessoal! Tudo certo? Espero que sim. No meu último artigo eu expliquei sobre Vetor de Registros em Linguagem C. Recordando, registros é o nome do recurso computacional, sendo que cada linguagem de programação pode dar um nome diferente. No caso da linguagem C, chama-se Estruturas. Bom, hoje eu vou mostrar para vocês como trabalhar com Estruturas Aninhadas, isto é, com usar uma estrutura dentro de outra. Vocês vão ver que é bem simples e também muito útil. Vamos começar!

 

 

Estruturas Aninhadas

 

Uma estrutura aninhada é basicamente uma estrutura dentro de outra, isto é, uma estrutura contida em outra ou uma estrutura que pode ser acessada por outra. Há duas formas de implementar estruturas aninhadas. A primeira forma é colocar uma estrutura dentro da outra, literalmente, como apresentado no exemplo a seguir:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>

typedef struct {
    int codigo;
    char nome[200];
    struct {
       int dia;
       int mes;
       int ano;
    };
} Aluno;
Aluno aluno_especial;

int main() {
    setlocale(LC_ALL,"portuguese");
    aluno_especial.codigo = 0;
    strcpy(aluno_especial.nome, "NULL");
    aluno_especial.dia = 0;
    aluno_especial.mes = 0;
    aluno_especial.ano = 0;
    printf(" \n O código do aluno especial é: %d ", aluno_especial.codigo);
    printf(" \n O nome do aluno especial é: %s ", aluno_especial.nome);
    printf(" \n A data de nascimento do aluno especial é: %d / %d / %d ", 
         aluno_especial.dia,aluno_especial.mes, aluno_especial.ano);
    printf(" \n \n");
    printf(" Digite o código do aluno especial: ");
    scanf("%d%*c", &aluno_especial.codigo);
    printf(" Digite o nome do aluno especial: ");
    scanf("%s%*c", &aluno_especial.nome);
    printf(" Digite o dia do nascimento do aluno especial: ");
    scanf("%d%*c", &aluno_especial.dia);
    printf(" Digite o mês do nascimento do aluno especial: ");
    scanf("%d%*c", &aluno_especial.mes);
    printf(" Digite o ano do nascimento do aluno especial: ");
    scanf("%d%*c", &aluno_especial.ano);
    printf(" \n O código do aluno especial é: %d ", aluno_especial.codigo);
    printf(" \n O nome do aluno especial é: %s ", aluno_especial.nome);
    printf(" \n A data de nascimento do aluno especial é: %d / %d / %d ", aluno_especial.dia, 
    aluno_especial.mes, aluno_especial.ano);
    printf(" \n \n");
    return 0;
}

 

Observe as linhas de 06 a 14. Nesse trecho é definida uma estrutura que recebe o nome de Aluno e, dentro dela, outra estrutura com os membros dia, mês e ano. Essa estrutura está nas linhas 10, 11 e 12, note que ela não tem nome, e não é necessário que tenha, pois ela está contida dentro da estrutura Aluno. Podemos dizer que temos uma estrutura externa e uma estrutura interna, as quais são respectivamente Aluno e data. 

 

Os membros da estrutura interna são acessados da mesma forma que a estrutura externa, isto é, diretamente. Veja todas as linhas em que é necessário acessar esses membros, todos eles são acessados diretamente pelo nome da variável da Estrutura. Portanto, a sintaxe para trabalhar com estruturas aninhadas nessa forma é:

 

typedef struct {
    tipo membro_1;
    tipo membro_2;
    ...
    tipo membro_n;
    struct{
        tipo membro_1;
        tipo membro_2;
        ...
        tipo membro_n;
    }
} Nome_estrutura;
Nome_estrutura NE;

 

E para acessar os membros, a sintaxe é:

 

//Para atribuir valores:
NE.membro_1 = 0;

//Para leitura do teclado:
&NE.membro_1

//Para impressão:
NE.membro_1

 

A outra forma é você declarar a estrutura_1 antes e, na  estrutura_2, declarar uma variável da estrutura 1, conforme apresenta o exemplo a seguir:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>

typedef struct {
    int dia;
    int mes;
    int ano;
} Data;

typedef struct { 
    int codigo;
    char nome[200];
    Data datNasc;
} Aluno;
Aluno aluno_especial;

int main() { 
    setlocale(LC_ALL,"portuguese");
    aluno_especial.codigo = 0;
    strcpy(aluno_especial.nome, "NULL");
    aluno_especial.datNasc.dia = 0;
    aluno_especial.datNasc.mes = 0;
    aluno_especial.datNasc.ano = 0;
    printf(" \n O código do aluno especial é: %d ", aluno_especial.codigo);
    printf(" \n O nome do aluno especial é: %s ", aluno_especial.nome);
    printf(" \n A data de nascimento do aluno especial é: %d / %d / %d ", 
        aluno_especial.datNasc.dia, aluno_especial.datNasc.mes, aluno_especial.datNasc.ano);
    printf(" \n \n");
    printf(" Digite o código do aluno especial: ");
    scanf("%d%*c", &aluno_especial.codigo);
    printf(" Digite o nome do aluno especial: ");
    scanf("%s%*c", &aluno_especial.nome);
    printf(" Digite o dia do nascimento do aluno especial: ");
    scanf("%d%*c", &aluno_especial.datNasc.dia);
    printf(" Digite o mês do nascimento do aluno especial: ");
    scanf("%d%*c", &aluno_especial.datNasc.mes);
    printf(" Digite o ano do nascimento do aluno especial: ");
    scanf("%d%*c", &aluno_especial.datNasc.ano);
    printf(" \n O código do aluno especial é: %d ", aluno_especial.codigo);
    printf(" \n O nome do aluno especial é: %s ", aluno_especial.nome);
    printf(" \n A data de nascimento do aluno especial é: %d / %d / %d ", 
       aluno_especial.datNasc.dia, aluno_especial.datNasc.mes, aluno_especial.datNasc.ano);
    printf(" \n \n");
    return 0;
}

 

Neste exemplo as estruturas são declaradas separadamente. As estruturas que serão utilizadas dentro de outras devem ser declaradas antes. Se você declarar uma estrutura_x e tentar utilizá-la dentro de uma estrutura_w, e a estrutura_x não tiver sido declarada antes, ao compilar o programa um erro será apontado. Assim, em nosso exemplo, declaramos antes a estrutura data, que será usada dentro da estrutura aluno. Isso é notado nas linhas 6 a 16.

 

A forma de acesso aos membros da estrutura Aluno agora é um pouco diferente. Dentro da estrutura Aluno é criada uma variável do tipo da estrutura Data, que é datNasc. Esse nome, datNasc, é o nome que deverá ser utilizado para acessar os seus membros. Mas não somente ele, é necessário usar em conjunto com o nome da estrutura aluno, como mostram as linhas 23, 24 e 25.

 

Dessa forma a sintaxe é a seguinte:

 

typedef struct {
    tipo membro_1;
    tipo membro_2;
    ...
    tipo membro_n;
} nome_estrutura_1;

typedef struct {
    tipo membro_1;
    tipo membro_2;
    nome_estrutura_1 NE1;
    ...
    tipo membro_n;
} nome_estrutura_2;

nome_estrutura_2 NE2;

//para acessar os membros
NE2.membro1;
NE2.membro2;
NE2.NE1.membro1;
NE2.NE1.membro2;

 

 

Vetores de Estruturas Aninhadas

 

Para usarmos vetores de estruturas, com estruturas aninhadas, o procedimento é praticamente o mesmo, a única coisa que realmente vai mudar é a inserção da posição do vetor. O exemplo a seguir demonstra como fazer isto:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>

typedef struct {
    int dia;
    int mes;
    int ano;
} Data;

typedef struct {
    int codigo;
    char nome[200];
    Data datNasc;
} Aluno;

Aluno aluno_especial[5];
int i=0;

int main() {
    setlocale(LC_ALL,"portuguese");
    for(i=0; i<5; i++) {
        aluno_especial[i].codigo = 0;
        strcpy(aluno_especial[i].nome, "NULL");
        aluno_especial[i].datNasc.dia = 0;
        aluno_especial[i].datNasc.mes = 0;
        aluno_especial[i].datNasc.ano = 0;
    }

    for(i=0; i<5; i++) {
        printf(" \n ======================================================================");
        printf(" \n O código do aluno especial é: %d ", aluno_especial[i].codigo);
        printf(" \n O nome do aluno especial é: %s ", aluno_especial[i].nome);
        printf(" \n A data de nascimento do aluno especial é: %d / %d / %d ", 
             aluno_especial[i].datNasc.dia, aluno_especial[i].datNasc.mes, 
             aluno_especial[i].datNasc.ano);
        printf(" \n ");
    }

    for(i=0; i<5; i++) {
        printf(" \n ======================================================================");
        printf(" Digite o código do aluno especial: ");
        scanf("%d%*c", &aluno_especial[i].codigo);
        printf(" Digite o nome do aluno especial: ");
        scanf("%s%*c", &aluno_especial[i].nome);
        printf(" Digite o dia do nascimento do aluno especial: ");
        scanf("%d%*c", &aluno_especial[i].datNasc.dia);
        printf(" Digite o mês do nascimento do aluno especial: ");
        scanf("%d%*c", &aluno_especial[i].datNasc.mes);
        printf(" Digite o ano do nascimento do aluno especial: ");
        scanf("%d%*c", &aluno_especial[i].datNasc.ano);
    }

    for(i=0; i<5; i++) {
        printf(" \n ======================================================================");
        printf(" \n O código do aluno especial é: %d ", aluno_especial[i].codigo);
        printf(" \n O nome do aluno especial é: %s ", aluno_especial[i].nome);
        printf(" \n A data de nascimento do aluno especial é: %d / %d / %d ",
            aluno_especial[i].datNasc.dia, aluno_especial[i].datNasc.mes,
            aluno_especial[i].datNasc.ano);
        printf(" \n ");
    }

    return 0;
}

 

 

Conclusão

 

Estruturas aninhadas são ótimas para reaproveitamento de código pois, ao invés de criar uma única estrutura com muitos membros, e que nem sempre serão acessados, várias estruturas podem ser criadas, de forma ainda mais abstraída, e reutilizadas em diversas partes do seu projeto. 

 

Portanto, estruturas aninhadas é mais um recurso muito útil, disponível em suas mãos, para que você consiga resolver o seu problema de forma ainda mais eficiente e modularizada.

 

Não entendeu alguma coisa? Deixe ali nos comentários, que eu responderei assim que possível, tudo bem? Até a próxima pessoal.

Outros artigos da série

<< Vetor de Struct
NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Elaine Cecília Gatto
Bacharel em Engenharia de Computação. Mestre em Ciência da Computação. Doutoranda em Ciência da Computação. Co-fundarora e Líder das #GarotasCPBr. Pesquisadora Convidada no Grupo de Pesquisa: "Artes em Tecnologias Emergentes" do Programa de Pós Graduação em Design na UNESP Campus Bauru. Cantora, Docente no Magistério Superior, Geek, Nerd, Otaku e Gamer. Apaixonada por Michael Jackson, Macross, Rocky Balboa, Séries, Filmes, Cervejas e Vinhos. Mais informações sobre mim você encontra em: http://lattes.cnpq.br/8559022477811603.

5
Deixe um comentário

avatar
 
3 Comment threads
2 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
4 Comment authors
Alexandro Vieira FerreiraElaine Cecília GattoLaercio BarbosaWillians de Almeida Vieira Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Alexandro Vieira Ferreira
Visitante
Alexandro Vieira Ferreira

Olá, eu preciso armazenar 10 nomes de pessoas 10 vezes.
Por exemplo grupo1 com 10 nomes
grupo2 com 10 nomes...
Eu teria que criar 10 structs?

Laercio Barbosa
Visitante
Laercio Barbosa

Olá, Elaine.
Não ficou claro, para mim, a utilidade da primeira forma de estruturas aninhadas. Já a segunda forma é, para mim, um tanto óbvia. Poderia citar exemplos onde a aplicação da primeira forma seja útil?

Obrigado

Willians de Almeida Vieira
Visitante
Willians De Almeida

Excelente artigo.