Tutoriais e Programação
Linguagem C - Estruturas e Uniões
Sex 28 Nov 2008 12:09 |
- Detalhes
- Categoria: Linguagem C
- Atualização: Sexta, 28 Novembro 2008 13:16
- Autor: vovó Vicki
- Acessos: 20210
Estruturas são peças contíguas de armazenamento que contém vários tipos simples agrupados numa entidade. Pode-se fazer uma analogia com uma estante de livros: se tivermos uma estante para 50 livros, o espaço para cada um dos 50 livros está garantido, esteja ou não na estante. Se fixarmos (melhor ainda, se identificarmos com uma etiqueta) onde cada um dos livros deve ser armazenado, sempre saberemos onde encontrar e onde guardar cada um dos livros. A estante funciona como estrutura, os locais como campos e os livros como dados.
Criando uma estrutura
Estruturas são manifestadas através da palavra-chave struct seguida pelo nome da estrutura e por uma área delimitada por chaves que contém os campos. Os campos também são manifestados da forma habitual,
Lembre-se de que o manifesto de uma variável do tipo estrutura é apenas um aviso para o pre-processador (se tiver dúvidas, reveja Bibliotecas e Tipos) - a entidade existe, mas não possui dados. Usando esta nova entidade, que na verdade é um novo tipo criado por nós, podemos manifestar ou definir variáveis ou objetos deste novo tipo:
Aqui definimos a variável coordTela, que é uma estrutura do tipo coordenadas, que possui dois campos de inteiros, o "x" e o "y". Aproveitamos o embalo e indicamos os valores 35 e 98 (observe que os valores estão entre chaves). O pre-processador, quando processar esta definição, atribuirá o valor 35 para o campo x e o valor 98 para o campo y.
Acessando dados
Existem duas formas de acessar dados armazenados numa estrutura. Para obter diretamente o valor de um campo, a forma é
Recursividade
Estruturas podem ser recursivas, isto é, podem conter ponteiros para si mesmas - o que é o mesmo que dizer que podem "se chamar". Esta peculiaridade ajuda a definir estruturas do tipo lista:
Aqui definimos uma estrutura que contém um ponteiro para a mesma estrutura no primeiro campo e um inteiro no segundo campo. Mas ATENÇÃO: estamos fazendo o manifesto de um ponteiro para uma outra estrutura idêntica, NÃO a própria. Uma estrutura não pode conter ela mesma!
Listas duplas podem ser manifestadas da forma mostrada abaixo, com dois ponteiros: um para o próximo elemento da lista (*Next) e um para o elemento anterior (*Previous).
Campo de bits
Um manifesto especial que só pode ser usado em estruturas é o campo de bits. Com ele pode-se especificar um campo da estrutura com um certo número de bits. Veja o exemplo:
Esta estrutura possui três campos. Os dois primeiros são campos de 1 bit, isto é, só podem conter um valor lógico (ou booleano) de 0 ou 1. O terceiro campo pode armazenar um inteiro de 5 bits, ou seja, números de 0 a 31.
Estruturas aninhadas
Estruturas podem conter outras estruturas ou tipos. Por exemplo, tendo manifestado a estrutura coordenadas (veja acima), é possível manifestar uma nova estrutura que a contenha:
Esta estrutura contém uma estrutura "coordenadas". Para acessar o campo "x" da estrutura coordTela contida na estrutura Ponto, basta referenciá-lo com:
Estruturas em arrays
Arrays (ou matrizes) podem conter estruturas. Abaixo está o manifesto de um array com 25 estruturas do tipo coordenadas:
Lembre-se que os elementos dos arrays são numerados a partir de 0 (zero). Neste caso, os elementos são numerados de 0 a 24, perfazendo 25 elementos. Se quisermos acessar o "x" do sexto elemento, escrevemos:
Um bom exemplo de uso
O número de estruturas possíveis é praticamente infinito. As estruturas podem ser modeladas de acordo com a necessidade e o projeto. De qualquer forma, são extremamente versáteis e permitem atribuir, obter e modificar dados com facilidade. Veja um exemplo prático, como se fosse um registro de uma tabela de dados:
Esta estrutura, de nome mailsRecebidos, é composta pelos seguintes campos: um número inteiro para armazenar a identificação do email (IDmail), um time_t (tipo time) para armazendar a data e a hora (data_hora) e mais quatro campos com endereços apontando para o início de uma string de caracteres.
Uniões
Sabemos que um número inteiro (int), no lcc-win32, possui o tamanho 4 e que o um número de precisão dupla (double) ocupa 8 bits. Para poder acomodar qualquer um dos dois valores declarados, é claro que esta união vai reservar 8 bits. Num dado momento, apenas um dos números poderá ser armazenado, nunca os dois juntos. E qual é a vantagem que Maria leva?
Bem, uma união funciona mais ou menos como um rascunho ocupando um número fixo de bits na memória. Imagine o seguinte: num determinado programa manifestamos um montão de estruturas ligeiramente diferentes que nunca serão usadas simultaneamente. No momento em que forem definidas e receberem valores, cada uma delas ocupará determinado espaço na memória. Quando tivermos usado cada uma delas, uma grande área da memória estará alocada, mas apenas uma pequena porção, referente à estrutura em uso no momento, estará sendo utilizada.
É aí que está o pulo do gato: empacotamos as estruturas numa união. A união reserva um espaço correspondente à maior estrutura da lista e o resultado é que trocamos a soma dos espaços necessários para cada estrutura pelo espaço necessário para a maior delas. Cada vez que quisermos trabalhar com uma das estruturas, podemos copiar a mesma para a união porque temos a certeza de que haverá espaço suficiente para contê-la.
Resumindo: uniões são uma forma prática e elegante de economizar memória!
Observações da vó
Estruturas são excelentes para manter a ordem e tornarem o código fonte legível. Práticas, rápidas e eficientes, não é à toa que são utilizadas com frequência em aplicativos e sistemas operacionais que dependam de desempenho e de confiabilidade.
Por outro lado, as uniões são as "muquiranas" que garantem um melhor aproveitamento da memória. Formam uma dupla dinâmica com qualquer tipo de variável, inclusive com estruturas, controlando o apetite voraz de aplicativos extensos ou de sistemas operacionais.
Mas, apesar de tantos elogios, o Ministério da Saúde adverte: use com moderação