terça-feira, 10 de maio de 2011

Ponteiros para estruturas [C]

  Ponteiros para estruturas

É possível criar um ponteiro para virtualmente qualquer tipo em C, incluindo tipos definidos pelo usuário. É extremamente comum criar ponteiros para estruturas. Um exemplo é mostrado abaixo:
  typedef struct
  {
   char nome[21]; 
  char cidade[21];  
  char estado[3];
  } Rec;
  typedef Rec *RecPointer;
  
  RecPointer r;
  r = (RecPointer)malloc(sizeof(Rec));  

O pointeiro r é um ponteiro de estrutura. Observe que, como r é um ponteiro, ele retira 4 bytes de memória como qualquer outro ponteiro. Porém, a instrução malloc aloca 45 bytes de memória da pilha. *r é uma estrutura como qualquer estrutura de tipo Rec. A codificação seguinte mostra os usos freqüentes de variável de ponteiro:
  strcpy((*r).nome, "Leigh");
  strcpy((*r).cidade, "Raleigh"); 
  strcpy((*r).estado, "NC");
  printf("%s\n", (*r).cidade);
  free(r);  
Você lida com *r como lida com uma variável normal de estrutura, porém precisa ter cuidado com a precedência de operadores em C. Se deixasse de usar parênteses ao redor de *r, o código não compilaria, pois o operador "." tem maior precedência sobre o operador "*". Por se tornar tedioso digitar tantos parênteses ao trabalhar com ponteiros em estrutura, o C inclui uma anotação de taquigrafia que faz exatamente a mesma coisa:
  strcpy(r->nome, "Leigh");  
A notação r-> é equivalente ao (*r)., mas tem 2 caracteres a menos.
Ponteiros de matrizes
Também é possível criar ponteiros para matrizes:
int *p;
   int i;  


   p = (int *)malloc(sizeof(int[10]));  
   for (i=0; i<10; i++) 
     p[i] = 0;
   free(p);  
ou:
     int *p;  
     int i;  
   p = (int *)malloc(sizeof(int[10]));  
   for (i=0; i<10; i++)  
          *(p+i) = 0;
   free(p);  
Observe que ao criar um ponteiro para uma matriz de inteiros, você só precisa criar um ponteiro normal para int. A chamada para malloc aloca uma matriz de qualquer tamanho desejável e o ponteiro aponta para o primeiro elemento daquela matriz. Você pode indexar pela matriz apontada por p usando a indexação de matriz normal ou pode fazer isso usando a aritmética de ponteiros. A linguagem C vê ambas as formas como equivalentes.
Esta técnica particular é extremamente útil ao se trabalhar com strings. Ela permite alocar armazenamento suficiente para manter exatamente um string de determinado tamanho.
Matrizes de ponteiros
Às vezes, pode-se economizar bastante espaço ou resolver problemas de memória declarando uma matriz de ponteiros. No código de exemplo abaixo, uma matriz de 10 ponteiros de estruturas é declarada, em vez de declarar uma matriz de estruturas. Em vez disso, se uma matriz de estruturas tivesse sido criada, 243 * 10 = 2.430 bytes seriam necessários para a matriz. Usar a matriz de ponteiros permite que a matriz ocupe o menor espaço possível até que os registros reais sejam alocados com as instruções malloc. O código abaixo simplesmente aloca um registro, coloca um valor e descarta o registro para demonstrar o processo:
   typedef struct
   {  
  char s1[81];
    char s2[81];  
      char s3[81];
   } Rec;  
    Rec *a[10];
    
   a[0] = (Rec *)malloc(sizeof(Rec));
   strcpy(a[0]->s1, "olá"); 
  free(a[0]); 

Estruturas contendo ponteiros
As estruturas podem conter ponteiros, como mostrado abaixo:
     typedef struct  
     {  
       char nome[21];
         char cidade[21];
         char telefone[21]; 
        char *comentario;   
     } Addr;
     Addr s; 
     char comm[100];

     gets(s.nome, 20);  
     gets(s.cidade, 20);  
     gets(s.telefone, 20); 
     gets(com., 100);   
     s.comentário =       
     (char *)malloc(sizeof(char[strlen(comm)+1]));  
     strcpy(s.comentario, com.);  



Esta técnica é útil quando apenas alguns registros realmente contêm um comentário no campo de comentário. Se não houver nenhum comentário para o registro, então o campo consiste em apenas um ponteiro (4 bytes). Depois, estes registros que têm um comentário alocam exatamente o espaço necessário para manter a string de caracteres do comentário, com base na extensão do string digitada pelo usuário.

Nenhum comentário:

Postar um comentário