Projeto de Algoritmos

Registros e Structs

Um registro (= record) é uma coleção de várias variáveis, possivelmente de tipos diferentes. Na linguagem C, registros são conhecidos como structs (abreviatura de structures).

Definição e manipulação de structs

O exemplo abaixo declara um registro x com três campos (ou membros) inteiros:

   struct {
      int dia;
      int mes;
      int ano; 
   } x; 

É uma boa ideia dar um nome ao tipo de registro. No nosso exemplo, dma parece um nome apropriado:

   struct dma {
      int dia;
      int mes;
      int ano; 
   }; 
   struct dma x;  /* um registro x do tipo dma */
   struct dma y;  /* um registro y do tipo dma */

É fácil atribuir valores aos campos de um registro:

   x.dia = 31;
   x.mes = 8;
   x.ano = 1998;

 

Exemplo: A função abaixo recebe a data de início de um evento e a duração do evento em dias. Ela devolve a data de fim do evento.

struct dma fim_evento (struct dma datainicio, int duracao) {
   struct dma datafim;
   . . .
   . . .
   datafim.dia = ...
   datafim.mes = ...
   datafim.ano = ...
   return datafim;
}

O código foi omitido porque é um tanto enfadonho: deve levar em conta a existência de meses com 31 dias, de meses com 30 dias, com 29 dias etc.   Eis como essa função poderia ser usada:

int main( void) {
   struct dma a, b;
   int d;
   scanf( "%d %d %d", &a.dia, &a.mes, &a.ano);
   scanf( "%d", &d);
   b = fim_evento( a, d);
   printf( "%d %d %d\n", b.dia, b.mes, b.ano);
   return EXIT_SUCCESS;
}

Exercícios

  1. Complete o código da função fim_evento acima.
  2. Escreva uma função que receba dois structs do tipo dma, cada um representando uma data válida, e devolva o número de dias que decorreram entre as duas datas.
  3. Escreva uma função que receba um número inteiro que representa um intervalo de tempo medido em minutos e devolva o correspondente número de horas e minutos (por exemplo, converte 131 minutos em 2 horas e 11 minutos). Use uma struct como a seguinte:
    struct hm {
       int horas;
       int minutos;
    };
    

Structs e ponteiros

Cada registro tem um endereço na memória do computador.  (Você pode imaginar que o endereço de um registro é o endereço de seu primeiro campo, mas essa detalhe é irrelevante.)  É muito comum usar um ponteiro para guardar o endereço de um registro. Dizemos que um tal ponteiro aponta para o registro.  Por exemplo,

   struct dma *p;   /* p é um ponteiro para registros dma */
   struct dma  x;
   p = &x;          /* agora p aponta para x */
   (*p).dia = 31;   /* mesmo efeito que x.dia = 31 */

[Cuidado! A expressão  *p.dia,  que equivale a  *(p.dia),  tem significado muito diferente de  (*p).dia .]   A expressão  p->mes  é uma abreviatura muito útil para a expressão (*p).mes :

   p->mes = 8;      /* mesmo efeito que (*p).mes = 8 */
   p->ano = 1998;

Registros podem ser tratados como um novo tipo-de-dados. Por exemplo,

   typedef struct dma data; 
   data  x;  
   data *p;
   p = &x;

Exercícios

  1. Defina um registro empregado para guardar os dados (nome, sobrenome, data de nascimento, RG, data de admissão, salário) de um empregado de sua empresa.  Defina um vetor de empregados para armazenar todos os empregados de sua empresa.
  2. Um racional é qualquer número da forma p/q, sendo p inteiro e q inteiro não nulo.  É conveniente representar um racional por um registro:
    typedef struct {
       int p, q;
    } racional;
    

    Vamos convencionar que o campo q de todo racional é estritamente positivo e que o máximo divisor comum dos campos p e q é 1.  Escreva

    • uma função reduz que receba inteiros a e b e devolva o racional que representa a/b;
    • uma função neg que receba um racional x e devolva o racional −x;
    • uma função soma que receba racionais x e y e devolva o racional que representa a soma de xy;
    • uma função mult que receba racionais x e y e devolva o racional que representa o produto de x por y;
    • uma função div que receba racionais x e y e devolva o racional que representa o quociente de x por y;

 

 


URL of this site: www.ime.usp.br/~pf/algoritmos/
Last modified: Thu Jan 17 06:58:59 BRST 2013
Paulo Feofiloff
IME-USP

Valid HTML 4.01 Transitional    Valid CSS!