terça-feira, 31 de julho de 2012

Tipos de dados estruturados


Introdução

Até o presente instante, nós definimos dados do tipo simples ou não estruturados, como por exemplo: Byte, Integer, Real, Char e Boolean. No entanto, existem outros tipos de dados chamados complexos ou estruturados, String é um deles. Nós já falamos sobre o tipo de dado estruturado String, por ser extremamente utilizado como já salientamos antes. Mas o Turbo Pascal possui outros tipos de estruturas, a saber:

            - Array
            - Record
            - Set
            - File
            - String ( já visto )

O tipo file refere-se a arquivos de discos e será amplamente estudado num capítulo à parte. Os demais serão vistos neste capítulo.

Array

Imagine que nós precisemos declarar 100 variáveis do tipo integer, isso poderia ser feito da seguinte forma:

        Var i1,i2,i3,i4,...,i100 : Integer;

Embora isso pareça uma brincadeira (de mal gosto), é possível. Mas podemos também dizer que é um grande incômodo. E se além dessas 100 variáveis, precisarmos também 1000 do tipo Char ou 2000 ou ... . Como podemos ver, as coisas podem se complicar. Mas  para  quem  acessa BBS, coisa de louco, então o cara pode achar MUITO LEGAL. (:-))

Arrays unidimensionais

Turbo Pascal nos fornece um tipo de dado estruturado chamado Array, que nos permite criar um grande número de variáveis de determinado tipo,sem os inconvenientes anteriores.

Exemplo 1:

    Type Arranjo = Array[1..100] of Integer;

    Var  i : Arranjo;

    ou

    Var i : Array[1..100] of Integer;
Após a declaração acima, teríamos definidas 100 variáveis do tipo Integer, cujos nomes seriam:

            i[1] - i[2] - i[3] - . . . - i[100]

Exemplo 2:

    Type
      faixa   = 1..2000;
      Arranjo = Array[faixa] Of Char;

    Var
      Arranjo_simples : Arranjo;

Após as declarações acima, teríamos definidas 2000 variáveis do tipo char com o nome Arranjo_simples.

Exemplos:

    Program Exemplo_1;
    Uses Crt;

{Lê 10 números inteiros do teclado e os escreve na tela ao contrário do que foram lidos}

    Type faixa   = 1..10;
         arranjo = Array[faixa] Of Integer;
    Var  a : arranjo;
         i : Integer;
    Begin
       ClrScr;
       For i:=1 to 10 do
          Begin
             Write('a[',i:2,'] = ');
             Readln(a[i]);
          End;
       ClrScr;
       For i:=10 downto 1 do writeln(a[i]);
    End.

    Program Exemplo_2;
    Uses CRT;

{Programa que lê no máximo 100 números reais do teclado e os coloca em ordem crescente}

    Const Num_max = 100;
    Type  faixa   = 1..Num_max;
          arranjo = Array[faixa] of Real;
    Var   i,j,n : Integer;
          a     : arranjo;
          z     : Real;
    Begin
       ClrScr;
       Writeln('Ordenação de números lidos do teclado':40+19);
                                {escreve no  meio da linha}
       Writeln;Writeln; { pula duas linhas }
       n:=0;
       Writeln('digite um no. menor que 0 para terminar':40+19);
       Writeln;Writeln;
       Repeat
          n:=n+1;
          Write('a[',n:3,'] = ');
          Readln(a[n]);
       Until (n=Num_max) Or (a[n]<0);
       n:=n-1; { elimina o ultimo no. lido pois e' negativo }
       ClrScr;
       For i:=1 to n-1 Do
          For j:=i+1 to n Do
             If a[i] >= a[j]
                Then Begin
                        z:=a[i];
                        a[i]:=a[j];
                        a[j]:=z;
                     End;
       For i:=1 to n Do Writeln(a[i]:10:2);
    end.

    Program Exemplo_3;
    Uses CRT;

{Programa semelhante ao anterior só que coloca em ordem crescente nomes lidos do teclado}

    Const Num_max = 100;
    Type  faixa   = 1..Num_max;
          nomes   = String[30];
          arranjo = Array[faixa] of nomes;
    Var   i,j,n : Integer;
          a     : arranjo;
          z     : nomes;
    Begin
       ClrScr;
       Writeln('Ordenação de nomes lidos do teclado':40+19);
                                        {escreve no meio da linha}
       Writeln;Writeln; { pula duas linhas }
       n:=0;
       Writeln('digite um nome = a zero para terminar':40+19);
       Writeln;Writeln;
       Repeat
          n:=n+1;
          Write('a[',n:3,'] = ');
          Readln(a[n]);
       Until (n=Num_max) Or (a[n]='0');
       n:=n-1; { elimina o ultimo nome lido pois e' zero }
       ClrScr;
       For i:=1 to n-1 Do
          For j:=i+1 to n Do
             If a[i] >= a[j]
                Then Begin
                        z:=a[i];
                        a[i]:=a[j];
                        a[j]:=z;
                     End;
       For i:=1 to n Do Writeln(a[i]:30);
    end.


    Program Exemplo_4;
    Uses CRT;

{Programa que lê as notas de alunos de uma determinada classe e depois lista os alunos e as respectivas notas menores que 5.0}

    Const
              No_de_alunos = 30;
    Type
              Classe = Array[1..No_de_alunos] Of Real;
    Var
              n : Integer;
              a : Classe;
    Begin
       ClrScr;
       For n:=1 to No_de_alunos Do
          Begin
             Write('Aluno no. ',n:2,' ---> ');
             Readln(a[n]);
          End;
       ClrScr;
       Writeln('Alunos com media menor que 5':40+15);
       Writeln('numero  nota');
       For n:=1 to No_de_alunos Do
          If a[n]<5
             Then Writeln(n:2,a[n]:10:1);
    End.

Arrays Multidimensionais

No item anterior, trabalhamos com Arrays unidimensionais, ou seja, de uma dimensão.  No  entanto, é possível trabalhar com arrays de mais de uma dimensão e nesses casos, eles são chamados de multidimensionais.

    Exemplos:

    Var a : array[1..10,2..5] Of Integer;

Na declaração acima, definimos um Array de 40 elementos chamado 'a'. Ele é constituído de 10 linhas numeradas de 1 a 10 por 4 colunas numeradas de 2 a 5. O acesso a cada elemento é feito da seguinte forma:

    a[1,2]   a[1,3] ...   a[1,5]
    a[2,2]   a[2,3] ...   a[2,5]
    ...      ...    ...   ...
    a[10,2]  a[10,3] ...  a[10,5]

    Poderíamos definir o mesmo array da seguinte forma:

    Var a : array[1..10] of array[2..5] Of Integer;
    Ou da seguinte forma:

    Type b = array[2..5] Of Integer;

    Var a : array[1..10] Of b;

Podemos também definir arrays de maior número de dimensões pelo mesmo processo, exemplo:

    Var a : array[1..5,1..6,1..7] Of Integer;



    Exemplo:

    Program Exemplo;
    Uses CRT;

{Programa Matriz => Tem a finalidade de ler uma matriz do teclado e em seguida multiplicar uma coluna ou linha por uma constante. Neste programa, procurei utilizar o maior número possível de conceitos dados até aqui}

    (* definição das constantes do programa *)

    Const NUM_MAX_COL = 20; (* número máximo de colunas *)
             NUM_MAX_LIN = 10;  (* número máximo de linhas  *)
    Var a           : array[1..NUM_MAX_LIN,1..NUM_MAX_COL] of integer;
        i,j,k,p, nl,nc       : integer;
        lc                     : char;
    Begin
       ClrScr;
           (* lê o número de linhas da matriz *)
       Repeat
          Write('Numero de linhas da matriz ----------> ');
          Readln(nl);
       Until nl<=NUM_MAX_LIN;
           (* lê o número de colunas da matriz *)
       Repeat
          Write('Numero de colunas da matriz ---------> ');
          Readln(nc);
       Until nc<=NUM_MAX_COL;
           (* lê a constante de multiplicaçåo *)
       Write('Constante para multiplicação --------> ');
       Readln(k);
           (* pergunta se é uma coluna ou linha para ser multiplicada *)
       Repeat
          Write('Coluna ou linha para mult. (c/l) ----> ');
          Readln(lc);
       Until (lc='c') Or (lc='l');
           (* pergunta pelo número da coluna ou da linha a ser  multiplicada *)
       If lc='c'
       Then Repeat
               Write('Numero da coluna para a multip. -----> ');
               Readln(p);
            Until p<=nc
       Else Repeat
               Write('Numero da linha para a multip. ------> ');
               Readln(p);
            Until p<=nl;
       Writeln;
       TextBackGround(7);
       TextColor(15+16);
       Gotoxy(24,7);
       Write('Entre com os elementos da matriz');
       textcolor(8);
       For i:=1 to nl do
          for j:=1 to nc do
             Begin
                gotoxy(8*j,i+8);
                Write('+');
             End;
       TextBackGround(0);
       Textcolor(13);
              (* lê os elementos da matriz *)
       For i:=1 to nl do
          for j:=1 to nc do
             Begin
                gotoxy(8*j,i+8);
                Read(a[i,j]);
             End;
             (* faz a multiplicaçåo da coluna ou da linha *)
       if lc='c'
          Then for i:=1 to nl do a[i,p]:=a[i,p]*k
          Else for j:=1 to nc do a[p,j]:=a[p,j]*k;
       TextBackGround(0);
       TextColor(15+16);
       Gotoxy(24,7);
            (* apresenta o resultado final na tela *)
       Write('........Resultado final.........');
       textcolor(13);
       For i:=1 to nl do
          for j:=1 to nc do
             Begin
                gotoxy(8*j,i+8);
                Write(a[i,j]);
             End;
    End.

Tipo Record

Conceito de estrutura heterogênea

Até o presente momento, trabalhamos com estruturas que envolvem dados do mesmo tipo. O tipo Record nos permite criar um tipo de dado que é composto de itens de vários tipos. Estes itens dos quais o tipo Record é formado recebem o nome de campos.
Imaginem que queiramos armazenar os seguintes dados a respeito de uma  pessoa:

                Nome - Idade - Sexo - Altura

Até o momento, não temos nenhum tipo de variável capaz de fazer isso, pois como podemos reparar, os quatros itens são de tipos diferentes, a saber:

            Nome ---> String
            Idade --> Integer
            Sexo ---> Char
            Altura -> Real

Como veremos a seguir, o tipo Record  resolver-nos-á o problema.

Definição de Records

A definição de uma variável do tipo record, começa com a palavra reservada Record, a qual é seguida pelos campos (variáveis) e os seus tipos. A palavra reservada End seguida de um ponto e vírgula, termina a definição do Record.

Exemplo:

    Var Nome_Do_Registro            : Record
                                 Nome   : String[30];
                                 Idade    : Integer;
                                 Sexo     : Char;
                                 Altura   : Real;
                          End;

    OU

    Type Registro = Record
                                 Nome   : String[30];
                                 Idade    : Integer;
                                 Sexo     : Char;
                                 Altura   : Real;
                           End;

    Var Nome_Do_Registro : Registro;

Acesso aos elementos da estrutura

Para acessarmos os elementos da estrutura, ou seja, os campos, nós devemos incluir o nome da variável seguida de um ponto e depois o nome do campo, exemplos:

    Nome_Do_Registro.Altura := 1.78;
    Nome_Do_Registro.Sexo   := 'M';
    Etc...

    Exemplos:

    Program Exemplo_1;
    Uses CRT;

{Lê uma variável do tipo record do teclado e em seguida a mostra no monitor}

    Type Pessoas = Record
                      Nome    : String[30];
                      Idade   : Integer;
                      Sexo    : Char;
                      Altura  : Real;
                   End;
    Var p : Pessoas;
    Begin
       ClrScr;
       Write('Nome ------> ');
       Readln(p.Nome);
       Write('Idade -----> ');
       Readln(p.Idade);
       Write('Sexo ------> ');
       Readln(p.Sexo);
       Write('Altura ----> ');
       Readln(p.Altura);
       Writeln;
       Writeln('Voce digitou os seguintes dados :');
       Writeln;Writeln;
       Writeln(p.nome);
       Writeln(p.idade);
       Writeln(p.sexo);
       Writeln(p.altura:6:2);
    End.

       Podemos também definir arrays de records, vejam o exemplo abaixo:

    Program Exemplo_2;
    Uses CRT;

{Programa para ler dados de no máximo 20 pessoas. Em seguida é feita uma listagem em ordem alfabética pelo nome}

    Label fim;

    Type Pessoas = Record
                      Nome    : String[30];
                      Idade   : Integer;
                      Sexo    : Char;
                      Altura  : Real;
                   End;

    Var p     : array[1..20] of Pessoas;
        i,x,y : Integer;
        s     : Pessoas;
    Begin
       ClrScr;
       i:=0;
       Repeat
          i:=i+1;
          Write('Nome (0=fim) -> ');
          Readln(p[i].Nome);
          if p[i].Nome='0' then goto fim;
          Write('Idade --------> ');
          Readln(p[i].Idade);
          Write('Sexo ---------> ');
          Readln(p[i].Sexo);
          Write('Altura -------> ');
          Readln(p[i].Altura);
          Writeln;
    fim:
       Until ((p[i].Nome='0') or (i=20));
       If i<20 then i:=i-1;
       For x:=1 to i-1 do
          For y:=x+1 to i do
             If ((p[x].nome) >= (p[y].nome))
                then begin
                        s:=p[x];
                        p[x]:=p[y];
                        p[y]:=s;
                     End;
       ClrScr;
       Writeln('NOME':30,'IDADE':6,'SEXO':5,'ALTURA':8);
       For x:=1 to i do
          Writeln(p[x].nome:30,p[x].idade:6,p[x].sexo:5,p[x].altura:8:2);
    End.

Declaração With

Se existe uma série de campos de uma variável do tipo record que será acessada repetidamente, pode ser cansativo ter que escrever o nome da variável na frente do campo diversas vezes. Para resolver o problema, podemos utilizar a declaração With. Sua forma é:

    WITH Variável_do_tipo_record DO comando;

    ou

    WITH Variável_do_tipo_record DO
        Begin
            comando_1;
            comando_2;
            . . .
        End;

    Exemplo:

    Program Exemplo_1;
    Uses CRT;

{ lê uma variável tipo record e em seguida a mostra }

    Type Pessoas = Record
                      Nome    : String[30];
                      Idade   : Integer;
                      Sexo    : Char;
                      Altura  : Real;
                   End;

    Var p : Pessoas;

    Begin
       ClrScr;
       With p do
          Begin
             Write('Nome ------> ');
             Readln(Nome);
             Write('Idade -----> ');
             Readln(Idade);
             Write('Sexo ------> ');
             Readln(Sexo);
             Write('Altura ----> ');
             Readln(Altura);
             Writeln;
             Writeln('Você digitou os seguintes dados :');
             Writeln;Writeln;
             Writeln(nome);
             Writeln(idade);
             Writeln(sexo);
             Writeln(altura:6:2);
         End;
    End.

Tipo Set

Definição e declaração

Na matemática, usamos uma linguagem não só adequada às suas necessidades, mas também ao estudo de outras ciências. Uma boa parte dessa linguagem vem da teoria de conjuntos.
Em matemática, definimos um conjunto como sendo uma coleção de objetos, nomes, números etc. Chamamos de elementos aos objetos, nomes, números etc. que pertencem a esse conjunto.
Pois bem, na linguagem Pascal, também podemos utilizar estes conceitos. Na linguagem Pascal, um conjunto é uma coleção de elementos semelhantes. O tamanho do conjunto pode ser variável, sendo que no caso específico do Turbo Pascal, o conjunto pode ter no máximo 256 elementos.
Um conjunto pode consistir em zero ou mais elementos do mesmo tipo base que, obrigatoriamente deverá ser um tipo simples, podendo ser qualquer escalar com exceção do REAL.
Em Pascal, os conjuntos têm seus elementos inclusos em colchetes e separados por vírgulas. Podemos ter também a representação da sub-faixa.

    Exemplos:

    [1,3,5,7,9,11,13]       - alguns inteiros
    [3..7]                         - inteiros entre 3 e 7
    [3,4,5,6,7]                 - equivalente  ao anterior
    ['A'..'Z']                      - caracteres alfabéticos maiúsculos
    [gol,passat,fusca]      - marcas de carro
    []                                - conjunto vazio

    Declaração

    A forma geral para definição de conjuntos é:

    Type
        <identificador> = SET OF <tipo base>;

    Exemplos:

    Type
        caracteres        = set of Char;
        letras_maiúsculas = set of 'A'..'Z';
        dígitos           = set of 0..9;
        carros            = set of (fusca,gol,escort,opala);

    Var c       : caracteres;
        letras  : letras_maiúsculas;
        números : dígitos;
        marca   : carros;

                        etc.

Operações em tipos Set

    Atribuição: ( := )

O operador de atribuição é o mesmo utilizado para tipos simples, exemplos:

    c := ['a','e','i','o','u'];
    letras := ['B'..'H'];
    números := [0,3,5];
                             etc.

União: ( + )

O operador união é representado pelo sinal '+'. A união entre dois conjuntos resulta num terceiro conjunto, constituído dos elementos dos dois conjuntos.

Exemplo:

    a := [1,2,3];
    b := [2,3,4,5];
    c := a+b;           resulta  c = [1,2,3,4,5]

Intersecção: ( * )

Representada pelo sinal '*'. A intersecção entre dois conjuntos, resulta num terceiro conjunto, constituído pelos elementos que fazem parte tanto de um como do outro conjunto.
Exemplo:

    a := [1,2,3];
    b := [2,3,4,5];
    c := a*b;           resulta  c = [2,3]

Diferença: ( - )

Representada pelo sinal '-'. Retorna um conjunto, cujos elementos estão num conjunto mas não no outro.

    a := [1,2,3,6];
    b := [2,3,4,5];
    c := a-b;           resulta  c = [1,6]
    c := b-a;           resulta  c = [4,5]

Operadores relacionais:

    a =  b  todos elementos estão em ambos conjuntos
    a <> b  alguns ou todos elementos não estão em ambos conjuntos
    a >= b  todos elementos de b estão em a
    a <= b  todos elementos de a estão em b
    a IN b  a é um elemento do conjunto b

Neste último caso, a deve ser um elemento do mesmo tipo base do conjunto b.

    Exemplos de programas:

    Program Exemplo_1;
    Uses CRT;

{Lê uma tecla e a envia para o monitor até que se digite  'S' ou 's' ou 'N' ou 'n'}

    Var tecla : Char;

    Begin
       ClrScr;
       Repeat
          Read(kbd,tecla);
          Write(tecla);
       Until tecla IN ['s','S','n','N'];
    End.

    Program Exemplo_2;
    Uses CRT;

{lê uma tecla e diz se é número, letra maiúscula ou letra minúscula até que se leia um '?'}

    Type símbolos = Set of Char;

    Var Maiusc, Minusc, Números : símbolos;
        tecla : char;

    Begin
       ClrScr;
       Maiusc  := ['A'..'Z'];
       Minusc  := ['a'..'z'];
       Numeros := ['0'..'9'];
       Repeat
          Read(kbd,tecla);
          If tecla IN Maiusc
             Then Writeln('MAIUSCULA')
             Else if tecla IN minusc
                     Then Writeln('minuscula')
                     else if tecla IN numeros
                             Then Writeln('numero')
                             else Writeln('nada');
       Until tecla = '?';
    End.

    Program Exemplo_3;
    Uses CRT;
{Programa que conta o número de vogais, número de consoantes e de brancos numa frase lida do teclado}

    Type símbolos = set of char;

    Var Alfabeto, vogais, consoantes : símbolos;
        frase : string[50];
        v,c,b,x : integer;
    Begin
       Vogais:=['a','e','i','o','u','A','E','I','O','U'];
       alfabeto:=['a'..'z']+['A'..'Z'];
       consoantes:=alfabeto-vogais;
       Clrscr;
       Write('Digite uma frase --> ');
       Readln(frase);
       b:=0;c:=0;v:=0;
              (* a função length() devolve o número de caracteres que o
                 parâmetro tem *)
       For x:=1 to length(frase) do
          if frase[x] in vogais
             then v:=v+1
             else if frase[x] in consoantes
                     then c:=c+1
                     else if frase[x] = ' ' then b:=b+1;
       Writeln;
       writeln(b,' brancos');
       Writeln(c,' consoantes');
       Writeln(v,' vogais');
    End.
   

Nenhum comentário:

Postar um comentário