Structs dinâmicos com UNION

Publicado por Thiago 10/04/2008

[ Hits: 9.681 ]

Download union.c




Após uma longa temporada de abstinência estou de volta :)

Por favor leiam. Os comentários são de suma importância.

  



Esconder código-fonte

/*
 *  LEIA PARA NAO CHORAR DEPOIS!
 *
 * Autor: thiagoamm
 * Data: 29/02/2008
 *
 * Objetivo: Aplicar o conceito de union utilizado na programacao C
 *           e perceber o dinamismo que proporciona no desenvolvimento
 *           da aplicacao.
 *
 * OBSERVACOES: Este programa foi implementado na Arquitetura Win32 mais 
 *              precisamente no Windows XP meus amigos.
 *              Para que ele funcione no Linux substituam as chamadas de 
 *              sistema system ("cls") por system ("clear"), fflush (stdin)
 *              por __fpurge (stdin).
 *              Pode ocorrer algum problema quanto a resolução.
 *              Os ortodoxos que me perdoem mas nao tive a menor disposicao
 *              de portar este codigo para o Linux apos tê-lo concluído.
 *              Deixo a tarefa nas mãos de vcs.
 *              O que vale e a intencao de compartilhar o conhecimento.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define FISICA 0
#define JURIDICA 1
#define LIM_MIN 1
#define LIM_MAX 100

/*
 * Uma união é uma estrutura composta por uma parte fixa e uma parte variável.
 * As variáveis estrutura na Linguagem C (struct) especificam variáveis com
 * membros fixos que obedecem a um único formato.
 * Uniões (unions) podem ser vistas com um conjunto de mapas que determinam
 * diferentes métodos de interpretação para uma determinada região da memória.
 *
 * O compilador aloca espaço suficiente para conter o maior membro da união (union).
 * Com o uso de union é possível especificar qual a estrutura mais apropriada a ser 
 * manipulada em um dado instante.
 *
 * Os diferentes membros de uma union sobrepõem-se entre si.
 * Ou seja, só pode existir um único membro da união (union) em um dados instante.
 *
 */

typedef struct
{
   // Parte fixa da União.
   char nome[51];
   char endereco[101];
   int tipo; // Fisica = 0, Jurídica = 1.
   
   union  // Inicio da parte variável da União.
   {
        // Possiveis representações de uma pessoa no direito
        struct
        {
           char carac[15]; // 14 caracteres para numeros e sinais e mais um para o {FONTE}.
           int num[11];                   
        } cpf;
        
        struct
        {
           char carac[19];
           int num[14]; 
        } cnpj;
   };
} PESSOA_DIREITO;


int  lerDados      (PESSOA_DIREITO pessoasDireito[]);
void imprimirDados (PESSOA_DIREITO pessoasDireito[]);
void menu (void);
void inicializarVetorEstruturas (PESSOA_DIREITO vetor[]);


int main (void)
{ 
   menu();
   system ("cls");      
   return 0;
}

int lerDados (PESSOA_DIREITO pessoasDireito[])
{
   int register i; // indice do vetor (contador do loop)
   int qtd;
   
   system ("cls");
   printf ("\nInforme a quantidade de Pessoas de Direito a serem cadastradas:\t");
   scanf  ("%d", &qtd);
   
   if (qtd < LIM_MIN)
   {
      printf ("\n\a-> Quantidade informada menor que o LIMITE MINIMO\n");
      getchar();
      getchar();
   }   
   else if (qtd > LIM_MAX)
   {
      printf ("\n\a-> Quantidade informada maior que o LIMITE MAXIMO\n");
      getchar();
      getchar();
   }
   else
   {
      for (i = 0; i < qtd; i++)
      {
         system ("cls");
         printf ("\n\t\t\t\tINFORME OS DADOS\n\n\n");
      
         printf ("\nNome:\t\t");
         fflush (stdin);
         fgets  (pessoasDireito[i].nome, 51, stdin);

         printf ("\nEndereco:\t");
         fflush (stdin);
         fgets  (pessoasDireito[i].endereco, 101, stdin);
      
         printf ("\nTipo-pessoa:\t");
         scanf  ("%d", &pessoasDireito[i].tipo);
    
         switch (pessoasDireito[i].tipo)
         {
            case 0:
               printf ("\nCPF:\t\t");
               fflush (stdin);
               fgets  (pessoasDireito[i].cpf.carac, 15, stdin); 
            break;
      
            case 1:
               printf ("\nCNPJ:\t\t");
               fflush (stdin);
               fgets  (pessoasDireito[i].cnpj.carac, 19, stdin);
            break;
      
            default:
               printf ("\nTipo inválido!\n");
        }          
        getchar(); // para dar uma pausa.       
      }
   } 
   return qtd;   
}

void imprimirDados (PESSOA_DIREITO pessoasDireito[])
{
   int register i;
   int qtd;
      
   system ("cls");
   printf ("\nInforme a quantidade de Pessoas de direito a terem seus dados impressos: ");
   scanf  ("%d", &qtd);
   
   if (qtd < LIM_MIN)
   {
      printf ("\n\a-> Quantidade informada menor que o LIMITE MINIMO\n");
      getchar();
      getchar();
   }   
   else if (qtd > LIM_MAX)
   {
      printf ("\n\a-> Quantidade informada maior que o LIMITE MAXIMO\n");
      getchar();
      getchar();
   }
   else
   {
      system ("cls");
   
      for (i = 0; i < qtd; i++)
      {
          printf ("\nREGISTRO: %d\n", i);
          
          if ( pessoasDireito[i].tipo == -1)
             continue; // desvia para proxima iteracao
             
          printf ("\n_____________________________________________________________________\n");
          printf ("\nNome:\t\t%s",       pessoasDireito[i].nome);
          printf ("\nEndereco:\t%s",     pessoasDireito[i].endereco);
          printf ("\nTipo:\t\t%d\t-",    pessoasDireito[i].tipo);
       
          switch (pessoasDireito[i].tipo)
          {
            case 0:
               printf ("\tPESSOA FISICA\n");
               printf ("\nCPF:\t\t%s",  pessoasDireito[i].cpf.carac);
            break;
          
            case 1:
               printf ("\tPESSOA JURIDICA\n");
               printf ("\nCNPJ:\t\t%s", pessoasDireito[i].cnpj.carac);
            break;
          
            default:
               printf ("");
          }
          printf ("\n_____________________________________________________________________\n");
      } 
   }   
   getchar();
   getchar();
}


void menu (void)
{
   int opcao;
   int sair = 0;
   int register i;
   
   PESSOA_DIREITO pessoasDireito[LIM_MAX];      
   
   // Inicializando estruturas de vetor
   inicializarVetorEstruturas (pessoasDireito);
   
   do
   {
      system ("cls");
      printf ("\n\t-------------------------------------------------------------------");
      printf ("\n\t|\t\t\t    M   E   N   U \t\t\t  |");      
      printf ("\n\t-------------------------------------------------------------------");
      printf ("\n\t*******************************************************************");
      printf ("\n\t*\t\t\t\t\t\t\t\t  *");
      printf ("\n\t*\t\t(1) Cadastro de Pessoas de Direito\t\t  *");
      printf ("\n\t*\t\t\t\t\t\t\t\t  *");
      printf ("\n\t*\t\t(2) Imprimir dados de Pessoas de Direito\t  *");    
      printf ("\n\t*\t\t\t\t\t\t\t\t  *");
      printf ("\n\t*\t\t(3) Sair\t\t\t\t\t  *");
      printf ("\n\t*\t\t\t\t\t\t\t\t  *");
      printf ("\n\t*******************************************************************\n");
   
      printf ("\n\n\n\tOpcao:\t");
      scanf  ("%d", &opcao);
      
      switch (opcao)
      {
         case 1:
            lerDados (pessoasDireito);              
         break;
      
         case 2:
            imprimirDados (pessoasDireito);           
         break;
      
         case 3:
            sair = 1;
            system ("cls");            
         break;
      
         default:
            printf ("\nOpcao invalida!\n");
      }
   } while (sair != 1);
}


void inicializarVetorEstruturas (PESSOA_DIREITO vetor[])
{
   int register i; // variavel armazenada em registrado, ganho de performance
   
   /*
    * Compiladores C padrao nao inicializam os membros da estrutura.
    * Na rotina de impressao dos dados poderia pedir para imprimir as 100
    * estruturas sem ter inicializado nenhuma delas com dados.
    * Isso iria poluir a tela do pc com sujeira na memória (dados não compatíveis
    * com o contexto do programa que estamos executando).
    * Alguns podem pensar em implementar uma comparação usando uma estrutura condicional
    *
    * if ( strcmp (pessoasDireito[i].nome, "") == 0)
    *   continue
    *
    * ou seja se alguma das estruturas possuir nome igual a vazio passa para a proxima
    * iteracao (executa a proxima instrucao) mas isso não funciona de todo pois
    * cada posicao do vetor (ou seja cada estrutura) aponta para uma área da memória
    * que não foi sobrescrita (inicializada) e esta pode conter algum dado diferente
    * de vazio.
    * A melhor forma que encontrei foi inicializar o membro tipo com -1.
    * O programador está garantindo que o valor está lá.
    */
   for (i = 0; i < LIM_MAX; i++)
      vetor[i].tipo = -1;
}

Scripts recomendados

indice.c - Indice em strings

Contador de palavras, linhas e caracteres de um arquivo texto

Quadrado de um número

[C] Fibonacci

Conta e substitui caracteres de uma frase


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts