Structs dinâmicos com UNION

Publicado por Thiago 10/04/2008

[ Hits: 9.552 ]

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

Validador de Cartão de Credito

Tabuada em C

Encontrar string em ficheiro

SIMPCalc

Manipuladores de bases numéricas


  

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