Um registro
(= record)
é um pacote
de variáveis,
possivelmente de tipos diferentes.
Cada variável é um campo (= field) do registro.
Na linguagem C,
registros são conhecidos como structs
(o nome é uma abreviatura de structure).
O seguinte exemplo declara (ou seja, cria) um registro x com três campos que pode ser usado para armazenar datas:
struct { int dia; int mes; int ano; } x;
É uma boa ideia dar um nome à classe de todos os registros de um mesmo tipo. No nosso exemplo, acho que dma é 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
Para se referir a um campo de um registro, basta escrever o nome do registro e o nome do campo separados por um ponto:
x.dia = 31; x.mes = 12; x.ano = 2018;
Registros podem ser tratados como
um novo tipo-de-dados.
Depois da seguinte definição, por exemplo,
poderemos passar a dizer data
no lugar de struct dma
:
typedef struct dma data; data x, y;
Exemplo. A seguinte função calcula a data de fim de um evento ao receber a data de início do evento e a duração do evento em dias.
data fimEvento (data inicio, int duracao) { data fim; . . . . . . fim.dia = ... fim.mes = ... fim.ano = ... return fim; }
O código foi omitido porque é um tanto enfadonho, uma vez que deve levar em conta o número de dias em diferentes meses e os anos bissextos. Eis como a função fimEvento poderia ser usada:
int main (void) {
data a, b;
scanf ("%d %d %d", &a.dia, &a.mes, &a.ano);
// &a.dia significa &(a.dia)
int dura;
scanf ("%d", &dura);
b = fimEvento (a, dura);
printf ("%d %d %d\n", b.dia, b.mes, b.ano);
return EXIT_SUCCESS;
}
struct hm { int horas, minutos; };
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.) O endereço de um registro pode ser armazenado em um ponteiro. Dizemos que um tal ponteiro aponta para o registro. Por exemplo,
data *p; // p é um ponteiro para registros dma data x; p = &x; // agora p aponta para x (*p).dia = 31; // mesmo efeito que x.dia = 31
A expressão p->dia é uma abreviatura muito útil de (*p).dia . Portanto, a última linha do código acima pode ser escrita assim:
p->dia = 31;
A propósito, o significado de (*p).dia é muito diferente do significado de *(p.dia) , que equivale a *p.dia graças às regras de precedência.
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 funções
Resposta: Sim. Você pode escrever
typedef struct dma dma; dma x, y;