Cooler_

self-referential structures

May 11th, 2014
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.56 KB | None | 0 0
  1. Autor: VoidPointer (Diego Rocha)
  2.  
  3. self-referential structures são estruturas que contém um ponteiro para uma estrutura do mesmo tipo, exemplo:
  4.  
  5.  
  6.   struct words {
  7.         char word[100];
  8.         struct words *next;
  9.     };
  10.  
  11. Repare que o *next é um ponteiro para uma estrutura do mesmo tipo que words, e isso é totalmente válido em C, essa técnica é muito útil para armazenar sequências de dados, como listas, queues, stacks e arvores de dados por exemplo, vamos supor que você queira criar uma lista de palavras, primeiro precisamos de uma estrutura que aponte para uma estrutura do mesmo tipo (no nosso caso a struct words), para assim criar a sequência de dados, e precisaremos também de algumas funções para manipular essa estrutura, vamos criar uma função para adicionar palavras no final dessa estrutura, a função seria basicamente assim:
  12.  
  13.     struct words *add_word( struct words *w, char *word )
  14.     {
  15.         /* verificamos se a estrutura esta livre para receber uma palavra */
  16.         if (w == NULL) {
  17.             w = (struct words*)malloc(sizeof(struct words)); //alocamos memoria para a estrutura
  18.             if (w == NULL)
  19.                 return NULL; //problema ao alocar memoria
  20.  
  21.             (void)strlcpy(w->word, word, sizeof(w->word)); //copiamos word para w->word
  22.             w->next = NULL;
  23.         }else
  24.             w->next = add_word(w->next, word); //chamada recursiva
  25.         return w; //retornamos w
  26.     }
  27.  
  28. Repare que usamos uma função recursiva para “caminhar” pela estrutura ate o ponto livre para receber uma palavra, agora vamos fazer uma função para imprimir todas as palavras da lista, poderíamos usar recursao também, mais vou usar outro metódo para fazer isso, vou usar o for para “caminhar” pela estrutura,
  29.  
  30.  
  31.    
  32.  
  33.     void printf_words( struct words *w )
  34.     {
  35.         struct words *pw; //criamos um ponteiro do tipo words para apontar para w
  36.         for( pw = w; pw != NULL; pw = pw->next ) //"caminhamos" pela estrutura w
  37.             (void)fprintf( stdout, "%s\n", pw->word ); //imprimos a palavra
  38.         fflush( stdout );
  39.         return;
  40.     }
  41.  
  42. bom agora criamos o main e testamos,
  43.  
  44.  
  45.    
  46.  
  47.   int main( int argc, char *argv[] )
  48.     {
  49.         struct words *glb_w = NULL;//estrutura principal
  50.         /* adicionamos palavras a lista */
  51.         glb_w = add_word( glb_w, "teste1" );
  52.         glb_w = add_word( glb_w, "teste2" );
  53.         glb_w = add_word( glb_w, "teste3" );
  54.         glb_w = add_word( glb_w, "teste4" );
  55.         glb_w = add_word( glb_w, "teste5" );
  56.         /* imprimimos as palavras */
  57.         printf_words( glb_w );
  58.         return 0;
  59.     }
  60.  
  61. e compilamos com gcc -Wall words.c -o words agora executamos com ./words
  62.  
  63. [diego@blackbird ~]$ ./words
  64. teste1
  65. teste2
  66. teste3
  67. teste4
  68. teste5
  69.  
  70. codigo completo:
  71.  
  72.  
  73.    
  74.  
  75. #include <stdio.h>
  76.     #include <stdlib.h>
  77.     #include <string.h>
  78.  
  79.     struct words {
  80.         char word[100];
  81.         struct words *next;
  82.     };
  83.  
  84.     struct words *add_word( struct words *w, char *word )
  85.     {
  86.         if( w == NULL ) /* verificamos se a estrutura esta livre para receber uma palavra */
  87.         {
  88.             w = (struct words*)malloc(sizeof(struct words)); //alocamos memoria para a estrutura
  89.             if( w == NULL )
  90.                 return NULL; //problema ao alocar memoria
  91.             (void)strlcpy(w->word, word, sizeof(w->word)); //copiamos word para w->word
  92.             w->next = NULL; //w->next aponta para nada
  93.         }else
  94.             w->next = add_word( w->next, word ); //chamada recursiva
  95.         return w; //retornamos w
  96.     }
  97.  
  98.     void printf_words( struct words *w )
  99.     {
  100.         struct words *pw; //criamos um ponteiro do tipo words para apontar para w
  101.         for( pw = w; pw != NULL; pw = pw->next ) //"caminhamos" pela estrutura w
  102.             (void)fprintf( stdout, "%s\n", pw->word ); //imprimos a palavra
  103.         fflush( stdout );
  104.         return;
  105.     }
  106.  
  107.     int main( int argc, char *argv[] )
  108.     {
  109.         struct words *glb_w = NULL;//estrutura principal
  110.         /* adicionamos palavras a estrutura */
  111.         glb_w = add_word( glb_w, "teste1" );
  112.         glb_w = add_word( glb_w, "teste2" );
  113.         glb_w = add_word( glb_w, "teste3" );
  114.         glb_w = add_word( glb_w, "teste4" );
  115.         glb_w = add_word( glb_w, "teste5" );
  116.         /* imprimimos as palavras */
  117.         printf_words( glb_w );
  118.         return 0;
  119.     }
  120.  
  121. Pelo nosso amigo voidpointer artigo original –> http://blue.kracknet.net/~voidpointer/articles/self_referential_struct.html
  122. encontre voidpointer no servidor do IRC irc.freenode.net no canal openbsd-br…
Advertisement
Add Comment
Please, Sign In to add comment