CIÊNCIA DA COMPUTAÇÃO PROF. AIR RABELO 2012 – Segundo Semestre 1 - Introdução a Programação 1.1 - Algoritmo É a descrição seqüencial de ações a serem executados para o cumprimento de uma determinada tarefa. É a forma pela qual descrevemos soluções para problemas que serão implementadas posteriormente em uma linguagem de programação e executadas pelo computador. Pode ser escrito através de pseudo linguagens, como o Portugol, ou símbolos como em fluxogramas. 1.2 - Algoritmo x Programa Um programa é a conversão, ou tradução, de um algoritmo para uma determinada linguagem de programação, segundo suas regras de sintaxe e semântica da linguagem, de forma a permitir que o computador possa interpretar e executar a seqüência de comandos pretendidos. 1.3 - Linguagem de Programação Uma linguagem de programação é um conjunto de símbolos (comandos, identificadores, caracteres ASCII, etc. ...) e regras de sintaxe que permitem a construção de sentenças que descrevem de forma precisa ações compreensíveis e executáveis para o computador. 1.4 – Programa Fonte O programa que escrevemos utilizando uma linguagem de programação, como o Pascal, a linguagem C, Java, e outras, é chamado de Programa Fonte. As linguagens de programação permitem que os programas sejam escritos e interpretados pelo homem, mas não pode ser interpretado pelo computador. 1.5 – Programa Objeto Programa Objeto é a seqüência de comandos de um programa escritos em linguagem de máquina. A linguagem de máquina é composta de símbolos binários que é interpretada pelo computador, mas não pode ser interpretada pelo homem. 1.6 – Compilador Compilador é um programa que traduz o Programa Fonte escrito por um programador em um Programa Objeto a ser interpretado pelo computador. Ou seja, é um tradutor de Programa Fonte em Programa Objeto. 2 - A Linguagem Pascal A linguagem Pascal, cujo nome é uma homenagem ao filósofo e matemático francês Blaise Pascal, foi inventada por Niklaus Wirth no início da década de 70. Objetivo: desenvolver uma linguagem de programação de alto nível utilizando-se programação estruturada. Antes do Pascal, a introdução à programação se fazia, em geral, através do Fortran, uma linguagem desestruturada e bem mais antiga. Wirth acreditava que muitos dos erros mais comuns de programação poderiam ser evitados com o uso de uma linguagem por blocos, e que trouxesse um severo controle de tipos. Padronização: ANSI ( American National Standars Institute ) e IEEE ( Institute of Eletrical and Eletronics Engineers ) Apostila de LTP2 – Pascal - Air Rabelo 2 Padrão de Fato: Borland International cria em 1983 o Turbo Pascal. Atualizações: durante os últimos anos foram lançadas diversas variações da linguagem Pascal implementando recursos que não são encontrados na estrutura padrão da linguagem. Nas mãos da Borland, já foram lançadas as versões 3.0, 4.0, 5.0 e 5.5 na década de 80. Durante a década de 90 foram lançadas as versões 6.0, 7.0 e o lançamento da linguagem Delphi, para programação em ambiente Windows. 2.1 - O Turbo Pascal O Turbo Pascal é mais que um simples compilador da linguagem Pascal, ele é um Ambiente Integrado de Desenvolvimento, consistindo de um conjunto de ferramentas como: Editor de CódigoFonte, Compilador, Depurador, help de comandos, e outras. 3 - Estrutura de um programa em Pascal: Todo programa em pascal é estruturado em 3 partes seqüenciais: 1 - Nome do programa 2 - Declarações 3 - Linhas de comandos program NOMEPROGRAMA; { nome do programa } { -- Área de declarações de bibliotecas, variáveis, constantes e conjuntos -- } uses { utilização de bibliotecas externas } var { declaração das variáveis } const { definição de constantes } type { definição de novos tipos de dados} begin { linhas de comandos }; end. OBS: O Pascal não faz distinção entre letras minúsculas e letras maiúsculas 4 – Comentários no programa Usam-se os símbolos { e } ou (* e *) para indicar que o texto entre os delimitadores é um comentário, o qual não tem sentido para o compilador. 5 – Variáveis Variável é uma região identificada da memória que tem por finalidade armazenar informações (dados) de um programa em execução. Uma variável armazena apenas um valor por vez. Toda vez que um valor é atribuído a uma variável, o seu valor anterior será sobreposto. Portanto as variáveis armazenam apenas o ultimo valor atribuído a elas. Sendo considerado como valor o conteúdo de uma variável, este valor está associado ao tipo de dado da variável (inteiro, real, lógico, caracter, ...). Apostila de LTP2 – Pascal - Air Rabelo 3 5.1 – Nomes de Variáveis e outros tipos Os nomes dados a variáveis, procedimentos, funções, constantes e outros tipos no Pascal devem seguir as seguintes regras: - iniciar sempre por uma letra (a - z , A – Z); - os demais caracteres podem ser somente letras, números ou o caracter underscore ( _ ). - pode ter qualquer quantidade de caracter, mas nomes muito grandes dificultam a escrita do programa, e nomes muito pequenos podem ser pouco significativos. 5.2 – Tipos de Variáveis Estudaremos variáveis de 3 classes no Pascal: - NUMÉRICAS – aceitam somente dígitos, e possuem valor numérico Ex: 0 ,1 , 2 , 5.10 ... - ALFANUMÉRICAS – qualquer caracter da tabela ASCII. Ex: a,b,c,A,B,C,!,@,#, 0, 1,2, ... - LÓGICAS - assumem apenas dois valores: TRUE ou FALSE, ou seja, verdadeiro e falso. 5.2.1 - Tipos de Dados Numéricos Inteiros São caracterizados tipos inteiros, os dados numéricos positivos ou negativos, excluindo-se qualquer número fracionário: Tipo de dado Valores que podem assumir Tamanho em bytes na memória shortint de –128 até 127 1 byte de 0 até 255 1 integer De –32.768 a 32.767 2 word de 0 até 65.535 2 longint de –2.147.483.648 a 2.147.483.647 4 5.2.2- Tipos de Dados Reais Os tipos de dado real permitem trabalhar com números fracionários, tanto positivos quanto negativos, sendo sua capacidade de armazenamento maior que dos números inteiros: Tipo de dado Valores que podem assumir Tamanho em bytes na memória 38 4 real de 2.9 e-39 até 1.7 e38 6 double de 5.0 e-324 até 1.7 e308 8 comp de 9.2 e-18 até 9.2 e18 8 extended de 3.4 e-4.932 até 1.1 e4.932 10 single -45 de 1.5 e Apostila de LTP2 – Pascal - Air Rabelo até 3.4 e 4 5.2.3 - Tipos de Caracter Os tipos de dado caracter permitem trabalhar com qualquer caracter da tabela ASCII: Tipo de dado Valores que podem assumir Tamanho em bytes na memória char armazena um caracter por vez. 1 string armazena de 1 a 256 caracteres 2 a 256 Tipo de dado Valores que podem assumir Tamanho em bytes na memória boolean TRUE ou FALSE 1 bit 5.2.4 - Tipo de Lógico 5.3 – Declaração de Variáveis no Pascal No Pascal as variáveis são declaradas logo após o título do programa utilizando-se a cláusula var: program EXEMPLO; var IDADE: integer; SALARIO, PESO, ALTURA : real; NOME: string[40]; { tamanho máximo = 40 caracteres } DESCRICAO: string; { caso não seja informado o tamanho máximo, ele será de 256} SEXO: char; APROVADO: boolean; 5.4 – Atribuição de valores as Variáveis Para se atribuir uma valor a uma variável utiliza-se o comando de Atribuição do Pascal ( := ). Os valores atribuídos as variáveis do tipo caracter deverão vir entre apóstrofe ( ‘ ‘ ). Exemplo: IDADE := 25; SALARIO := 2786.50; NOME := 'Marcelo dos Santos'; SEXO := 'F'; APROVADO := TRUE; {tipo {tipo {tipo {tipo {tipo inteiro} real} string} char} lógico} 6 – Linha de Comando no Pascal Uma linha de comando no Pascal pode ocupar uma ou mais linhas no programa fonte, e sempre se encerra com ponto-e-vírgula ( ; ). Há também a possibilidade de se escrever mais de uma linha de comando em uma mesma linha do programa fonte, mas não é recomendável, pois dificulta a interpretação da lógica. Exemplo: Apostila de LTP2 – Pascal - Air Rabelo 5 SALARIO := 2786.50; { uma linha de comando em uma linha de programa fonte} NOME := 'Marcelo dos Santos'; SEXO := 'F'; APROVADO := TRUE; IDADE := 25; {3 comandos em uma linha} TEXTO := 'O Nome da linguagem Pascal é uma homenagem ao filósofo e matemático francês Blaise Pascal'; {1 comando em duas linhas do progama fonte} 7 – Operadores 7.1 - Operadores Aritméticos Os operadores aritméticos são utilizados para efetuar operações aritméticas com número inteiros e reais. São eles: Operador O que representa + Soma Subtração * Multiplicação / Divisão div Divisão inteira (o resto é eliminado) mod Resto da divisão Exemplos: A B C A B A C B := := := := := := := := 1; 3; 5; B + C; 10 div 3; 10 mod B; B / C; C * B; 7.2 - Operadores Relacionais Os operadores relacionais são utilizados para efetuar a comparação entre dados de mesmo tipo. São eles: Operador > < >= <= <> = O que representa Maior que Menor que Maior ou igual a Menor ou igual a Diferente de Igual a O resultado de uma operação relacional é sempre um valor lógico, ou seja, TRUE ou FALSE. Exemplos: A B C A := 1; := 3; := 5; > B {FALSE} Apostila de LTP2 – Pascal - Air Rabelo 6 B <= C A <> B {TRUE} {TRUE} 7.3 - Operadores Lógicos Os operadores lógicos são utilizados para se criar expressões Relacionais compostas. São eles: Operador and or not O que representa e (junção) ou (escolha) não (negação ou inversão) Exemplos: Considere A = 1 , B = (A > B) and (B <= C) (A <> B) or (C < B) Not (B <= C) 3 e C = 5 {FALSE and TRUE {TRUE or FALSE {not TRUE => => => FALSE} TRUE } FALSE} Obs: no Pascal, as operações lógicas compostas devem vir separadas por parênteses. 7.4 -Tabela verdade para operações lógicas: Abaixo, segue três tabelas, chamadas tabela-verdade, contendo o resultado do uso dos operadores lógicos sobre dois operandos. Operando 1 TRUE TRUE FALSE TRUE TRUE FALSE ------------- Operador and and and or or or not not Operando 2 TRUE FALSE FALSE TRUE FALSE FALSE TRUE FALSE Resultado TRUE FALSE FALSE TRUE TRUE FALSE FALSE TRUE 7.5 - Prioridade das Operações Se vários operadores aparecerem em uma expressão, a ordem de execução das operações será dada segundo os seguintes critérios seqüenciais: 1º. 2º. 3º. 4º. 5º. 6º. Parênteses – ( ) Funções matemáticas (Ex: abs() , int() , ln() , ...) Multiplicação e Divisão ( * , / , mod , div ) Soma e Subtração ( + , - ) Operadores Relacionais, sem ordem entre eles ( >, <, >=, <=, <>, = ) Operadores Lógicos na seguinte ordem: not, and, or Apostila de LTP2 – Pascal - Air Rabelo 7 7.6 - Operador de Concatenação O operador de concatenação efetua a junção de duas variáveis ou constantes do tipo string ou char. Exemplo: var Nome, SobreNome, NomeCompleto : string[30]; begin { Suponhamos o nome Josias Santos } Nome := 'Josias'; SobreNome := 'Santos'; NomeCompleto := Nome + ' ' + SobreNome; writeln( NomeCompleto ); { Josias Santos } NomeCompleto := 'Jose' + ' ' + 'Maria'; writeln( NomeCompleto ); { José Maria } end. 8 – Comando de Entrada e Saída de dados 8.1 – Entrada de Dados O principal comando de entrada de dados no Pascal é o comando readln. Este comando permite a entrada de dados através de variáveis oriundas de diversos dispositivos, principalmente via teclado. Sintaxe: readln( variável ); Exemplo: readln(NOME); 8.2 - Saída de dados Os principais comandos destinadas a exibir todos os tipos dados no vídeo são: Write e Writeln Sintaxe: write( variável1, variável2, expressão1, expressão2, …); writeln( variável1, variável2, expressão1, expressão2, …); A diferença entre write e writeln é que ao ser executado o comando write, o cursor se posiciona na tela logo a frente ao último valor exibido (exemplo 1). Mas quando é executado o comando writeln, o cursor se posicona na tela sempre na primeira coluna da próxima linha (exemplo 2). Exemplo1: write('TESTE DE TELA'); TESTE DE TELA_ Apostila de LTP2 – Pascal - Air Rabelo 8 Exemplo2: writeln('TESTE DE TELA'); TESTE DE TELA _ Os comandos write e writeln Permitem ao usuário certo controle com relação à formatação dos dados de saída. Quando o tipo da variável for real, double ou extended, poderá ser definida a quantidade de casas decimais. Ex: SALARIO := 2500.30; write(SALARIO:4:2); {saída formatada para 4 casas inteiras e duas decimais} Exemplo 1: Faça um programa em Pascal que receba via teclado o Nome, o Salário e o Valor do Aumento Salarial de um empregado. Em seguida o programa deverá calcular e imprimir o novo salário do empregado, que será a soma do atual salário com o Valor do Aumento Salarial. program EXEMPLO1; var NOME: string[40]; SALARIO, VLR_AUMENTO: real; begin write('Digite o Nome do Empregado: '); readln(NOME); write('Digite o Salário do Empregado: '); readln(SALARIO); write('Digite o valor do aumento para o Salário: '); readln(VLR_AUMENTO); SALARIO := SALARIO + VLR_AUMENTO; writeln('O novo Salário é: ', SALARIO:5:2); end. 9 – Comando de alternativa – IF 9.1 – Alternativa Simples – if … then Sintaxe: if <condição> then <comando1>; ou if <condição> then begin Apostila de LTP2 – Pascal - Air Rabelo 9 <comando1>; <comando2>; end; Obs: sempre que existir mais de um comando a ser executado após o then, estes comandos devem estar entre begin … end; Exemplo1: readln(IDADE); if IDADE < 2 then write('É um bebê !'); Exemplo2: readln(IDADE); if IDADE < 2 then begin write('É um bebê !'); IDADE := IDADE + 5; end; 9.2 – Alternativa Composta – if … then… else Sintaxe: if <condição> then <comando1> else <comando2>; ou if <condição> then begin <comando1>; <comando2>; end else begin <comando3>; <comando4>; end; Obs: - sempre que existir mais de um comando após o then ou após o else, estes comandos devem estar entre begin … end; - sempre que for utilizado o else, na linha anterior não poderá haver ponto-e-vírgula (;) Exemplo1: readln(IDADE); if IDADE < 2 then write(' É um bebê ! ') else write(' Não é um bebê ! '); Apostila de LTP2 – Pascal - Air Rabelo 10 Exemplo2: readln(IDADE); if IDADE < 2 then begin write(' É um bebê ! '); IDADE := IDADE + 5; end else if IDADE < 10 then write(' É uma criança ! ') else if IDADE < 16 then write(' É um adolescente ! ') else begin write(' É um Adulto ! '); IDADE := IDADE – 5; end; Apostila de LTP2 – Pascal - Air Rabelo 11 Exercícios (parte 1): 1 - Fazer um programa em Pascal que receba via teclado o Nome do Aluno, a Nota1, a Nota2 e a Nota 3. O programa deverá calcular e imprimir a média e o desempenho do aluno baseando-se nas seguintes regras: - média de 7 para cima => aluno aprovado - média de 4 para baixo => aluno reprovado - média entre 4.1 e 6.9 => aluno em recuperação 2 – Fazer um programa em Pascal que receba via teclado as medidas dos 3 lados de um triângulo. De acordo com os valores digitados o programa deverá imprimir o tipo do triângulo: - eqüilátero, se os 3 lados forem iguais, - isósceles, se 2 lados forem iguais e 1 diferente - escaleno, se os 3 lados forem diferentes 3 – Faça um programa em Pascal para calcular e imprimir o Bônus Salarial e Desconto de Vale Transporte para um empregado da Empresa ABCDário LTDA. O programa deverá receber via teclado o Tempo de Casa e o Salário do Empregado e considerar: Tempo de Casa Até 5 anos Até 5 anos De 6 a 10 anos De 6 a 10 anos De 6 a 10 anos Acima de 10 anos Salário Até R$300 Acima de R$300 Até R$500 Acima de R$500 até R$2000 Acima de R$2000 ------------ Apostila de LTP2 – Pascal - Air Rabelo Bônus R$50 R$80 15% do Salário 13% do Salário 12% do Salário R$300 Vale Transporte 1% do Salário 2% do Salário R$100 R$120 8% do Salário 4% do Salário 12 10 – Comandos de repetição - loop 10.1 – while...do (enquanto...faça) Caracteriza-se por verificar uma condição antes de entrar na repetição. Se a condição for verdadeira, os comandos contidos dentro da estrutura do loop serão executados repetidamente enquanto a condição permanecer verdadeira. Se a condição for falsa, os comandos que estão dentro do loop não serão executados e o programa segue executando os comandos após o final da repetição, ou seja, fora do loop. Sintaxe: while <condição> do <comando1>; ou while <condição> do begin <comando1>; <comando2>; end; Obs: - sempre que existir mais de um comando dentro da estrutura de repetição while do, estes comandos devem estar entre begin … end; Exemplo: R := 0; A := 3; B := 5; I := 1; while I <= 5 do begin R := A + B; writeln('O resultado de A + B é: ',R); A := A + 2; B := B – 1; I := I + 1; end; Apostila de LTP2 – Pascal - Air Rabelo 13 10.2 – repeat...until (repita...até) Se caracteriza por executar a lista de comandos contidos no loop antes de verificar a condição que vem no final. Após executar os comandos do loop, verifica a condição. Se a condição for falsa, continua executando repetidamente os comandos do dentro da estrutura do loop até que a condição se torne verdadeira. Se a condição for verdadeira, o loop é encerrado e o programa segue executando os demais comandos após o final da repetição, ou seja, fora do loop. Sintaxe: repeat <comando1>; <comando2>; until <condição>; Obs: - a estrutura repeat...until não utiliza Begin...end, independente de quantos comandos exitam no loop. Exemplo: R := 0; A := 3; B := 5; I := 1; repeat R := A + B; writeln('O resultado de A + B é: ',R); A := A + 2; B := B – 1; I := I + 1; until I > 5; 10.3 – for...do (para...faça) Caracteriza-se por repetir um conjunto de comandos uma quantidade de vezes pré-definida. O loop é encerrado quando as repetições já tiverem ocorrido a quantidade de vezes pré-determinada. Sintaxe: For <var1> := <valor1> to <valor2> do <comando1>; ou For <var1> := <valor1> to <valor2> do begin <comando1>; <comando2>; End; Obs: - sempre que existir mais de um comando dentro da estrutura de repetição for...do, estes comandos devem estar entre begin … end; Apostila de LTP2 – Pascal - Air Rabelo 14 - no Pascal, não há como mudar o passo de incremento da variável <var1>, portanto, a cada execução da lista de comandos do loop, a variável <var1> tem seu valor incrementado de 1. Exemplo: R := 0; A := 3; B := 5; For I := 1 to 5 do begin R := A + B; writeln('O resultado de A + B é: ',R); A := A + 2; B := B – 1; end; Para se executar o for com passo negativo, ou seja, ao invés do valor da variável <var1> ser incrementado de 1 em cada execução do loop, ele ser decrementado de 1, deve-se utilizar downto ao invés de to. For <var1> := <valor1> downto <valor2> do <comando1>; ou For <var1> := <valor1> downto <valor2> do begin <comando1>; <comando2>; End; Exemplo: R := 0; A := 3; B := 5; For I := 5 downto 1 do begin R := A + B; writeln('O resultado de A + B é: ',R); A := A + 2; B := B – 1; end; 10.4 - Comparação entre o while, repeat e for O while deve ser utilizado em situações onde os comandos do loop só devem ser executados se a condição do loop for verdadeira antes de iniciar o loop. O repeat deve ser utilizado em situações onde os comandos do loop devem ser executados pelo menos uma vez independente se a condição do loop é verdadeira ou falsa. O for deve ser utilizado em loops onde o número de repetições é previamente conhecido e não há condições para que estas repetições ocorram, elas simplesmente devem ocorrer em uma quantidade de vezes pré-determinada . Apostila de LTP2 – Pascal - Air Rabelo 15 O quadro abaixo contém uma mesma lógica escrita com cada um dos três comandos de loop estudados. Desta forma podemos comparar as diferenças de sintaxe entre eles: R := 0; A := 3; B := 5; I := 1; while I <= 5 do Begin R := A + B; writeln(R); A := A + 2; B := B – 1; I := I + 1; end; R := 0; A := 3; B := 5; I := 1; repeat R := A + B; writeln(R); A := A + 2; B := B – 1; I := I + 1; until I > 5; R := 0; A := 3; B := 5; For I := 1 to 5 do begin R := A + B; writeln(R); A := A + 2; B := B – 1; end; 11 – Funções e Procedimentos do Pascal 11.1 – Funções Matemáticas abs( ) Retorna o valor absoluto de um número real ou inteiro passado como parâmetro. Valor absoluto é um valor sem sinal. Exemplo: A A A A := := := := abs(-2); abs(2); 2 + abs(-2); abs(-3.45); { { { { A A A A = = = = 2 } 2 } 4 } 3.45 } int( ) Transforma as casas decimais de um número real em zero. Exemplo: A := int(2.3); A := int(3.85); { A = 2.0 } { A = 3.00 } trunc() Transforma um número real em inteiro eliminando as casas decimais. Exemplo: A := trunc(2.3); A := trunc(3.85); { A = 2 } { A = 3 } round() Arredonda um número fracionário mantendo-o como real. Se o valor decimal for de 0.5 ou maior, o número é arredondado para cima, caso contrário, para baixo. Exemplo: A := round(2.3); A := round(3.85); Apostila de LTP2 – Pascal - Air Rabelo { A = 2.0 } { A = 4.00 } 16 Potência no Pascal: O Pascal não possui uma função pré-definida para potência, desta forma, para calcular a potência de um número, utilizamos uma fórmula matemática com as funções exp( ) e ln( ). exp( N ) => retorna a potência do número e (e=2.7182818) elevado ao valor de N ln ( N ) => retorna o logaritmo neperiano de N fórmula de potencia: exp(P * ln(B)) {onde P é o expoente e B é a base} Exemplo: A := exp(3 * ln(5)); A := exp(20 * ln(2)); { A = 53 } { A = 220 } 11.2 – Funções e Procedimentos para manipulação de strings. copy( X , Y, Z ) - Função que retorna a cópia de Z caracteres a partir da posição Y da string X - Y e Z são valores inteiros - X é uma string Exemplo: C := 'AERODINÂMICA'; B := copy( C , 5 , 8 ) ; A := copy( C , 1 , 4 ); { B = 'DINÂMICA' } { A = 'AERO' } length( ) Função que retorna o tamanho, ou o número de caracteres, de uma variável string. Exemplo: A := 'DINÂMICA'; write( length( A ) ); B := 'JOSE DA SILVA'; write( length( B ) ); { 8 } { 13 } pos( X , Y ) Função que retorna a posição numérica onde se encontra o conjunto de caracteres da variável (ou expressão) X dentro da string Y. Se não for encontrada, o retorno será zero. Exemplo: A B C D E E E := := := := := := := 'FUMEC'; 'M'; 'UM'; 'UMA'; pos( B , A ); pos( C , A ); pos( D , A ); {E=3} { E = 2 , o retorno é da posição inicial da 1ª. string dentro da 2ª.} { E = 0 , porque a string D não se encontra totalmente em A } delete( X , Y , Z ) - Procedimento que deleta Z caracteres da variável X a partir da posição Y. - Y e Z são valores inteiros Apostila de LTP2 – Pascal - Air Rabelo 17 - X é uma string Exemplo: NOME := delete( NOME := delete( 'JOSÉ ANTÔNIO'; NOME , 5 , 8 ); { NOME = 'JOSE' } 'JOSÉ DA SILVA'; NOME , 6 , 3 ); { NOME = 'JOSE SILVA' } insert( X , Y , Z ) - Procedimento que insere a string X na string Y a partir da posição Z. - Z é um valor inteiro - X e Y são strings Exemplo: NOME := 'JOSÉ SILVA'; insert(' DA' , NOME , 5); PLACA := 'XP1212'; insert('T', PLACA , 3 ); { NOME = 'JOSE DA SILVA' } { PLACA = 'XPT1212' } str( X , Y ) - Procedimento que copia o valor numérico de X , converte para string, e grava em Y. - X é um valor numérico inteiro ou real - Y é uma string Exemplos: A := 15; B := ' '; str( A , B ); { A = 15 , B = '15' } DIA:= 10; MES:= 12; ANO:= 1980; DATA:= ' '; D:=' '; M:=' '; A:=' '; str(DIA, D); str(MES, M); str(ANO, A); DATA := D + '/' + M + '/' + A; {DATA = '10/12/1980'} val( X , Y , Z ) - Procedimento que copia o valor string de X , converte para número (real ou inteiro), e grava em Y. Como nem toda string pode ser um número, ou seja, somente as strings que contêm apenas dígitos no seu conteúdo podem ser convertidas para números, Z é uma variável inteira que indica se a copia foi bem sucedida ou não (status). Se a cópia foi bem sucedida o valor de Z será zero, caso contrário o valor de Z será maior que zero e apontará qual posição da variável X gerou a impossibilidade de cópia. - Y é um valor numérico inteiro ou real - X é uma string - Z é um valor inteiro Exemplos: A := '15'; B := 0; C := 0; Apostila de LTP2 – Pascal - Air Rabelo 18 val( A , B , C ); { A = '15' , B = 15 , C = 0 } DATA = '10/12/1980'; B := 0; C := 0; val(DATA,B,C); { DATA = '10/12/1980' , B = 0 , C = 3 } { após o val, C valerá 3 porque a 3ª. posição da variável DATA ( / ) foi a primeira que impossibilitou a conversão da string DATA para o número B }. EXERCÍCIOS (parte 2): 1 – Faça um programa em Pascal para receber via teclado a data de nascimento de uma pessoa e a data de hoje, ambas no formato string DD/MM/AAAA. O programa deverá calcular e imprimir a idade da pessoa. 2 – Fazer um programa em Pascal para receber via teclado um código caracter contendo 11 dígitos. Os 9 primeiros dígitos representam o código e os 2 últimos os dígitos representam os dígitos verificadores. O programa deverá calcular os dois dígitos verificadores para este código de 9 algarismos e comparar com os 2 dígitos verificadores digitados. Se forem iguais, o programa deverá imprimir a mensagem: “Dígito Correto”, caso contrário imprimir “Dígito Inválido”. O cálculo dos dígitos verificadores deverá ser feito seguinte forma: 1º. Dígito verificador: 1 - somar entre si o valor de cada dígito do código 2 - dividir o resultado por 10 3 - o 1º. Dígito será a parte inteira do resultado da divisão do item 2 (acima). 2º. Dígito verificador: 1 - multiplicar entre si o valor de cada dígito do código 2 - o 2º. Digito verificador será o ultimo algarismo a direita do resultado da multiplicação do item 1 (acima). Exemplo: Código de 9 dígitos: '821324312' 1º. Digito verificador: 8+2+1+3+2+4+3+1+2 = 26 / 10 = 2,6 => Parte inteira = 2 2º. Digito verificador: 8*2*1*3*2*4*3*1*2 = 2304 => Ultimo algarismo a direita = 4 3 – Fazer um programa em Pascal para receber via teclado a ALTURA em metros e o SEXO dos atletas de uma delegação. O programa deverá calcular e imprimir: - a maior altura encontrada - a menor altura encontrada - o número de atletas do sexo feminino - a média da altura masculina - a média geral das alturas. Obs: - adotar um flag para encerrar a entrada de dados - consistir os valores digitados na entrada de dados de maneira que só poderão ser aceitos: SEXO = M ou F; ALTURA maior que zero e menor ou igual a 2,5 metros; 4 - Em uma Fábrica trabalham homens e mulheres divididos em 3 classes: - Classe A: fabricam até 30 peças por mês - Classe B: fabricam entre 31 e 40 peças por mês - Classe C: fabricam acima de 40 peças por mês Fazer um programa em Pascal que receba via teclado o Código do Operário (caracter 5 posições), o Número de Peças fabricadas no mês (inteiro) e o Sexo do operário (caracter 1 posição => M ou F). Os funcionários da Classe A recebem salário mínimo (R$ 540,00), os da Classe B recebem salário Apostila de LTP2 – Pascal - Air Rabelo 19 mínimo + 3% do salário mínimo por peça fabricada acima de 30. Funcionários da Classe C recebem salário mínimo + 5% do salário mínimo por peça fabricada acima de 30. O programa deverá calcular e imprimir para cada funcionário o salário a receber. Ao final, o programa deverá imprimir: - Total gasto pela empresa com o pagamento de salários - Número total de peças fabricadas - Código do Operário que fabricou o menor número de peças - Média de quantidade de peças fabricadas por homens - Média de quantidade de peças fabricadas por mulheres Obs: adotar o flag Código de Operário = 00000 para encerrar a entrada de dados Apostila de LTP2 – Pascal - Air Rabelo 20 12 – Outros comandos, procedimentos e funções do Pascal gotoxy(coluna,linha) Posiciona o cursor em qualquer posição da tela referenciada pelos eixos X e Y, ou coluna e linha. A tela é composta de 80 colunas e 25 linhas, portanto, para posicionar o cursor na coluna 10 e linha 2 é só executar o comando: gotoxy(10,2); clreol É a abreviação do texto em inglês: clear end of line. Apaga todos os caracteres da linha correspondente a partir da posição corrente do cursor. Exemplo: gotoxy(20,01); write('Digite o Nome: '); readln(NOME); gotoxy(20,01); clreol; chr( X ) Função que retorna o caracter de número X da tabela ASCII. A tabela ASCII contém 256 caracteres onde o primeiro é o de número 1 e o ultimo o de número 256. Exemplo1: write( chr(42) ); { será exibido o caracter * } Exemplo2 (programa que exibe na tela toda a tabela ASCII): Program TAB_ASCII; var CONT: integer; begin for CONT := 0 to 255 do writeln( chr(cont) ); end; ord( X ) Função que retorna o número do caracter X na tabela ASCII. Exemplo: write( ord('*') ); {será exibido o número 42 } CARAC := 'd'; write( ord( CARAC ) ); { sera exibido o número do caracter d na tabela ASCII } readkey Função que interrompe a execução de um programa até que uma tecla do teclado seja pressionada, e então retorna o caracter da tecla pressionada. obs: a tecla pressionada não é exibida na tela Exemplo: write('Confirma a resposta? (S/N) '); TECLA := readkey; write(TECLA); {exibe a tecla pressionada na tela} if TECLA = 'S' then write('Resposta confirmada !'); Apostila de LTP2 – Pascal - Air Rabelo 21 upcase( X ) Função que retorna a letra maiúscula de X. Caso X não seja letra ou já seja maiúscula, a função retornará o próprio caracter X. Obs: X deve ser uma variável do tipo char Exemplo 1: readln(SEXO); if ( upcase(SEXO) <> 'M' ) and ( upcase(SEXO) <> 'F' ) then write('Sexo Inválido ! '); Exemplo 2: readln(SEXO); SEXO := upcase(SEXO); if ( SEXO <> 'M' ) and ( SEXO <> 'F' ) then write('Sexo Inválido !'); Exemplo 3: readln(NOME); for CONT := 1 to length(NOME) do NOME[CONT] := upcase( NOME[CONT] ); Obs: NOME[1] - retorna o primeiro caracter da variável NOME NOME[2] - retorna o segundo caracter da variável NOME... EXERCÍCIOS (parte 3): 1 – Fazer um programa em Pascal para receber cada letra de um nome utilizando a função readkey, e caso seja digitado um espaço (‘ ’), exibir na tela o nome completo digitado 2 – Fazer um programa em pascal para receber um nome via teclado com o comando readln. Em seguida o programa deverá converter a primeira letra de cada parte do nome digitado para maiúsculo e exibir o resultado na tela. 3 - Fazer um programa em Pascal para verificar uma senha de acesso: - Definir uma variável com a senha correta. - A senha deverá possuir 6 caracteres. - O programa deverá ser cancelado após 5 tentativas incorretas, e após cada uma delas, emitir uma mensagem indicando a senha incorreta. - O programa deverá emitir uma mensagem quando a senha estiver correta, e, após isto, finalizar. - A digitação não será “case sensitive”, ou seja, A = a, B = b, ... - Os caracteres digitados não deverão aparecer na tela, portanto, para cada caracter digitado, deverá aparecer na tela um asterisco (*) representando aquele caracter. 4 - Fazer um programa em Pascal para calcular uma conta telefônica. Serão digitadas via teclado o Horário Inicial e o Horário Final de cada ligação. Calcular e imprimir o custo de cada chamada de acordo com a tabela abaixo: Intervalo de horário 00:00 ás 05:59 06:00 às 07:59 08:00 às 17:59 18:00 às 23:59 Apostila de LTP2 – Pascal - Air Rabelo Custo do minuto R$ 0,10 R$ 0,15 R$ 0,20 R$ 0,15 22 - Receber os dados via teclado em uma variável do tipo string com 5 posições. Exemplo: ’10:30’ - Imprimir o total da conta telefônica - Criar uma consistência para que o Horário Final da chamada seja sempre maior que o Horário Inicial. - Considerar que as ligações sempre ocorrem dentro do mesmo dia. - Considerar o valor do minuto do Horário Inicial da chamada para calcular o custo. - Adote um Flag para encerrar a entrada de dados. 5 - O DETRAN deseja fazer o controle das multas de veículos. Faça um programa em Pascal que receba via teclado a PLACA DO VEÍCULO, a DATA DA MULTA (DD/MM/AAAA) e o VALOR DA MULTA. O programa deverá consistir a entrada de dados da seguinte forma: - A placa deverá ser formada por três letras e quatro números. Ex: GVP5566 - A data deverá ser uma string de 10 posições e validada da seguinte forma: DD/MM/AAAA | | |_ deve ser maior ou igual 1980 e menor ou igual a 2009 | |_ deve ser maior ou igual a 01 e menor ou igual a 12 |_ deve ser maior ou igual a 01 e menor ou igual a 31 - O valor da multa deverá ser maior que zero. Como resultado final o programa deverá imprimir: - A soma dos valores das multas. - O valor médio das multas. - O valor da menor multa. Obs: - Definir um Flag para encerrar o programa. Apostila de LTP2 – Pascal - Air Rabelo 23 13 - VETORES e MATRIZES: Ao se utilizar variáveis, pode-se armazenar apenas um valor por vez. Considere um programa que precisa armazenar as notas de 5 provas realizadas por um aluno. Uma opção seria criar cinco variáveis para armazenar as notas. Por exemplo: NOTA1, NOTA2, NOTA3, NOTA4, NOTA5 : integer; Em Pascal existem estruturas que permitem agrupar várias informações dentro de uma mesma variável. Estas estruturas são chamadas de vetores e matrizes. 13.1 – Vetores Este tipo de estrutura é também chamado de matriz unidimensional. Um vetor é declarado com seu nome, tamanho e seu tipo. Sintaxe: <vetor> : array[tamanho] of <tipo_de_dado>; onde: - vetor é o nome do vetor, - tamanho é o tamanho atribuído ao vetor, em número de elementos - tipo_de_dado é o tipo de elemento armazenado (inteiro, real...). Uma variável somente pode conter um valor por vez. No caso dos vetores, estes poderão armazenar mais de um valor por vez, pois são dimensionados exatamente para este fim. Para criar um vetor para armazenar as cinco notas do aluno: NOTAS : array[1..5] of real; A leitura e exibição de vetores são feitas indicando individualmente quais elementos se deseja ler ou imprimir. Atribuindo valores ao vetor de notas do aluno: NOTAS[1] NOTAS[2] NOTAS[3] NOTAS[4] NOTAS[5] := := := := := 5.2; 8.0; 9.2; 7.5; 8.3; O nome é um só, o que muda é a informação indicada dentro dos colchetes, ou seja, o índice ou posição do vetor, que representa o endereço onde o valor está armazenado. Para o exemplo anterior teríamos: NOTAS 1 2 3 4 5 => índice ou posição no vetor 5.2 8.0 9.2 7.5 8.3 => conteúdo de cada posição 13.2 – Matrizes Usando mesmo exemplo do início desta página, vamos supor que agora será necessário armazenar 4 notas dos mesmos 5 alunos, ao invés de apenas uma. Uma opção seria criar cinco vetores, um para cada 4 notas de cada aluno. Entretanto, esta não é a melhor solução já que seria necessário criar uma estrutura de controle para cada vetor. A melhor opção seria criar uma única matriz de duas dimensões para armazenar cada uma das 4 notas dos 5 alunos. Apostila de LTP2 – Pascal - Air Rabelo 24 Sintaxe: <matriz> : array[dimensão_linha,dimensão_coluna] of <tipo_de_dado>; onde: - matriz é o nome atribuído à matriz, - dimensão_linha é o tamanho da matriz em número de linhas, - dimensão_coluna é o tamanho da matriz em número de colunas - tipo_de_dado é o tipo do elemento armazenado(inteiros, reais...). Para o caso das 4 notas dos 5 alunos a declaração da matriz seria: NOTAS : array[1..5,1..4] of real; Neste caso, as linhas representam os alunos, e as colunas representas as notas: NOTAS 1 1 3 4 Índice das colunas => 4 notas 8.5 9.0 7.8 8.9 5.0 ALUNOS 3 7.0 4 8.5 5 5.5 2 2 6.8 7.5 8.0 8.0 8.7 5.7 9.2 7.2 6.5 7.8 7.9 7.0 | Índice das linhas => 5 alunos Exemplo de programa: program EXEMPLO; uses CRT; var NOMES: array[1..50] of string[40]; IDADES: array[1..30] of byte; QUANT_ALUNOS_POR_NOTA: array[0..100] of integer; QUANT_ALUNOS_NOTA_ACIMA60: array[60..100] of integer; ALUNOS_NA_SALA_DE_AULA: array[1..8,1..7] of string[30]; X: integer; begin IDADES[1] := 74; {atribuir o valor 74 para a posição 1 do vetor} for X := 1 to 50 do { recebe a digitação dos 50 nomes do vetor NOMES } Begin write('Digite o Nome: '); readln(NOMES[X]); end; write(NOMES); {Comando inválido por não ter sido feita referência à posição desejada do vetor NOMES} write(NOMES[10]); {OK} end. Apostila de LTP2 – Pascal - Air Rabelo 25 13.3 - Método de Pesquisa Seqüencial ou Linear em Vetores Este é o método de pesquisa mais simples em vetores, no qual cada item do vetor é examinado por vez e comparado ao item que se está procurando, até ocorrer uma coincidência. Este método de pesquisa é lento, porém eficiente nos casos em que um vetor encontra-se com seus elementos desordenados. Exemplo de Pesquisa Seqüencial: Criar um programa que armazene 5 nomes em um vetor em seguida faça a pesquisa dos nomes solicitados: Algoritmo: 1- Criar uma repetição para receber a digitação dos 5 nomes 2- Criar uma repetição que efetue a pesquisa enquanto o usuário assim desejar. Durante a fase de pesquisa, deverá ser solicitada a informação a ser pesquisada. Essa informação deverá ser comparada com o primeiro elemento; se for igual, o elemento procurado foi encontrado, caso contrário, avança para o próximo. Se não achar em toda a lista, informar que não existe o elemento pesquisado; se existir deverá mostrá-lo. 3- Encerrar a pesquisa quando desejado. program PESQUISA_SEQUENCIAL; uses CRT; var NOMES: array[1..5] of string[30]; CONT,Z: integer; NOME_PESQ: string[30]; ENCONTROU: boolean; begin clrscr; for CONT:=1 to 5 do begin gotoxy(5,2); write('Digite o Nome ' , CONT , ': '); clreol; readln(NOMES[CONT]); end; gotoxy(5,4); write('Digite o Nome para pesquisar(FIM para encerrar): '); repeat gotoxy(55,4); clreol; readln(NOME_PESQ); IF NOME_PESQ = 'FIM' then break; ENCONTROU := FALSE; for Z:= 1 to 5 do if NOME_PESQ = NOMES[Z] then begin ENCONTROU:= TRUE; break; end; gotoxy(5,60); clreol; if ENCONTROU then write('O nome foi encontrado na posição ' , Z , ' do vetor') else write('O nome não foi encontrado no vetor'); until NOME_PESQ = 'FIM'; readkey; Apostila de LTP2 – Pascal - Air Rabelo 26 end. EXERCÍCIOS (parte 4): 1 – Fazer um programa em Pascal para consultar informações sobre os vôos de uma empresa aérea. Primeiramente o programa deverá receber via teclado os Nomes e respectivas Distâncias (em km, até Belo Horizonte) de até 20 Cidades no mundo. Em seguida, o programa deverá entrar no módulo de consultas e solicitar o Nome de uma Cidade. Para cada cidade digitada o programa deverá calcular e exibir os seguintes resultados: - Preço da Passagem - Tempo de Vôo em minutos - Número de escalas no percurso Considerações para os cálculos: - A empresa aérea cobra R$0,25 por km percorrido no vôo - O avião voa com uma velocidade de 800 km/h - A empresa aérea faz uma escala a cada 3 horas de vôo. Observações: - Adotar um flag para finalizar a entrada de dados com os Nomes de Cidades e Distâncias - Adotar um flag para finalizar as consultas - Exibir mensagem de erro se o Nome da Cidade digitada na consulta não existir na lista de cidades digitadas inicialmente (Max. 20) - Durante a digitação dos Nomes das Cidades e Distâncias, consistir: - O Nome da Cidade deverá ser de preenchimento obrigatório - A distância até Belo Horizonte deverá ser no mínimo 500 km. Apostila de LTP2 – Pascal - Air Rabelo 27 14 – Procedimentos e Funções (procedures and functions) Na medida em que o nível de complexidade dos programas e o tamanho vão aumentando, muitas vezes escrevemos um mesmo conjunto de instruções em dois ou mais pontos do programa, ou em programas diferentes. O ideal seria se aquele conjunto de instruções pudesse ser escrito somente uma vez e utilizado quantas vezes fossem necessários. Para isto, existem os Procedimentos e Funções, ou seja, para facilitar e agilizar a criação de programas pelos programadores. A idéia e dividir o programa em partes, sendo as partes em que o uso ocorrer mais de uma vez, transformadas em procedimentos ou funções, evitando-se assim a reescrita de um mesmo conjunto de comandos mais de uma vez. Ou seja, a seqüência de comandos é escrita somente uma vez, dentro do procedimento ou função, e usada quantas vezes forem necessárias no mesmo programa ou em programas diferentes. A vantagem de transformar uma seqüência de comandos em um procedimento ou função, além de evitar a reescrita de código, já que são escritos uma vez e usados quantas vezes forem necessários, é reduzir também o trabalho do programador quando este for alterar algum comando desta seqüência lógica. Se os comandos estiverem escritos repetidas vezes no mesmo programa ou em programas diferentes, o programador deverá promover a alteração e todas elas, tomando-se muito tempo e trabalho. Entretanto, se a lógica estiver contida em uma função ou procedimento, esta foi escrita somente uma vez, e, portanto, será alterada também somente uma vez, independente se a função ou procedimento estiver sendo usado uma ou mais vezes em um programa ou em programas diferentes. Uma outra vantagem da criação de funções e procedimentos, é o uso dos mesmos por diferentes programadores, evitando que um programado tenha que desenvolver uma lógica que já foi criada por outro programador. 14.1 – Diferença entre procedimento e função A principal diferença entre os procedimentos e as funções é na forma de uso e no resultado. Os procedimentos simplesmente substituem uma seqüência de comandos e representam uma linha de comando no programa Já as funções devem ser associadas a um comando do Pascal e o seu uso sempre produz um resultado. Exemplo 1, usando o procedimento val do pascal: DATA = '10/12/1980'; B := 0; C := 0; val(DATA,B,C); { DATA = '10/12/1980' , B = 0 , C = 3 } Perceba que neste primeiro exemplo, o procedimento val representa uma linha de comando. Exemplo 2, usando a função copy do pascal: C := 'AERODINÂMICA'; B := copy( C , 5 , 8 ) ; { B = 'DINÂMICA' } Perceba que neste segundo exemplo, a função copy está associada ao comando de atribuição (:=), e a sua execução retornará o valor ‘DINÂMICA’ para variável B. Apostila de LTP2 – Pascal - Air Rabelo 28 14.2 - Variáveis Globais e Locais Uma variável é considerada Global quando é declarada no início de um programa escrito em Pascal, podendo ser utilizada dentro de quaisquer procedimentos ou funções declarados neste programa. Uma variável é considerada Local quando é declarada dentro de uma função ou procedimento, portando, só é válida ali dentro onde foi criada. Desta forma, se uma variável é declarada dentro de uma função, as outras funções e procedimentos existentes e o programa principal não poderão fazer uso daquela variável, pois não visualizam a existência da mesma. 14.3 – Procedures Um procedimento é uma estrutura de programa autônoma que está incluída num programa em Pascal. Nele podem ser colocados todos os elementos da linguagem Pascal, como se fosse um programa completo. Um procedimento pode ser executado escrevendo simplesmente o seu nome seguido de um lista opcional de parâmetros (como no Exemplo 1, acima). Quando um procedimento é chamado em uma linha de comando, o controle de execução do programa é automaticamente transferido para o início do procedimento. As instruções de execução dentro do procedimento são então executadas, tendo em conta quaisquer declarações especiais que sejam únicas para o procedimento. Quando todas as instruções de execução tiverem sido executadas, o controle passa automaticamente para a instrução imediatamente a seguir à da chamada do procedimento. Sintaxe: procedure nome( parâmetro1:<tipo> ; parâmetro2:<tipo> ); var <variáveis> {variáveis Locais} begin <comandos> end; onde: nome é o nome atribuído ao procedimento parametros são informações adicionais que serão vistas mais tarde. tipo é o tipo de dado do parâmetro (ex: integer, real, string, ...) A linguagem Pascal exige que os procedimentos sejam declarados na área de declarações do programa, ou seja, antes do comando begin. Exemplo 1: program PROC_DEMO1; var X,Y : integer {variáveis globais} procedure SUBTRAI; begin X := X - 2; Y := Y - 1; end; begin X := 5; Y := 10; Apostila de LTP2 – Pascal - Air Rabelo 29 SUBTRAI; write(X,Y); end; { X => 3 , Y => 9} 14.4 - Parâmetros Os parâmetros têm por finalidade servir como um ponto de comunicação entre o procedimento/função e o programa principal. Desta forma, é possível passar valores de um programa para um procedimento/função através do uso de parâmetros. Dentro do procedimento/função os parâmetros funcionam como uma variável Local, ou seja, só podem ser utilizados dentro do procedimento/função. Exemplo 2: program PROC_DEMO2; var X,Y,W,Q : integer {variáveis globais} procedure SUBTRAI( A,B:integer); begin A := A - 2; B := B - 1; end; begin X := 5; Y := 10; W := 8; Q := 6; SUBTRAI(X,Y); write(X,Y); SUBTRAI(W,Q); write(W,Q); end; { X => 5 , Y => 10 } { W => 8 , Q => 6 } Neste exemplo a procedure SUBTRAI possui 2 parâmetros: A e B. Quando a procedure é executada no programa principal, deverão ser utilizados dois valores na chamada da procedure. O primeiro valor passado será transferido para o primeiro parâmetro da procedure (A) , e o segundo valor passado será transferido para o segundo parâmetro da procedure (B). Na primeira execução (SUBTRAI(X,Y);) o valor da variável X é o primeiro valor passado, portanto, este valor será transferido para o parâmetro A, e o valor da variável Y é o segundo valor passado, portanto, será transferido para o parâmetro B. Na segunda execução (SUBTRAI(W,Q);) o valor da variável W é o primeiro valor passado, portanto, este valor será transferido para o parâmetro A, e o valor da variável Y é o segundo valor passado, portanto, será transferido para o parâmetro B. Entretanto, após a execução da procedure SUBTRAI, os valores das variáveis passados como parâmetro (X e Y , W e Q) não sofreram nenhuma alteração, porque na procedure a subtração é feita nos parâmetros A e B, e isto não afeta os valores originais de X,Y,W e Q. Neste caso, para visualizar a subtração realizada na procedure, deverá ser inserido o comando write(A,B) dentro da procedure. Apostila de LTP2 – Pascal - Air Rabelo 30 Para que uma procedure/função altere o valor de uma variável global, utilizada na passagem de parâmetro, o parâmetro tem que ser declarado com parâmetro por referência. 14.5 – Parâmetros por Referência A passagem de parâmetro por referência caracteriza-se pela alteração do valor da variável utilizada na passagem de valor dentro do programa chamador da procedure/função. Toda vez que o parâmetro sofrer uma alteração de valor dentro da procedure/função, o valor da variável utilizado na chamada da procedure/função sofrerá a mesma alteração. Exemplo 3: program PROC_DEMO3; var X,Y,W,Q : integer {variáveis globais} procedure SUBTRAI(var A,B:integer); {parâmetro por referência=> var} begin A := A - 2; B := B - 1; end; begin X := 5; Y := 10; W := 8; Q := 6; SUBTRAI(X,Y); write(X,Y); SUBTRAI(W,Q); write(W,Q); end; { X => 3 , Y => 9 } { W => 6 , Q => 5 } Neste terceiro exemplo, os parâmetros da procedure foram declarados por referência (var). Desta forma, após a execução da procedure SUBTRAI(X,Y) e SUBTRAI(W,Q), os valores das variáveis passados como parâmetro (X e Y , W e Q) sofrerão as mesmas alterações que os respectivos parâmetros A e B sofrerem dentro da procedure. Sendo assim, a subtração feita no primeiro parâmetro (A) será também feita nas variáveis X e W. E a subtração feita no segundo parâmetro (B) será feita da mesma forma nas variáveis Y e Q. 14.6 – Functions Uma function, assim com uma procedure, é um bloco de programa, dentro do qual são válidas todos os comandos do Pasca. A diferença em relação a uma procedure está no fato de retornar sempre um valor. O valor de uma função é retornado no próprio nome da função, e pode ser numérico, lógico ou caracter. Sintaxe: function <nome> [(parâmetros)] : <tipo>; var <variaveis> ; {variáveis Locais} begin Apostila de LTP2 – Pascal - Air Rabelo 31 <comandos>; end; onde: nome é o nome atribuído a uma função, parâmetro é uma informação passada para a função tipo é o tipo de dado a ser retornado pela função. Exemplo 1: program FUNC_DEMO1; var VALOR : integer; fuction FATORIAL(N : integer):longint; var I : integer; begin FATORIAL := 1; for I:=1 to N do FATORIAL := FATORIAL * I; end; begin write('Digite um valor inteiro: '); readln(VALOR); writeln('o fatorial de ', VALOR, ' é: ', FATORIAL(VALOR) ); end. Neste exemplo, a função FATORIAL, possui o tipo longint, isto significa que o valor que ela retornará ao programa que a executou será um número do tipo longint (inteiro de tamanho grande). Neste exemplo a execução da função está contida dentro do próprio comando writeln, onde o valor exibido na tela será o resultado retornado pela função. Repare que o nome da função (FATORIAL) é utilizado dentro da própria função e recebe valores do tipo longint, que é o tipo do valor a ser retornado pela função. O ultimo valor assumido por FATORIAL será o valor que a função vai retornar para o programa que a executou. EXERCÍCIOS (parte 5): 1 – Fazer um programa para receber via teclado um NOME do tipo string. Em seguida o programa deverá exibir o nome digitado na tela após executar os seguintes procedimentos e funções: 1.1 – Criar um procedimento para Converter Nome para maiúsculo. 1.2 – Criar uma função para eliminar espaços em branco digitados à esquerda do Nome. 1.3 – Criar uma função para eliminar espaços em branco digitados à direita do Nome. 1.4 – Criar uma função para eliminar espaços em branco excessivos digitados entre as palavras do nome de tal forma que fique somente um espaço entre cada palavra. Obs: para eliminar caracteres de uma string, utilizar o procedimento DELETE: Apostila de LTP2 – Pascal - Air Rabelo 32 DELETE( Variável string , Posição , Num caracteres a deletar); 2 - Escreva uma procedure em pascal para desenhar na tela uma janela. A procedure deverá receber como parâmetro as coordenadas de linha/coluna superior esquerda e linha/coluna inferior direita. A partir destes parâmetros a procedure desenhará na tela uma janela começando na primeira coordenada e terminando na segunda coordenada. Exemplo: Coordenada 1 => Coluna = 5 , Linha = 3 Coordenada 2 => Coluna = 50 , Linha = 10 Resultado (considere o retângulo maior abaixo como sendo a tela do computador): 5 3 10 50 Para desenhar os caracteres necessários para a construção da Janela, use: Código ASCII Caracter 201 ╔ 186 ║ 200 ╚ 205 ═ 187 ╗ 188 ╝ 3 - Fazer um programa para receber via teclado o Nome do Empregado, o Código do Empregado, e o Número de Peças fabricadas em um determinado mês. O programa deverá imprimir uma lista, contendo o Nome do Empregado, o Salário e a Média de Salários da empresa. Para calcular o Salário, considerar: - 1 a 200 peças fabricadas – salário de R$ 2,00 por peça - 201 a 400 peças fabricadas – salário de R$ 2,30 por peça - acima de 400 peças fabricadas – salário de R$ 2,50 por peça No final do relatório, imprimir o total gasto em salários pela empresa. Apostila de LTP2 – Pascal - Air Rabelo 33 Observações: - O Código do Empregado e o Nome do Empregado são obrigatórios na digitação - O número de peças deverá ser maior que zero. - O código deverá ser formado por 5 caracteres sendo: - os 2 primeiros caracteres devem ser iguais às 2 primeiras letras do Nome do Empregado - os 3 últimos caracteres deverão ser dígitos. Ex: Nome do Empregado: MARCIO CAMPOS Código do Empregado: MA910 - Fazer uma função para calcular o Salário do Empregado - Parâmetro: número de peças - Retorno: salário - Fazer uma função para consistir o Código do Empregado - Parâmetro: código do empregado, as duas primeiras letras do Nome do Empregado. - Retorno: TRUE => se o valor estiver correto / FALSE => se o valor estiver incorreto - Adotar um flag para encerrar a entrada de dados. - Considerar o máximo de 100 empregados. Layout do relatório: Nome -------------------------------XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX Salário ---------999.99 999.99 999.99 999.99 Média Salários ------------------999.99 999.99 999.99 999.99 Total pago com salários: 9,999.99 4 - Fazer um programa para controlar contas de um Hotel. Receber via teclado o Nome do Hóspede, a Data de Entrada no Hotel, a Data de Saída do Hotel e o Tipo de Quarto. O programa deverá calcular a Conta do hóspede de acordo com a seguinte tabela: Tipo de Quarto STANDARD LUXO SUPER-LUXO Valor da Diária 120,00 150,00 180,00 O valor da conta será o valor da diária multiplicada pelo número de diárias da hospedagem. Para descobrir o número de diárias, subtrair o dia da data de saída do dia da data de entrada no hotel. Ex: Data de Entrada: 20/10/2008 Data de Saída: 25/10/2008 Tipo de Quarto: Luxo Cálculo do valor da conta: ( 25 – 20 ) * 150,00 = 750,00 O programa deverá imprimir no final um relatório com o Nome do hóspede e valor de todas as contas acima da média. Fazer uma função chamada DATA para consistir as datas de Entrada e Saída: - a função deverá receber como parâmetro uma data no formato DD/MM/AAAA - a consistência deverá seguir as seguintes regras: - para os meses de Janeiro, Março, Maio, Julho, Agosto, Outubro e Dezembro o dia deverá ser entre 01 e 31. - para os meses Abril, Junho, Setembro e Novembro o dia deverá ser entre 01 e 30. - para o mês de Fevereiro o dia deverá ser entre 01 e 28. Apostila de LTP2 – Pascal - Air Rabelo 34 - os mês deverá ser entre 01 e 12 - o ano deverá ser menor ou igual a 2010. - a função deverá retornar um valor do tipo Boolean. Caso a data recebida como parâmetro esteja de acordo com as regras acima, a função retornará o valor TRUE, caso contrário, retornará o valor FALSE. Fazer uma procedure para enviar mensagens de erro. A procedure receberá como parâmetro a mensagem a ser exibida, e exibirá tal mensagem na linha 24 e coluna 10 da tela. Esta procedure deverá ser usada para enviar mensagens em todas as consistências do programa. Obs: - Criar um flag para encerrar a entrada de dados. - O número máximo de hospedagens que o programa receberá será 100. - Consistir o tipo de quarto para aceitar somente os valores STANDARD, LUXO ou SUPER-LUXO. - O programa deverá consistir as datas de entrada e saída através da função DATA: - As datas de Entrada e de Saída serão digitadas no formato DD/MM/AAAA. - A data de saída deverá ser maior que a data de entrada - O mês e o Ano da data de entrada e de saída deverão ser iguais. Apostila de LTP2 – Pascal - Air Rabelo 35 15 – Registros e Arquivos de Dados Registro: - É um Conjunto de dados heterogêneos, ou seja, dados diferentes, porém relacionados a um mesmo objeto. Exemplo: Registro de Alunos da FUMEC, que contém os seguintes dados: - Nome do Aluno - Endereço do Aluno - Data de Nascimento - Sexo - ... Ou seja, são dados diferentes, mas todos relativos ao mesmo aluno. Arquivo de Dados: - Conjunto de registros seqüênciais armazenados em um dispositivo de armazenamento (ex: HD), gerenciado pelo Sistema Operacional, e manipulado através de programas que podem incluir, alterar, consultar ou excluir dados nos registros. Exemplo de um arquivo de registros: - Arquivo que contém os registros dos Alunos da FUMEC: No. Data Matrícula Nome Aluno Endereço Aluno Sexo Reg. Nascimento 0 054689 JOSE DA SILVA Cobre, 200 10/10/1980 M 1 025478 MARIA JOSÉ Afonso Pena, 100 20/12/1989 F 2 009871 SAULO JORGE Goitacazes, 1350 12/02/1992 M 3 (end of file) Obs: O número do registro não é um campo de dado do registro, portanto sempre começa do 0 (zero), é seqüencial e não pode ser alterado ou excluído. As linhas em um arquivo representam os registros As colunas em um arquivo representam os campos de dados (atributos) Os registros em um arquivo são numerados seqüencialmente a partir do número 0 (zero) As inclusões de novos registros são feitas sempre após o ultimo registro do arquivo, em uma área chamada de END OF FILE (final de arquivo) Para excluir um registro fisicamente no arquivo não é uma operação simples. Uma opção para isto é criar um novo arquivo, com nome diferente, e fazer um programa para copiar os registros desejados para este novo arquivo, não copiando os registros a excluir. Depois excluir todo o arquivo anterior e renomear o novo arquivo para o nome original daquele que foi excluído. Todos os campos de dados de um registro podem ser alterados. Os campos de dados de um registro deverão ser associados a um tipo de dado do Pascal (ex: String, real, integer,...) 15.1 - Declaração de Registros em um programa do Pascal: Exemplo: Apostila de LTP2 – Pascal - Air Rabelo 36 program registro_demo; uses CRT; type ALUNO = Record MATRICULA : string[6]; NOME_ALUNO: string[3]; END_ALUNO : string[40]; DT_NASC : string[10]; SEXO : char; End; var REGALUNO: ALUNO; ARQALUNO: file of ALUNO; 15.2 - Comandos, Procedimentos e Funções para Manipulação de Registros em Arquivos ASSIGN( ): Associa o nome da variável de arquivo declarada no programa com o nome do arquivo em disco Exemplo: assign(ARQALUNO, 'ALUNO.DAT'); { ARQALUNO => nome da variável de arq. no prog. ALUNO.DAT => nome do arquivo em disco } REWRITE(): Se o arquivo informado já existir no disco, este comando abre o arquivo, apaga todos os registros existentes e disponibiliza o arquivo para uso. Se o arquivo informado não existir no disco, ele cria o arquivo com o nome utilizado no comando ASSIGN, no diretório corrente, e disponibiliza o arquivo para uso. Exemplo: rewrite(ARQALUNO); {ARQALUNO => nome da variável de arq. no prog. } RESET(): Se o arquivo informado existir, ele abre o arquivo, posiciona o ponteiro de registros no primeiro registro do arquivo (o de no. zero), e disponibiliza o arquivo para uso. Se o arquivo informado não existir, retorna erro de execução de Entrada/Saída de dados (Input/Output error); Exemplo: reset(ARQALUNO); {ARQALUNO => nome da variável de arq. no prog. } Obs: O que é ponteiro de registros? É um apontador lógico que indica qual o registro será manipulado pelo programa, seja na inclusão, alteração ou consulta de dados no arquivo. Somente um registro pode ser manipulado por Apostila de LTP2 – Pascal - Air Rabelo 37 vez, portanto, só existe um ponteiro para cada arquivo, e ele aponta para apenas um registro por vez. Diretivas de Compilação Diretivas para Erros de Entrada e Saída de dados: {$I-} { Desabilita cancelamento do programa caso aconteça daqui para frente algum erro Entrada/Saída de dados (input/output) } {$I+} { Reabilita cancelamentos do programa caso aconteça daqui para frente algum erro Entrada/Saída de dados (input/output) } de de Exemplo ... {$I-} Reset(ARQALUNO); {$I+} ... IORESULT(): Função que informa se uma operação de entrada ou saída de dados (I/O) foi bem sucedida ou não. No caso de sucesso, o valor retornado pela função IORESULT será 0 (zero). No caso de erro na operação de entrada/saída, o valor retornado será maior que 0 (zero). Exemplo ... {$I-} reset(ARQALUNO); {$I+} if ioresult <> 0 then rewrite(ARQALUNO); {cria um novo arquivo vazio} ... CLOSE(): Comando para fechar o arquivo de dados salvando todos os dados contidos na memória. Exemplo Close(ARQALUNO); SEEK(): Comando que localiza um registro pelo seu número no arquivo de dados, e posiciona o ponteiro de registros naquele registro. Exemplo seek(ARQALUNO,5); {posiciona o ponteiro no registro de número 5} READ(): Apostila de LTP2 – Pascal - Air Rabelo 38 Comando que carrega os dados do registro corrente (aquele que o ponteiro estiver apontando), gravado no arquivo de dados para a memória, possibilitando assim a manipulação (consulta ou alteração) do mesmo pelos programas. Toda vez que o comando READ é utilizado, após a carga dos dados na memória a ponteiro de registros avança para o próximo registro. Exemplo read(ARQALUNO,REGALUNO); WRITE(): Comando que grava os dados do registro contido na memória no arquivo de dados. A gravação será feita substituindo os dados contidos no registro corrente do arquivo (aquele que o ponteiro estiver apontando. Exemplo write(ARQALUNO,REGALUNO); FILESIZE(): Função que retorna a quantidade de registros do arquivo de dados. Exemplo seek(ARQALUNO, filesize(ARQALUNO)); {posiciona o ponteiro na final do arquivo – end of file – local utilizado para inserir novos registros} FILEPOS(): Função que retorna o número do registro corrente (aquele o qual o ponteiro está apontando). Exemplo if filepos(ARQALUNO) > 0 then write(‘O registro corrente não é o primeiro !’); EOF(): Função que retorna o valor TRUE se o ponteiro está apontado para o final do arquivo – end of file, caso contrário retorna FALSE. Exemplo 1 if eof(ARQALUNO) then seek(ARQALUNO,0); {se estiver no final do arquivo, posiciona o ponteiro no inicio – registro Zero. Exemplo 2 Apostila de LTP2 – Pascal - Air Rabelo 39 {esta lógica exibirá na tela o nome de todos os alunos do arquivo ARQALUNO} seek(ARQALUNO,0); while not eof(ARQALUNO) do begin read(ARQALUNO,REGALUNO); write('Nome do Aluno: ', REGALUNO.NOME_ALUNO); end; 15.3 – Campo Chave de um registro Para localizar um registro em um arquivo de dados se utiliza o comado seek(), estudado no tópico anterior. Entretanto, o seek() só permite localizar um registro pelo número de seqüência do mesmo no arquivo, como este número é automático e interno, e também não representa um dado do registro, é inviável a que os usuários que desejam alterar, consultar ou excluir um registro utilize este número para localização do registro no arquivo. Então, um dos campos de dados deverá identificar um registro dentro do arquivo de dados. Para isto, este campo de dados não poderá conter valores repetidos em registros diferentes. Quando não é possível utilizar apenas um campo de dados que identifique um registro sem que os valores deste campo, em registros diferentes, se repitam, pode-se criar um campo específico para este fim. Outra forma seria utilizar mais de um campo para identificar o registro, sendo que juntos, os valores destes campos são exclusivos para cada registro do arquivo. A este campo exclusivo, que identifica um registro no arquivo, damos o nome de campo chave ou chave primária. Exemplo: type ALUNO = Record MATRICULA : NOME_ALUNO: END_ALUNO : DT_NASC : SEXO : End; string[6]; string[3]; string[40]; string[10]; char; Na estrutura de registro acima, qual dos campos poderia ser o campo chave ? - NOME_ALUNO => não poderia ser o campo chave porque é possível que exista mais de um aluno com o mesmo nome (homônimo), não sendo assim exclusivo para cada registro. - END_ALUNO, DT_NASC e SEXO, também não poderiam ser o campo chave pelo mesmo motivo do NOME_ALUNO - MATRICULA => a matrícula é o campo adequado para ser a chave primária, porque ela existe no registro do aluno exatamente para identificá-lo e diferenciá-lo de outros alunos, sendo assim, cada aluno terá uma matrícula diferente. Então usaremos a MATRICULA com campo chave para localizar um registro no arquivo. Exemplo de localização de um registro no arquivo: Obs: vamos o nome variável de arquivo ARQALUNO e da variável de registro REGALUNO Apostila de LTP2 – Pascal - Air Rabelo 40 readln(chave); {usuário digita a matricula a ser localizada} seek(arqaluno,0); {posicinar no início do arquivo} ENCONTROU := 'N'; while not eof(arqaluno) do begin read(arqaluno,regaluno); if (regaluno.matricula = chave) then begin write('Registro do Aluno encontrado ! '); ENCONTROU := 'S'; end; end; if ENCONTROU = 'N' then write('Registro do Aluno nao encontrado'); 15.4 – Exemplos de programas 15.4.1 - Exemplo 1: Programa para INCLUSÃO de dados em um registro de Estoque de Produtos gravado em um arquivo em disco de nome ITEM.DAT program INCLUSAO; uses crt; type item=record status: char; {quando o status for '*' indica registro excluído} codprod: string[5]; {código do produto} descricao: string[20]; {descricao do produto} quant: integer; {quantidade em estoque} preco: real; {preco unitario do produto} end; var arqitem: file of item; regitem: item; num: integer; resp: char; codprodaux: string[5]; valido: boolean; begin clrscr; assign(arqitem, 'item.dat'); {$I-} reset(arqitem); {$I+} if ioresult <> 0 then rewrite(arqitem); gotoxy(45,06); write('Inclusao no.'); gotoxy(20,04); write('Digite cod. produto = 00000 p/ fim'); gotoxy(08,08); write('Cod. produto..:'); gotoxy(08,10); write('Descricao.....:'); gotoxy(08,12); write('Quantidade....:'); gotoxy(08,14); write('Pre‡o.........:'); num:= 1; repeat gotoxy(58,06); write(num:3); Apostila de LTP2 – Pascal - Air Rabelo 41 repeat repeat gotoxy(28,08); readln(codprodaux); until codprodaux <> ''; if codprodaux = '00000' then break; valido:= true; seek(arqitem,0); while not eof(arqitem) do begin read(arqitem,regitem); if (codprodaux = regitem.codprod) and (regitem.status <> '*') then begin gotoxy(10,23); write('Inclusao invalida, codigo já cadastrado !'); readkey; gotoxy(10,23); clreol; valido:= false; gotoxy(28,08); clreol; break; end; end; until valido; regitem.codprod := codprodaux; if regitem.codprod = '00000' then break; gotoxy(28,10); readln(regitem.descricao); gotoxy(28,12); readln(regitem.quant); gotoxy(28,14); readln(regitem.preco); repeat gotoxy(10,23); write('Confirma a Inclusao ? (S/N) '); readln(resp); until resp in ['N','n','S','s']; if upcase(resp) = 'S' then begin regitem.status := ' '; seek( arqitem, filesize(arqitem)); write(arqitem,regitem); num := num + 1; end; gotoxy(28,08); clreol; gotoxy(28,10); clreol; gotoxy(28,12); clreol; gotoxy(28,14); clreol; gotoxy(10,23); clreol; until regitem.codprod = '00000'; close(arqitem); end. 15.4.2 - Exemplo 2: Programa para ALTERAÇÃO de dados em um registro de Estoque de Produtos gravado em um arquivo em disco de nome ITEM.DAT program alteracao; uses crt; type item=record status: char; codprod: string[5]; {quando o status for '*' indica registro excluído} {código do produto} Apostila de LTP2 – Pascal - Air Rabelo 42 descricao: string[20]; {descricao do produto} quant: integer; {quantidade em estoque} preco: real; {preco unitario do produto} end; var arqitem: file of item; regitem: item; chave: string[5]; resp: char; begin clrscr; gotoxy(25,02); write('PROGRAMA DE ALTERACAO DE PRODUTOS'); assign(arqitem,'item.dat'); {$I-} reset(arqitem); {$I+} if ioresult <> 0 then begin gotoxy(10,23); write('O arq. nao existe ou esta’ corrompido!'); readkey; halt; end; gotoxy(02,05); write('Digite Codigo Produto = 00000 para encerrar o programa'); gotoxy(02,08); write('Codigo Produto:'); gotoxy(02,10); write('Descricao.....:'); gotoxy(02,12); write('Quantidade....:'); gotoxy(02,14); write('Preco.........:'); repeat gotoxy(18,08); readln(chave); if chave='00000' then break; seek(arqitem,0); while not eof(arqitem) do begin read(arqitem,regitem); if (regitem.codprod = chave) and (regitem.status <> '*') then begin gotoxy(18,10); write(regitem.descricao); gotoxy(18,12); write(regitem.quant:3); gotoxy(18,14); write(regitem.preco:6:2); gotoxy(45,10); write('Nova Descr:'); gotoxy(57,10); readln(regitem.descricao); gotoxy(45,12); write('Nova quant:'); gotoxy(57,12); readln(regitem.quant); gotoxy(45,14); write('Novo pre‡o:'); gotoxy(57,14); readln(regitem.preco); repeat gotoxy(10,23); write('Confirma a alteracao? (S/N):'); readln(resp); until resp in ['S','N','s','n']; gotoxy(10,23);clreol; if upcase(resp) = 'S' then begin seek(arqitem,filepos(arqitem)-1); write(arqitem,regitem); seek(arqitem,filepos(arqitem)-1); end; Apostila de LTP2 – Pascal - Air Rabelo 43 break; end; end; if eof(arqitem) then begin gotoxy(10,23); write('Registro nao encontrado'); readkey; gotoxy(10,23); clreol; end; gotoxy(18,08);clreol; gotoxy(18,10);clreol; gotoxy(18,12);clreol; gotoxy(18,14);clreol; until chave = 'FIM'; close(arqitem); end. 15.4.3 - Exemplo 3: Programa para CONSULTA de dados em um registro de Estoque de Produtos gravado em um arquivo em disco de nome ITEM.DAT program consulta; uses crt; type item=record status: char; {quando o status for '*' indica registro excluído} codprod: string[5]; {código do produto} descricao: string[20]; {descricao do produto} quant: integer; {quantidade em estoque} preco: real; {preco unitario do produto} end; var arqitem: file of item; regitem: item; resp: char; chave: string[5]; opcao: char; linha: integer; begin clrscr; gotoxy(15,1); write('Programa de Consulta'); assign(arqitem, 'item.dat'); {$I-} reset(arqitem); {$I+} if ioresult <> 0 then begin gotoxy(10,25); write('Erro na abertura do arquivo !'); readkey; halt; end; gotoxy(08,03); write('[0] Para sair da Consulta'); gotoxy(08,04); write('[1] Para Consulta em Lista'); gotoxy(08,05); write('[2] Para Consulta de 1 produto'); gotoxy(08,06); write('Digite sua opcao: '); Apostila de LTP2 – Pascal - Air Rabelo 44 gotoxy(01,08); write('Codigo-- Descricao----------- Quant--- Preco---'); repeat repeat gotoxy(26,06); opcao:= readkey; gotoxy(26,06); write(opcao); until opcao in ['0'..'2']; case opcao of '2': begin gotoxy(45,05); write('Codigo...: '); gotoxy(56,05); readln(chave); seek(arqitem,0); while not eof(arqitem) do begin read(arqitem,regitem); if (regitem.codprod = chave) and (regitem.status <> '*') then begin gotoxy(01,09); write(regitem.codprod); gotoxy(10,09); write(regitem.descricao); gotoxy(33,09); write(regitem.quant:5); gotoxy(42,09); write(regitem.preco:6:2); gotoxy(10,23); write('Digite <ENTER> para continuar'); readkey; gotoxy(10,23); clreol; gotoxy(01,09); clreol; break; end; end; if eof(arqitem) and (regitem.codprod <> chave) then begin gotoxy(10,23); write('Produto nao encontrado no arquivo'); readkey; gotoxy(10,23); clreol; end; gotoxy(45,05); clreol; end; '1': begin seek(arqitem,0); linha := 9; while not eof(arqitem) do begin read(arqitem,regitem); if regitem.status <> '*' then begin gotoxy(01,linha); write(regitem.codprod); gotoxy(10,linha); write(regitem.descricao); gotoxy(33,linha); write(regitem.quant:5); gotoxy(42,linha); write(regitem.preco:6:2); linha := linha + 1; if (linha = 24) and not (eof(arqitem)) then begin gotoxy(10,24); write('<ENTER> para a pr¢xima tela'); readkey; for linha := 9 to 24 do begin gotoxy(01,linha); clreol; Apostila de LTP2 – Pascal - Air Rabelo 45 end; linha := 9; end; end; end; gotoxy(10,24);write('tecle <ENTER> para continuar'); readkey; for linha := 9 to 24 do begin gotoxy(01,linha); clreol; end; end else break; end; gotoxy(26,06); clreol; until opcao = '0'; close(arqitem); end. 15.4.4 - Exemplo 4: Programa para EXCLUSÃO de dados em um registro de Estoque de Produtos gravado em um arquivo em disco de nome ITEM.DAT Obs: como a exclusão física de registros é uma operação complexa e demorada, normalmente o que se faz é uma exclusão lógica dos registros. No programa abaixo, a exclusão lógica se trata apenas de alterar o valor do campo STATUS para o valor '*' (asterisco). Sendo assim, nos programas de inclusão, alteração, consulta e no próprio de exclusão, toda vez que um registro tiver o valor do campo STAUTUS = '*', este registro será ignorado e tratado como se não existisse, ou seja, está excluído ! Program exclusao; uses crt; type item = record status: char; {quando o status for '*' indica registro excluído} codprod: string[5]; {código do produto} descricao: string[20]; {descricao do produto} quant: integer; {quantidade em estoque} preco: real; {preco unitario do produto} end; var arqitem: file of item; regitem: item; resp:char; chave: string[5]; begin clrscr; gotoxy(15,1); write('Programa de Exclusao'); assign(arqitem,'item.dat'); {$I-} reset(arqitem); {$I+} if ioresult <> 0 then begin gotoxy(10,25); write('Erro na abertura do arquivo ! <ENTER>'); readkey; Apostila de LTP2 – Pascal - Air Rabelo 46 halt; end; gotoxy(10,20);write('Digite codigo = FIM para encerrar o programa'); gotoxy(08,06);write('Codigo......:'); gotoxy(08,08);write('Descricao...:'); gotoxy(08,10);write('Quantidade..:'); gotoxy(08,12);write('Preco.......:'); repeat gotoxy(22,06);readln(chave); if chave = 'FIM' then break; seek(arqitem,0); while not eof(arqitem) do begin read(arqitem,regitem); if (regitem.codprod = chave) and (regitem.status <> '*') then begin gotoxy(22,08);write(regitem.descricao); gotoxy(22,10);write(regitem.quant:3); gotoxy(22,12);write(regitem.preco:6:2); repeat gotoxy(10,23);write('Confirma exclusao ? (S/N) '); readln(resp); until resp in ['s','S','n','N']; gotoxy(10,23);clreol; seek(arqitem,filepos(arqitem)-1); if upcase(resp) = 'S' then begin regitem.status:='*'; write(arqitem,regitem); seek(arqitem,filepos(arqitem)-1); gotoxy(10,23); write('Registro excluido com sucesso ! <ENTER>'); readkey; gotoxy(10,23);clreol; end; break; end; end; if eof(arqitem) then begin gotoxy(10,23);write('Codigo de produto nao encontrado ! <ENTER>'); readkey; gotoxy(10,23);clreol; end; gotoxy(22,08);clreol; gotoxy(22,10);clreol; gotoxy(22,12);clreol; until chave = 'FIM'; close(arqitem); end. Apostila de LTP2 – Pascal - Air Rabelo 47 EXERCÍCIOS (parte 6): 1 - Fazer um programa para incluir dados em um arquivo de Clientes de uma Empresa, de acordo com a estrutura de registro abaixo: STATUS CODCLI NOMECLI VLRCOMPRA ANO_PRIM_COMPRA EM_DIA Obs: -> -> -> -> -> -> CHAR INTEGER STRING[30] REAL INTEGER BOOLEAN - gravar '*' na exclusão código do cliente nome do cliente valor da compra ano que o cliente fez a primeira compra se o cliente está em dia com o pagamento - utilizar o campo CODCLI como campo chave primária. - utilizar o nome ARQCLI para a variável de arquivo - utilizar o nome REGCLI para a variável de registro CONSISTÊNCIAS: - o nome do cliente é de preenchimento obrigatório. - o código do cliente deve ser número inteiro e maior que (zero). - o valor da compra deve ser maior que zero. - o ano da primeira compra dever ser menor ou igual a 2011. - EM_DIA: por ser um campo do tipo boolean (lógico), no arquivo este campo deve ser preenchido com o valor TRUE ou FALSE. Entretanto, como não é possível utilizar o comando readln em variáveis do tipo boolean, deverá ser criada uma variável auxiliar, tipo char por exemplo, e solicitar ao usuário que responda a pergunta: ('Cliente está em dia (S/N)?'). Se a resposta for 'S', atribuir TRUE ao campo REGCLI.EM_DIA, caso contrário, atribuir o valor FALSE - Quando o CODCLI for digitado, verificar no arquivo se já existe algum outro registro que já possua o CODCLI informado, e com REGCLI.STATUS <> '*'(registro não excluído). Caso existir, mostrar uma mensagem de erro ('Cliente já cadastrado ! '), e não permitir a inclusão. 2 - Fazer os programas para alterar, consultar e excluir dados dos registros no arquivo do exercício anterior. Apostila de LTP2 – Pascal - Air Rabelo 48