Jump to content

Record e Type


Bravo121
 Share

Recommended Posts

Bem a minha questão é a seguinte:

Durante a minha aula de PSDI houve um exercício que tinham de criar uma variável (estado civil) e um tipo de dados para a variável.

O meu stor disse que tínhamos de criar um tipo de dados com uma limitação de palavras, ou seja, essa variável só ia aceitar umas certas palavras que neste caso era: solteiro, casado, viuvo.

Com umas pesquisas na internet encontrei o seguintes mas tem um erro:

Type dados = (viuvo, cadado, solteiro);

Var civil:dados;

Bem a declaração era essa mas pelo que encontrei não é possível guardar dados em variáveis desse tipo, ou seja não posso fazer readln(civil); e o meu compilador (Turbo Pascal) diz-me o mesmo

Quero saber o que estou a fazer mal e se é possível guardar dados em variáveis desse tipo pelo menos da mesma forma que nas outras.

Link to comment
Share on other sites

Um tipo de dados novo desse género não aceita, de facto, leitura directa pelo ReadLn. A única solução é leitura indirecta:

program exemplo;
uses crt;
Type dados = (viuvo, cadado, solteiro);
Var civil:dados;
    opc:char;

begin
   write('Estado civil? V=Viuvo, C=Casado, S=Solteiro');
   repeat
      opc := ReadKey;
   until (UpCase(opc) in ['V', 'C', 'S']);

   case UpCase(opc) of
      'V' : civil := Viuvo;
      'C' : civil := Casado;
      'S' : civil := Solteiro;
   end;
   // etc...
end.

Algo deste género. Podes fazer a leitura com uma string, que já será um Readln...

var s : string[1];

repeat
    readln(s);
until (s[1] in ['V', 'C', 'S']);

Cumpz. 👍

Knowledge is free!

Link to comment
Share on other sites

pois mas não era mais fácil fazer só uma string? não será código a mais com a 1ª opção?

No 2º código eu não repeti a estrutura Case Of.

Ser com um ReadLn da String ou um ReadKey do Char, vai dar tudo ao mesmo. Acabarás sempre numa estrutura Case Of ou de Ifs encadeados.

Para tipos de dados novos é a única opção óptima que existe. Não há volta a dar. 👍

EDIT: podes criar um procedimento de forma a não repetires sempre o mesmo código quando necessitas de ler o estado civil.

procedure LerCivil(var e : dados);
var s : string[1];
begin
   write('Estado civil? V=Viuvo, C=Casado, S=Solteiro');
   repeat
      readln(s);
      s:=UpCase(s);
   until (s[1] in ['V', 'C', 'S']);
   case UpCase(opc) of
      'V' : e := Viuvo;
      'C' : e := Casado;
      'S' : e := Solteiro;
   end
end;

Knowledge is free!

Link to comment
Share on other sites

Mais uma coisa quando vou escrever a variável civil tenho o mesmo problema de não poder escrever variáveis daquele tipo.

program exemplo;
uses wincrt;
Type dados = (viuvo, casado, solteiro);
Var civil:dados;
    opc:char;

begin
   write('Estado civil? V=Viuvo, C=Casado, S=Solteiro');
   repeat
      opc := ReadKey;
   until (UpCase(opc) in ['V', 'C', 'S']);

   case UpCase(opc) of
      'V' : civil := Viuvo;
      'C' : civil := Casado;
      'S' : civil := Solteiro;
   end;

writeln(civil);

end.

EDIT: GeSHi adicionado. thoga31

Link to comment
Share on other sites

Na verdade há outra solução para a leitura... E para a escrita também se arranja qualquer coisa...

Type
   Dados=(Viuvo,Casado,Solteiro);
Const
   Estados:Array [Dados] of String=('Viuvo','Casado','Solteiro');
Var
   Civil:Dados;
   i:integer;

begin
   (* Leitura *)
   Write('Estado Civil (0=Viuvo, 1=Casado, 2=Solteiro): ');
   readln(i);
   Civil:=Dados(i);  (* Converte um valor integer entre 0 e 2 num valor do tipo dados, e atribui-o à variavel *)

   (* Escrita *)
   Writeln('Escolheu o estado civil: ',Estados[Civil]);
end.

Um tipo de dados novo é geralmente um tipo ordinal, sendo que o primeiro valor é equivalente a 0, o segundo a 1 e assim sucessivamente. Portanto, usando um typecast (conversão entre tipos de dados) podemos atribuir quase directamente o valor à variável Civil.

Aproveitando essa mesma ordem, podemos usar um Array de Constantes string, para escrever o resultado. Só é necessário que as strings da constante estejam na mesma ordem que os valores do tipo.

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

E já agora, uma leitura "directa" à variável:

uses
   Crt;
Type
   Dados=(Viuvo,Casado,Solteiro);
Const
   Estados:Array [Dados] of String=('Viuvo','Casado','Solteiro');
Var
   Civil:Dados;

begin
   Write('Estado Civil (1=Viuvo, 2=Casado, 3=Solteiro): ');

   (* Lê o caracter da opção, cuja ordem dentro do tipo char é 49, 50 e 51 respectivamente, subtrai-lhe o valor da primeira opção (49) para obter valores de 0 a 2, e converte-a directamente para a variável Civil, tudo numa só instrução. *)
   Civil:=Dados(Ord(ReadKey)-49);  

   Writeln(Estados[Civil]);
   readln;
end.

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

A solução do @nunopicado é a mais óptima. Contudo deverás escolher o método que mais se aplica à matéria que já deste. Se não deste os pormenores que o @nunopicado utilizou, então aconselho-te a não os utilizares. Evita chatices de "onde desencantaste esta solução?". 👍

Cumpz.

Knowledge is free!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.