Manual de PL1 - Completo

189
┌───────────────────────────────────────────────────────────────────────┐ |***********************************************************************| |***********************************************************************| |***********************************************************************| |*********** ***************************************************| |*********** **************************************************| |*********** **** **************************************************| |*********** **** **************************************************| |*********** **** *******************************************| |*********** ***** *******************************************| |*********** *********** *******************************************| |*********** *********** *******************************************| |*********** *********** ****************** **********************| |************************* ***************** ***********************| |************************* **************** ************************| |************************* ******** *************************| |************************* ******* ******** ***********| |***************************************** ********* ***********| |**************************************** ************ *************| |*************************************** ************* *************| |************************************** ************** *************| |******************************************************* *************| |******************************************************* *************| |***************************************************** ***********| |***************************************************** ***********| |***********************************************************************| |***********************************************************************| |************************************************ VERSAO UNICA *******| |***********************************************************************| |***********************************************************************| |***********************************************************************| |***********************************************************************| |*************** ************************| |***********************************************************************| |***********************************************************************| └───────────────────────────────────────────────────────────────────────┘ ┌───────────────────────────────────────────────────────────────────────┐ | | | ANALISTA : _______________________________________________ | | | | | | DEPARTAMENTO : ______________________________________ | | | | ANDAR : _____ SALA : _____ | | | └───────────────────────────────────────────────────────────────────────┘ 1 Page 1

description

PL/I ("Programming Language One", ) is a procedural

Transcript of Manual de PL1 - Completo

Page 1: Manual de PL1 - Completo

┌───────────────────────────────────────────────────────────────────────┐|***********************************************************************||***********************************************************************||***********************************************************************||*********** ***************************************************||*********** **************************************************||*********** **** **************************************************||*********** **** **************************************************||*********** **** *******************************************||*********** ***** *******************************************||*********** *********** *******************************************||*********** *********** *******************************************||*********** *********** ****************** **********************||************************* ***************** ***********************||************************* **************** ************************||************************* ******** *************************||************************* ******* ******** ***********||***************************************** ********* ***********||**************************************** ************ *************||*************************************** ************* *************||************************************** ************** *************||******************************************************* *************||******************************************************* *************||***************************************************** ***********||***************************************************** ***********||***********************************************************************||***********************************************************************||************************************************ VERSAO UNICA *******||***********************************************************************||***********************************************************************||***********************************************************************||***********************************************************************||*************** ************************||***********************************************************************||***********************************************************************|└───────────────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────────────┐| || ANALISTA : _______________________________________________ || || || DEPARTAMENTO : ______________________________________ || || ANDAR : _____ SALA : _____ || |└───────────────────────────────────────────────────────────────────────┘

1

Page 1

Page 2: Manual de PL1 - Completo

Page 2

1. CONCEITOS BASICOS ____________________

1.1 NOCOES ELEMENTARES ______________________

Assim como o FORTRAN e' particularmente uma linguagem adaptada 'a programacao de problemas matematicos e o COBOL se adapta particularmente 'a programacao de problemas comerciais,o PL/I,tendo-se baseado nas linguagens Fortran e Cobol,se adapta 'a programacao de ambos problemas.

Uma linguagem de computador e' como qualquer idioma com sua sintaxe: tem vocabulario,regras gramaticais e de pontuacao.

Entende-se por sintaxe de uma linguagem de programacao a correta arrumacao de seus elementos,respeitando-se regras,que serao vistas no decorrer desta apresentacao.

Ao contrario do que muita gente pensa,os computadores nao pensam.Sao ma- quinas capazes de executarem muitas operacoes, desde que especificamentE instruidas nesse sentido;para que se possa comunicar com elas,e' preciso saber usar suas linguagens.

De maneira geral,pode-se conceituar Programador,Programa e Instrucao como sendo:

® Instrucao - comando ou diretriz dada ao computador para que ele execute uma operacao especifica.

® Programa - sequencia de instrucoes que podem ser seguidas pelo compu- tador.

® Programador - pessoa que planeja as operacoes que podem ser seguidas pelo computador.

Na linguagem PL/1,os programas sao escritos por meio de expressoes e co- mandos basicos,que sao agrupados para formar o que se denomina PROCEDIMENTOS(Procedures).

Os procedimentos,por sua vez,podem ser formados por conjuntos de comandos denominados "Blocos BEGIN",e/ou "Grupos DO".Mais adiante esses conjuntos serao vistos com mais detalhes.

Varios procedimentos(Procedures) podem ser compilados separadamente e considerados juntos para formar um so' programa, enquanto que um bloco BEGIN ou um grupo DO nao,estes devem estar contidos em um 'procedimento'.

Todo programa escrito em PL/1 tem que apresentar pelo menos um PROCEDIMENTO principal, que contem, como seu primeiro comando, o conjunto de palavras LABEL: PROCEDURE OPTIONS(MAIN), onde label e' o nome do procedimento e e' constituido de um conjunto de caracteres de no maximo 7 elementos(ver-se-ao,mais adiante,as regras que regem sua formacao ) e,como seu ultimo comando,o conjunto de palavras END LABEL, onde Label

1. CONCEITOS BASICOS

Page 3

Page 3: Manual de PL1 - Completo

e'o mesmo usado no primeiro comando e o seu uso e' opcional neste co- mando.

O "Procedimento" principal e' invocado automaticamente pelo Sistema Ope- racional da instalacao,enquanto que os outros sao por meio de comandos apropriados contidos em outros procedimentos ou no principal.

1.2 FORMULARIO DE PROGRAMACAO _____________________________

Normalmente,o PL/1 usa,para efeito de compilacao,apenas as colunas 2 a 72,inclusive do formulario de codificacao de programacao,sendo que as colunas 73 a 80 servem para numeracao ou documentacao dos comandos.O com- pilador apenas ignora essas posicoes, como tambem a coluna 1,que pode ser usada para controle do carro impressor na listagem do programa-fonte.

A linguagem PL/1 permite escrever seus comandos em fileira continua, com mais de um comando por linha, denominado formato "string",ou usando o chamado formato identado,com apenas um comando por linha,ou ainda uma combinacao dos dois tipos de formatos.

Esses formatos nao tem influencia, na execucao do programa;o importante e' saber que o PL/1 entende os comandos como colocados sequencialmente, um apos o outro.

Por exemplo:

® Formato "string"

Label: PROC OPTIONS(MAIN);COMANDO-1;COMANDO-2;....... ....COMANDO-S;...COMANDO-S+1;...COMANDO-R;COMANDO-(N-2); COMANDO-(N-1);COMANDO-N;END Label;

® Formato identado

Label: PROC OPTIONS(MAIN); COMANDO-1; COMANDO-1; .... COMANDO-S; COMANDO-S+1; .... COMANDO-(N-1); COMANDO-N; END Label;

® Formato combinado

Label: PROC OPTIONS(MAIN); COMANDO-1;COMANDO-2;

1. CONCEITOS BASICOS

Page 4

COMANDO-3; COMANDO-4;

COMANDO-N-1; COMANDO-N;END Label;

1.3 CONCEITO DE COMANDO _______________________

Em geral um comando em PL/1 e' formado de tres partes: Identificador de comando,Corpo de comando e Ponto-e-virgula, onde o identificador de co-

Page 4: Manual de PL1 - Completo

mando e' a palavra chave do comando. Alguns, porem, apresentam-se sem essa parte. Sao os chamados Comandos de Atribuicao,isto e',so possuem o corpo de comando e o ponto-e-virgula. Ainda ha' o comandoque so' apresenta uma parte, o chamado comando nulo, formado pelo ponto-e- virgula.

Eis alguns exemplos:

GOTO SEGUE; palavra-chave GOTO e corpo de comando SEGUE A = B + C; corpo de comando A = B + C DCL A DECIMAL FIXED; palavra-chave DCL e corpo de comando A DECIMAL FIXED

1.4 LABEL OU ROTULO DE COMANDO _______________________________

Nao e' um componente de comandos.Pode ser usado pelo programador para identificar um comando numa listagem do programa e/ou para que ele seja referenciado no mesmo,por um outro comando.Esta' sempre separado do co- mando por dois pontos.

Como exemplo,pode-se escrever:

CONTINUA: ; ---> comando nulo CORRE: I = I + 1; ---> comando de atribuicao

onde os Labels ou rotulos usados foram CONTINUA e CORRE.

1.5 EXEMPLO DE UM PROGRAMA EM PL/1 __________________________________

A seguir tendo um programa que se propoe a ler um conjunto de 10 valores perfurados em cartao,cuja ordem de grandeza de cada um nao ultrapasse 9.99,calcular seus quadrados e imprimir todos os valores lidos e calcu- lados.

1. CONCEITOS BASICOS

Page 5

PROG: PROC OPTIONS(MAIN); DCL A FIXED(3,2); DO I = 1 TO 10; GET FILE(SYSIN) LIST(A); B = A*A; PUT FILE(SYSPRINT) DATA(A,B); END; END PROG;

1.6 IDENTIFICADORES ___________________

No exemplo acima,certos nomes nao constituem palavras-chaves de comando,como,por exemplo,A,I e B - sao os nomes criados pelo programador e sao chamados IDENTIFICADORES.

Assim,IDENTIFICADORES sao os nomes criados pelo programador e usados na escrita de um programa em PL/1,e sao dados aos rotulos de comandos, aos procedimentos,'as variaveis,aos blocos de comando,etc.

Para se criar um identificador, e' necessario saber quais os caracteres que deverao ser usados e quais as regras para sua formacao.

Vejam-se, primeiramente os conjuntos de caracteres existentes na linguagem, e, a seguir, as regras para formar os identificadores.

Page 5: Manual de PL1 - Completo

1.7 CONJUNTOS DE CARACTERES ___________________________

Existem dois grupos de caracteres disponiveis para a linguagem PL/1: o conjunto de 48 e o de 60 caracteres(ver Fig.1.1).

O PL/I-Basico usa o conjunto de 48 caracteres. O PL/I-Full e o Optimizing,apesar de usarem o conjunto de 60 caracteres, tambem permitem o uso do conjunto de 48 caracteres.

Quando se usa o conjunto de 60 caracteres,nao ha' palavras reservadas Quando se usa o conjunto de 48 caracteres,algumas palavras sao reservadas ao compilador para um fim especifico,como por exemplo,LE,GT,NL, etc.,nao podendo,pois ser usadas como identificadores;elas sao usadas como ope- radores em expressoes matematicas,significando,respectivamente, MENOR OU IGUAL,MAIOR DO QUE e NAO MENOR.

Eles se dividem em tres grupos: Alfabeticos,Numericos e Especiais, sendo que os dois primeiros constituem o grupo dos Alfanumericos.

Tem-se,entao,a seguinte distribuicao de caracteres para os dois conjun- tos: . . │ 29 caracteres alfabeticos

1. CONCEITOS BASICOS

Page 6

│ - de 60 │ 10 caracteres numericos │ │ 21 caracteres especiais . .

. . │ 27 caracteres alfabeticos │ - de 48 │ 10 caracteres numericos │ │ 11 caracteres especiais . .

1. CONCEITOS BASICOS

Page 7

_______________________________________________________________ │ │ │ │ │ │ Classificacao │ 60 caracteres │ 48 caracteres │ Descricao │ │_______________│________________│________________│_____________│

Page 6: Manual de PL1 - Completo

│ │ │ │ │ │ │ A a Z │ A a Z │ alfabetico │ │ │ $ │ $ │ alfabetico │ │ Alfanumericos │ @ e # │ nao disponivel │ alfabetico │ │ │________________│________________│_____________│ │ │ │ │ │ │ │ 0 a 9 │ 0 a 9 │ numerico │ │ │________________│________________│_____________│ │ │ │ │ │ │ │ │ │ branco │ │ │ = │ = │ igual │ │ │ + │ + │ mais │ │ │ - │ - │ menos │ │ │ * │ * │ vezes ou ast│ │ │ / │ / │ divisao ou │ │ │ │ │ barra │ │ │ ( │ ( │ abre paren- │ │ │ │ │ teses │ │ │ ) │ ) │ fecha paren-│ │ │ │ │ teses │ │ │ , │ , │ virgula │ │ │ . │ . │ ponto │ │ Especiais │ ' │ ' │ apostrofo │ │ │ % │ // │ percentual │ │ │ : │ .. │ dois pontos │ │ │ ; │ ,. │ ponto e vir-│ │ │ │ │ gula │ │ │ ¬ │ NOT │ nao │ │ │ & │ AND │ e │ │ │ │ │ OR │ ou │ │ │ < │ LT │ menor que │ │ │ > │ GT │ maior que │ │ │ _ │ nao disponivel │ travessao │ │ │ ? │ nao disponivel │ interrogacao│ │_______________│________________│________________│_____________│

Fig. 1.1

1. CONCEITOS BASICOS

Page 8

_________________________________________________________ │ │ │ 60 caracteres 48 caracteres │ │_________________________________________________________│ │ │ 1 │ @ nao ha' correspondente │ 2 │ # nao ha' correspondente │ 3 │ - nao ha' correspondente │ 4 │ ? nao ha' correspondente │ 5 │ % // │ 6 │ : .. │ 7 │ ; ,. │ 8 │ > GT │ 9 │ < LT │ 10 │ ¬ NOT │ 11 │ │ OR │ 12 │ & AND │ │_________________________________________________________│

Fig 1.2

O conjunto de 48 caracteres e' formado pela omissao de 12 do de 60, que constituem a Fig 1.2,a qual tambem mostra as combinacoes de caracteres do

Page 7: Manual de PL1 - Completo

conjunto de 48 que substituem 8 desses 12,uma vez que para os 4 primeiros nao ha correspondentes.

1. CONCEITOS BASICOS

Page 9

1.8 REGRAS DOS IDENTIFICADORES ______________________________

Os identificadores sao regidos pelas seguintes regras:

® o primeiro carater de um identificador tem que ser alfabetico e,os demais,alfanumericos;

® o unico carater especial que pode ser usado num identificador e' o "travessao" (_);

® o comprimento maximo de um identificador e' de 31 caracteres,havendo algumas excecoes,como por exemplo,nos nomes de "procedimentos",que nao podem ultrapassar 7 caracteres(conforme visto anteriormente).

Eis alguns exemplos de identificadores:

B123B formado por 5 caracteres AAAAAA formado por 6 caracteres AULA formado por 4 caracteres NUM_AULA formado por 8 caracteres QUANT formado por 5 caracteres $ formado por 1 caracteres $3 formado por 2 caracteres PROG_FONTE_NUM_DOIS formado por 19 caracteres

1. CONCEITOS BASICOS

Page 10

2. OPERACOES E EXPRESSOES _________________________

2.1 INTRODUCAO ______________

A exemplo da Matematica,quando se reunem variaveis,constantes e operadores,forma-se o que se denomina expressao.

A*2+B e' um exemplo de uma expressao onde as letras A e B sao as

Page 8: Manual de PL1 - Completo

variaveis,o numero 2 a constante e os sinais * e + os operadores, representando,respectivamente,a multiplicacao e a soma.

Em PL/1,as variaveis sao identificadores,isto e', sao nomes criados pelo programador,as constantes sao valores numericos autodefinidos e os ope- radores sao simbolos que se verao a seguir.

Os operandos de uma expressao sao as variaveis e as constantes,tambem chamadas de "variaveis de elemento" e "dados de elementos",dai a denominacao "expressao de elemento".

2.2 OPERADORES ______________

Os operadores se classificam por tipo de operacao,podendo ser aritmeticos,de comparacao,logicos e de concatenacao.

Para os sinais + e - existe ainda a classificacao de Infixos e Prefixos.Sao ditos Prefixos quando eles precedem um operando ou uma expressao,e dizem-se Infixos quando ligam duas expressoes ou subexpressoes.

No exemplo(-A+B),o sinal menos e' um prefixo e o sinal + um infixo.

Com base nesse conceito,existe uma regra que diz :

Numa expressao de elementos,so podem existir dois operadores adjacentes se um deles for operador prefixo,e mais de dois operadores adjacentes se todos eles forem prefixos,com excecao de um,que sera' infixo.

2. OPERACOES E EXPRESSOES

Page 11

________________________________________________________________ │ │ │ │ │ Tipo de │ Simbolo de operacao │ │ │ │_____________________________│ Descricao │ │ operacao │ │ │ │ │ │ 60 caracteres│ 48 caracteres│ │ │______________│______________│______________│___________________│ │ │ │ │ │ │ │ + │ + │ soma ou prefixo + │ │ │ - │ - │ subtracao ou pre- │ │ Aritmetica │ │ │ fixo - │ │ │ * │ * │ multiplicacao │ │ │ / │ / │ divisao │ │ │ ** │ ** │ exponenciacao │ │______________│______________│______________│___________________│ │ │ │ │ │ │ │ > │ GT │ maior que │ │ │ >= │ GE │ maior ou igual │ │ │ = │ = │ igual │ │ Comparacao │ ¬= │ NE │ nao igual │ │ │ <= │ LE │ menor ou igual │ │ │ < │ LT │ menor que │ │ │ ¬> │ NG │ nao maior que │ │ │ ¬< │ NL │ nao menor que │ │______________│______________│______________│___________________│ │ │ │ │ │ │ │ ¬ │ NOT │ nao │ │ Logica │ │ │ OR │ ou │

Page 9: Manual de PL1 - Completo

│ │ & │ AND │ e │ │______________│______________│______________│___________________│ │ │ │ │ │ │ Concatenacao │ ││ │ CAT │ concatenacao │ │______________│______________│______________│___________________│

Fig 2.1

Eis alguns exemplos que explicam a regra apresentada:

1) 12 * -2 -->(+12) * (-2) o sinal de menos e' um prefixo; 2) A ++ B -->(+A) + (+B) o 2o. sinal de + e' um prefixo; 3) C ** -1 -->(+C) ** (-1) o sinal de menos e' um prefixo; 4) 20 + - -A -->(+20)+(-(-A)) os sinais de menos sao prefixos;

Se uma expressao de elementos contem operadores aritmeticos,ela especi- fica uma operacao aritmetica;se ela contem operadores de comparacao,especifica uma operacao de comparacao;se contem operadores logicos,especifica uma operacao logica;se contem operadores de concatenacao,especifica uma operacao de concatenacao;e,se contem varios tipos de operadores especifica uma operacao mista.

Eis alguns exemplos:

2. OPERACOES E EXPRESSOES

Page 12

1) operacao aritmetica -A+B*-C**2 2) operacao de comparacao B GT A ou B>A 3) operacao logica (C&A) │ D ou (C AND A) OR D 4) operacao de concatenacao C ││ E ou C CAT E 5) operacao mista (A+(B>A)*(B-A))│(C<D)

2.3 HIERARQUIA DAS OPERACOES ____________________________

As operacoes,em uma expressao de elemento,obdecem a uma certa ordem hierarquica em suas execucoes.

A Fig. 2.2 mostra a ordem de prioridade em que elas sao executadas.

_______________________________________________________________ │ │ │ │ │ │ │ │ │ │ Prioridades│ 1a │ 2a│ 3a│ 4a│ 5a │ 6a│7a │ │____________│_______│___│___│___│______________________│___│___│ │ │ │ │ │ │ │ │ │ │ Operadores │ ** + -│ /*│ +-│ │││ = >= <= > < ¬= ¬> ¬< │& │ │ │ │____________│_______│___│___│___│______________________│___│___│

Fig 2.2

Com excecao das operacoes de 1a. prioridade,a ordem hierarquica das operacoes e' da esquerda para a direita,respeitando-se as prioridades existentes em cada termo da expressao.Os sinais + e - na 1a. prioridade sao prefixos e os da 3a. sao infixos.

O uso dos parenteses em uma expressao de elemento modifica a prioridade automatica existente.

As operacoes entre parenteses sao efetuadas em primeiro lugar,indo do par de parenteses mais interno ao mais externo.

Observem-se os seguintes exemplos:

1) -A**2 e' diferente de (-A)**2, de uma vez que so' havendo um termo nessa expressao os dois operadores pertencem ao grupo de prioridades 1;

Page 10: Manual de PL1 - Completo

assim sendo,as expressoes serao efetuadas da direita para a esquerda. Essa expressao e' exatamente igual a -(A**2)

2) -A+B*-C**2 e' a mesma expressao que (-A)+(B*(-(C**2)))

3) A/B*C e' o mesmo que ((A/B)*C)

4) A expressao que exprime a sentenca: o resultado de X ou Y nao e' igual a A concatenado com B e' dada por :

(X│Y) ¬= (A││B) ou,usando o conjunto de 48 caracteres:

2. OPERACOES E EXPRESSOES

Page 13

(X OR Y) NE (A CAT B)

5)

3**1**2 = 3**(1**2) = 3 3**2*3 = (3**2)*3 = 27 3*2**3 = 3*(2**3) = 24

2.4 EXPRESSAO ARITMETICA ________________________

Ja' foi visto que uma expressao aritmetica e' aquela que usa operadores aritmeticos.O resultado de uma expressao aritmetica sera' o valor da expressao quando forem atribuidos valores de "constantes" 'as variaveis que compoem a expressao.

Por exemplo,na expressao A+B**2,se se tiver para o A o valor 1 e para B o valor 3,obter-se-a' como resultado o valor 10,pois,substituindo na expressao,tem-se: (1+3**2=10).

2.5 EXPRESSAO DE COMPARACAO ___________________________

Uma expressao de comparacao e' aquela que envolve operacao de comparacao e o seu resultado sera' um bit 1 ou um bit 0,se a relacao especificada entre os operandos for real ou falsa,respectivamente.

Por exemplo, se A GT C for verdadeiro,essa expressao tera' para resultado o valor 1, e se for falso, ou seja, se A nao for maior que C, tera' para resultado o valor 0.

2.6 EXPRESSAO LOGICA - STRING DE BITS _____________________________________

Uma expressao logica e' aquela cujos operadores sao logicos.

Antes,porem,de ver qual seu resultado,deve-se conceituar o que se entende por "Bit String"(string de bits).

Pode-se definir um string de bits como sendo uma sequencia de digitos bi- narios entre apostrofos e imediatamente seguida pela letra B,como,por exemplo,'110001111000001'B

Uma operacao logica e' efetuada em sequencia,da esquerda para a direita,em cada bit dos dois Bit String operandos,e o resultado sera um Bit String.

2. OPERACOES E EXPRESSOES

Page 11: Manual de PL1 - Completo

Page 14

Por exemplo,seja a seguinte expressao logica: '1001'B & '0110'B

O resultado sera' o Bit String '0000'B.

Para melhor compreender a operacao logica,veja-se a seguir uma figura onde estao especificadas todas as operacoes logicas possiveis entre dois strings de bits(Fig 2.3).

___________________________________ │ │ │ │ │ │ │ │ A │ B │ ¬A │ ¬B │ A&B │ A│B │ │_____│_____│_____│_____│_____│_____│ │ │ │ │ │ │ │ │ 1 │ 1 │ 0 │ 0 │ 1 │ 1 │ │ 1 │ 0 │ 0 │ 1 │ 0 │ 1 │ │ 0 │ 1 │ 1 │ 0 │ 0 │ 1 │ │ 0 │ 0 │ 1 │ 1 │ 0 │ 0 │ │_____│_____│_____│_____│_____│_____│

Fig 2.3

Os bit strings de uma expressao logica devem ter o mesmo tamanho (mesmo numero de bits).Se forem diferentes, a fileira menor sera automaticamente acrescida de zeros,'a direita,ate' igualar-se ao tamanho maior,antes de ser efetuada a operacao.

Por exemplo: '001'B&'00110'B implica a seguinte expressao: '00100'B&'00110'B dando como resultado o Bit String'00100'B.

Apenas como exercicio,comprovar os resultados abaixo: para

A='010111'B B='111111'B C='110'B temos:

NOT A.................'101000'B NOT C.................'001'B C AND B...............'110000'B A OR B................'111111'B C OR B................'111111'B A OR (NOT C)..........'011111'B NOT ((NOT C) OR (NOT B))...'110111'B

2.7 EXPRESSAO DE CONCATENACAO - STRING DE CARACTERES ____________________________________________________

Deve-se,primeiramente,conceituar "Character String"(string de caracteres),antes de estudar o resultado de uma operacao envolvendo operacao de concatenacao.

Pode-se definir string de caracteres como sendo uma sequencia de quaisquer caracteres validos em PL/1 escrita entre apostrofos,como,por

2. OPERACOES E EXPRESSOES

Page 15

exemplo,'A B C D - LETRAS' onde se tem um string de comprimento igual a 16 caracteres.

O resultado de uma expressao de concatenacao entre varios strings de ca- racteres e'simplesmente um outro string formado pela juncao dos mesmos na ordem em que eles aparecem na expressao.

Sejam os seguintes strings de caracteres 'ABCD','EFG','M' e 'HIJKL'; para a expressao

Page 12: Manual de PL1 - Completo

'ABCD'││'EFG'││'HIJKL'││'M' obter-se-a' como resultado o string "ABCDEFGHIJKLM' perfazendo um total de 13 caracteres.

Dentro de um string de caracteres,o unico carater que tem tratamento es- pecial e' o "apostrofo",que,quando incluido no string,deve vir duplicado.

Assim,para se escrever um string de caracteres compreendendo as palavras COPO D' AGUA CHEIO,e' preciso duplicar o "apostrofo" de D' AGUA ficando ,pois,'COPO D''AGUA CHEIO',nao obstante seu comprimento ainda seja de 17 caracteres(o apostrofo em duplicata conta como um so' carater).

Um outro exemplo e' o string formado apenas por 4 apostrofos,'''', indi- cando que se trata de um string de comprimento igual a 1,formado pel carater especial "apostrofo".

2.8. CONSTANTES E VARIAVEIS ___________________________

Pode-se definir CONSTANTE como sendo um valor autodefinivel, isto e', sua representacao e' seu proprio valor. Por exemplo: 20 constante real decimal de ponto fixo 31.4 idem 10010B constante real binaria de ponto fixo -37E2 constante real decimal de ponto flutuante 54.6I constante complexa 'PROG_NUM9' literal

Quanto a VARIAVEL, pode ser entendida como sendo o nome de um local de memoria (nome simbolico ou IDENTIFICADOR) que representara' uma ou mais constantes de determinado atributo, durante a execucao do programa.

2. OPERACOES E EXPRESSOES

Page 16

3. PROGRAMACAO ELEMENTAR ________________________

3.1. DECLARACAO DE VARIAVEIS E CONSTANTES _________________________________________

Declara-se uma constante pela simples escrita da mesma no programa. Ver- se-ao mais adiante os tipos de constantes existentes em PL/I.

Para as variaveis, ha' diversas maneiras de declarar seus tipos, que constituem as regras para definicao de atributos de variaveis.

Os atributos reconhecidos pela linguagem sao:

(a) BASE se a variavel e' decimal ou binaria; (b) ESCALA se a variavel e' decimal ou binaria de ponto flutuante ou de ponto fixo; (c) MODO se a variavel e' real ou complexa; (d) PRECISAO quanto a grandeza da variavel em relacao ao comprimento em bytes que ela ocupara' na memoria.

Em PL/I, declarar uma variavel significa dar atributos a essa variavel, e uma das maneiras de fazer isso e' pela regra automatica aplicada as variaveis reais numericas, que e a seguinte:

1) O primeiro caracter do identificador (nome da variavel) determina seus

Page 13: Manual de PL1 - Completo

atributos de BASE e ESCALA:

- Binaria de ponto fixo - se a 1a. letra for uma das letras I, J, K, L, M ou N - Decimal de Ponto Flutuante - se a 1a. letra for uma qualquer, diferente das ja mencionadas.

2) Para o atributo de PRECISAO tem-se a seguinte indicacao:

- Binario de ponto fixo - (15,0) ou no maximo (31,0) bits; - Decimal de ponto flutuante - (6) ou no maximo (16) digitos.

Assim, variaveis de nomes KONT, I, JK podem armazenar valores de cons- tantes do tipo inteiro e variaveis de nomes $XY, ABC, D26, por exemplo, podem armazenar valores de constantes reais(com ponto decimal).

Sem entrar em detalhes, por enquanto, uma constante dita decimal de ponto flutuante e' armazenada sob a forma de potencia de 10.

Por exemplo, a constante 53.4 e' armazenada sob a forma seguinte: 0.53400E02, que significa 0.53400 X 10**2.

A quantidade de algarismos que antecedem a letra E, letra indicativa da base 10, nas constantes, e' dada pela precisao da variavel que armazenara' tais constantes. Na verdade, esses algarismos sao os digitos significativos da constante, e, conforme consta da regra vista ante- riormente, essa precisao podera' ser modificada para, no maximo, 16

3. PROGRAMACAO ELEMENTAR

Page 17

digitos significativos. Ver como se faz essa modificacao quando for apresentado o comando DECLARE, mais adiante.

Nao obstante a precisao de 6 digitos significativos, podem-se usar gran- dezas para as constantes variando desde 10**-78 a 10**76.

3.2. COMANDO DE ATRIBUICAO __________________________

A fim de que o dado seja processado, o programa deve ter um meio para ma- nipular esse dado existente, para modifica'-lo ou gerar outros. Isso e' feito por meio de expressoes contendo variaveis, constantes e operadores.

Apos uma expressao ser calculada, seu resultado pode ser atribuido a uma variavel, na memoria, por meio de comando de atribuicao.

Sua forma geral e':

variavel-1, variavel-2, ..., variavel-n = expressao;

PI = 3.141592653589; a variavel PI armazenara' o valor da constante dada, na forma 3.14159E00.

VALOR = A; a variavel VALOR armazenara' o valor da variavel A.

B = B * 2 + (3**2-1); o valor da variavel B (valor que existe no local de memoria cujo nome simbolico e' B) e multiplicado pela constante 2; a esse resultado e' somado o valor 8 (proveniente de 3**2-1); o resultado final e' colocado no local de memoria cujo nome simbolico e B. Ou seja, o va- lor da variavel B e' redefinido pelo valor da expressao colocado 'a direita do sinal de igual. A,B,C = 5.0; as variaveis A, B e C conterao como seus valores a constante 5.00000E00.

Deve-se observar que o sinal de igualdade nao se refere a igualdade dos dois membros existentes em seus lados e sim 'a atribuicao do valor da expressao do lado direito a variavel (ou variaveis) do lado esquerdo.

Page 14: Manual de PL1 - Completo

Assim, podem-se ter comandos do tipo KONT = KONT + 1; significando que a variavel KONT, apos a execucao desse comando, sera' acrescida de 1.

3.3. COMANDO LIST _________________

Existem varios comandos usados em programacao PL/I que sao responsaveis pelas operacoes de entrada e saida de dados, ou seja, pelas operacoes de leitura de informacoes para o processamento de um programa de saida de informacoes decorrentes desse processamento.

Um dos comandos mais simples de E/S e' o comando LIST.

3. PROGRAMACAO ELEMENTAR

Page 18

Supondo toda entrada (INPUT) de um programa feita atraves de uma leitora de cartoes, padrao do sistema operacional, e toda saida (OUTPUT) atraves de uma impressora, tambem padrao do sistema operacional, o comando LIST pode apresentar-se nas seguintes formas:

Como input ...... GET LIST (lista de variaveis);

Como output ..... PUT LIST (lista de variaveis e/ou expressoes e/ou string de caracteres);

Como INPUT, todas as 80 colunas de um cartao sao lidas continuamente, passando de um cartao para o outro, ao ser atingida a ultima coluna do cartao que esta sendo lido.

Como OUTPUT, sao impressos 5 valores por linha, nas posicoes 1, 25, 49, 73 e 97, seguindo continuamente para as linhas seguintes, ao ser impresso o ultimo simbolo na linha.

Essa tabulacao de 24 em 24 espacos e' respeitada se o comprimento dos campos a serem impressos nao ultrapassa essas 24 posicoes, ou melhor, essas 24 menos uma posicoes. Se ultrapassar, serao impressos tantos cam- pos quantos forem possiveis na linha. Por exemplo, se houver dois campos de 30 posicoes cada um, e o primeiro for para ser impresso na 1a. posicao, o segundo campo sera' impresso a partir da posicao 49a..

O comando GET LIST(A,B,C,D); lera' quatro valores de constantes reais decimais de ponto flutuante e atribuira' esses valores as variaveis A,B, C e D, nessa ordem, ou seja, o 1o. valor para a variavel A, o 2o. para a variavel B, o 3o. para a variavel C e o 4o. para a variavel D.

Os quatro valores poderao ser perfurados de varias maneiras. Algumas de- las sao:

(a) um valor perfurado por cartao, em qualquer coluna;

________ ________ ________ ________ / │ / │ / │ / │ │ 10.0 │ │ 20.2 │ │ 30.5 │ │ 40.0 │ │ │ │ │ │ │ │ │

(b) todos os quatro valores perfurados em um so cartao; ____________________________ / │ │ 10.0 20.2 30.5 40.0 │ │ │

(c) ou qualquer combinacao dos quatro valores por um ou mais cartoes.

Page 15: Manual de PL1 - Completo

3. PROGRAMACAO ELEMENTAR

Page 19

Para distinguir um valor de um seguinte, deve existir uma virgula ou pelo menos um branco entre eles:

10.0,20.2

10.0 20.2

10.0 20.2 etc.

Um valor pode ter sido comecado num cartao e podera' terminar no seguinte, nao podendo, entretanto, haver brancos ou virgulas nessa interrupcao, por exemplo:

_____________________ ________________ │ / 10.0 20.2 3 │ │ 0.5 40.0 Representando a │ │ │ │ lista de valores: col.80 <--+ │ │ +--> col.1 10.0 20.2 30.5 40.0

3.4. COPY _________

O comando LIST de entrada permite o uso de um atributo de controle que, adicionado ao comando, copia, imprimindo na impressora os valores lidos - e' o COPY.

Entao, se se tiver GET LIST(A,B) COPY; e se no cartao houver ________________ / │ │ 10.11 20.1 │ │ │

ter-se-ao na memoria, para valores das variaveis A e B, respectivamente os valores 10.11 e 20.1 e na impressora sairao impressos, um por linha e ajustados a margem esquerda do formulario, tambem os valores 10.11 e 20.1, exatamente na ordem em que foram lidos.

Vejam-se, a seguir, alguns exemplos do comando LIST usado em operacao de saida.

O comando PUT LIST('ANO',IANOS); fara' com que sejam impressos, nessa ordem, o valor do string de caracteres 'ANO' e o valor da variavel IANOS. Supondo que o carro impressor esteja posicionado na primeira posicao da linha e que o valor da variavel IANOS seja 1976, ter-se-a' para saida a seguinte disposicao:

3. PROGRAMACAO ELEMENTAR

Page 20

________________________________________________ │ │ ANO bbbb 1976 │ │ │ │ +-> 1a.posicao +--> 25a.posicao │ │

Se, logo apos o comando PUT LIST apresentado acima, se escrever o comando PUT LIST(I,J,'SOMA =',I+J); e, imaginando que as variaveis I e J tenham

Page 16: Manual de PL1 - Completo

assumido nesse instante os valores 50 e 33, respectivamente, obter-se-a' a seguinte imagem de saida:

ANO 1976 50 33 SOMA = 83

Conforme se pode verificar, nao surtiu o efeito esperado, que era o de sair uma linha com os valores ANO e 1976 e outra linha com os valores 50, 33, SOMA = e 83. Isso se explica pelo fato de que o carro impressor fica posicionado imediatamente apos a ultima impressao feita. Uma das maneiras de se solucionar esse problema (nesse caso especifico) e' com- pletar a lista de variaveis do primeiro comando PUT com 3 strings for- mados pelo carater branco, ou seja: PUT LIST('ANO',1976,' ',' ',' '); ou entao usar o atributo de controle SKIP, um dos tres atributos que se verao a seguir.

3.5. PAGE, SKIP E LINE ______________________

O comando LIST de saida permite o uso de atributos de controle PAGE, SKIP e LINE.

Este controle especifica que a impressao sera' iniciada ou conti- PAGE - nuada na 1a. linha da pagina seguinte a atual, onde se processam as impressoes, no momento em que o atributo e' usado.

Este controle tem a forma SKIP ou SKIP(w). Especifica que (w-1) SKIP - linhas serao saltadas antes da proxima impressao (proximo comando PUT) e esta se dara' na 1a. posicao da nova linha.

Se w for omitido, recaindo na forma simples do atributo, SKIP, sera' assumido o valor 1, assim: SKIP e' o mesmo que SKIP(1).

Se w for menor ou igual a zero, a impressao se dara' na mesma linha que estava sendo impressa e na 1a. posicao.

Se w for tal que ultrapasse a ultima linha da pagina que esta sendo impressa, a impressao se dara' na 1a. posicao da 1a. linha da pagina seguinte.

3. PROGRAMACAO ELEMENTAR

Page 21

Este controle especifica que a impressao sera' iniciada na w- LINE(w) - esima linha da pagina que esta sendo impressa, na 1a. posicao.

Se w for menor ou igual a zero ou menor que o valor atual da linha, ou se ultrapassar a ultima linha da pagina, a impressao se dara' na 1a. posicao da 1a. linha da pagina seguinte.

O valor de w, tanto no SKIP quanto no LINE, podera' ser uma constante, variavel ou expressao; nos dois ultimos casos, os valores serao conver- tidos em um valor decimal inteiro.

Nao serao impressos valores binarios atraves do comando PUT. Eles serao sempre convertidos para o decimal correspondente. Vejam-se a seguir alguns exemplos.

PUT PAGE; move o carro impressor para a primeira linha da pagina seguinte.

PUT PAGE LIST('A'); move o carro impressor para a primeira linha da pa- gina seguinte e imprime o carater A.

Page 17: Manual de PL1 - Completo

PUT SKIP; move o carro impressor para a primeira posicao da linha seguinte.

PUT SKIP LIST('C'); move o carro impressor para a primeira posicao da linha seguinte e imprime o carater C.

PUT LIST('D1','D2'); imprime nas duas proximas posicoes os caracteres D1 e D2.

PUT SKIP(-1) LIST('H'); move o carro impressor para a primeira posicao da linha atual e imprime o carater H.

PUT SKIP(N+X) LIST('I'); a expressao N+X e' calculada, seu resultado e' transformado para inteiro e o carro impressor e' movido para a (N+X)-esima linha. Na 1a. posicao e' impresso o carater I.

3.6. UM PROGRAMA ELEMENTAR __________________________

Com os conceitos vistos ate' agora, ja' podemos escrever alguns progra- mas, obviamente triviais e que servirao para exercitarmos as primeiras praticas da linguagem PL/I.

Seja, por exemplo, escrever um programa que, lendo 5 valores numericos, com ou sem casas decimais,calculara' ou imprimira' a soma desses 5 valo- res e a media dos mesmos. Entao:

1 - EX1C3: PROC OPTION(MAIN);

2 - GET LIST(VAL_1,VAL_2,VAL_3,VAL_4,VAL_5);

3 - SOMA = VAL_1 + VAL_2 + VAL_3 + VAL_4 + VAL_5;

3. PROGRAMACAO ELEMENTAR

Page 22

4 - XMEDIA = SOMA/5;

5 - PUT LIST('SOMA E MEDIA DE 5 VALORES');

6 - PUT SKIP(2) LIST('SOMA = ',SOMA);

7 - PUT SKIP(5) LIST('MEDIA IGUAL A ',XMEDIA);

8 - END EX1C3;

Conforme se pode constatar, o programa foi escrito usando o formato identico para as suas 8 instrucoes. Apenas como ilustracao, veja-se esse mesmo programa escrito no formato em fileira:

EX1C3: PROC OPTIONS(MAIN); GET LIST(VAL_1,VAL_2,VAL_3,VAL_4,VAL_5);

SOMA=VAL_1+VAL_2+VAL_3+VAL_4+VAL_5; XMEDIA=SOMA/5; PUT LIST('SOMA

E MEDIA DE 5 VALORES'); PUT SKIP(2) LIST('SOMA = ',SOMA); PUT SKIP

(5) LIST('MEDIA IGUAL A ',XMEDIA); END EX1C3;

│ │

+---> coluna 2 coluna 72 <---+

O leitor deve, neste ponto, analisar a programacao apresentada no sentido de consolidar seus conhecimentos, atentando para os detalhes nela exis- tentes, no que diz respeito aos comandos obrigatorios (o primeiro e o ultimo), aos rotulos de comandos usados, aos nomes das variaveis criados

Page 18: Manual de PL1 - Completo

pelo programador, as expressoes e aos comandos de entrada e saida.

Deve-se salientar que existem muitas outras maneiras de se escrever esse programa, nao so' quanto ao formato de suas instrucoes, como tambem quanto ao uso dos comandos de programacao.

E' de grande utilidade que o leitor perfure e execute esse programa para ter uma primeira nocao de como as coisas vistas ate agora funcionam. Va- rios valores poderao ser lidos e testados, fazendo variar o conjunto dos 5 valores que serao lidos pelo programa.

Por exemplo, se forem perfurados em cartao (ou cartoes) os 5 valores: 30, 4.5, 68.46, 3 e 100 o programa produzira' como saida impressa o seguinte:

3. PROGRAMACAO ELEMENTAR

Page 23

1a. linha SOMA E MEDIA DE 5 VALORES │ 2a. linha │ │ 3a. linha SOMA = b 2.05960E+02 │ │ 4a. linha │ │ │ │ 5a. linha │ │ │ │ 6a. linha │ │ │ │ 7a. linha │ │ │ │ 8a. linha MEDIA IGUAL A b 4.11920E+01 │ │ │ │ +-> col.1 +-> col.25

3.7. USO DE COMENTARIOS EM PROGRAMACAO ______________________________________

Toda expressao (todo texto) envolvida entre os simbolos /* e */ constitui comentario na programacao PL/I.

Podem-se ter comentarios em qualquer lugar da codificacao, tendo-se ape- nas o cuidado de nao interferir na sintaxe da linguagem.

Por exemplo:

1a. linha /* PROGRAMA PARA CALCULAR A MEDIA DE 3 VALORES LIDOS */

2a. linha EX2C3: PROC OPTIONS(MAIN);

3a. linha GET LIST(X,Y,Z) COPY; /* LEITURA DOS 3 VALORES */

4a. linha A = (X+Y+Z)/3; /* CALCULO DA MEDIA */

5a. linha PUT LIST(A); /* IMPRESSAO DA MEDIA */

6a. linha END EX2C3;

Um texto de comentario pode comecar numa posicao de uma determinada linha e terminar em uma outra posicao de uma outra linha.

Page 19: Manual de PL1 - Completo

O compilador simplesmente ignora o trecho compreendido entre os simbolos /* e */.

3. PROGRAMACAO ELEMENTAR

Page 24

3.8. APLICACAO ______________

O programa que se segue se propoe a executar uma serie de comandos de impressao, usando os atributos SKIP, LINE e PAGE, mostrando ao leitor como esses atributos agem no controle do carro impressor.

Os valores impressos sao constantes string de caracteres e constantes numericas com e sem ponto decimal, apenas com finalidade didatica.

Deve-se observar o fato de que nao existem entradas de meio externo, ou seja, o programa nao le valores externos, eles simplesmente usa valores gerados nele proprio (as constantes e as variaveis):

EX3C3: PROC OPTIONS(MAIN); PUT PAGE; PUT PAGE LIST('A'); PUT SKIP; PUT SKIP(3) LIST('B'); PUT SKIP LIST('C'); PUT LIST('D1','D2'); N = 2; X = 1.5; PUT SKIP(N) LIST('E',N); PUT SKIP(N+X) LIST('F',N+X); PUT PAGE LINE(30) LIST('G'); PUT SKIP(40) LIST('I'); PUT LINE(40) LIST('FIM'); END EX3C3;

Deve ser notado tambem nesse programa o uso de variaveis nos parametros do atributo SKIP e o arredondamento para inteiro do valor da expressao N+X, ou seja, de 3,5 para 3.

Segue-se uma imagem das paginas que constituem a saida impressa do pro- grama:

3. PROGRAMACAO ELEMENTAR

Page 25

______________________________ ______________________________ │ │ │ │ │ (1a.pagina) │ │ (2a.pagina) │ │ / │ / │____________________________/ │____________________________/

____________________________________________________________________ │ │ │ A (3a.pagina) │ │ │ │ │ │ │

Page 20: Manual de PL1 - Completo

│ B │ │ C D1 D2 │ │ / │ E 2 / │ / │ / │ F 3.50000E + 00 / │_________________________________________________________/

_______________________________ ______________________________ │ │ │ │ │ (4a.pagina) │ │ I (5a.pagina) │ │ │ │ │ │ │ │ │ ' ' │ │ ' ' │ │ ' ' │ │ │ G │ ' ' │ / ' ' │ / ' ' │__________________________/ │ FIM / │_______________________/

3. PROGRAMACAO ELEMENTAR

Page 26

4. DECLARACOES DE VARIAVEIS ___________________________

4.1. COMANDO DECLARE ____________________

E' o comando usado para definir atributos de variaveis.

Dois atributos ja' foram vistos: BINARY FIXED e DECIMAL FLOAT de precisao (15,0) e (6), respectivamente. Ainda para variaveis numericas existem os atributos BINARY FLOAT e DECIMAL FIXED. Os quatro tipos de atributos tambem existem para as variaveis numericas complexas.

Para esses quatro tipos de atributos tem-se a seguinte tabela:

_____________________________________________________________________ │ │ Atributos de Precisao │ │ │______________________________│ │ Atributos de Base e Escala │ Assumido │ Maximo │ │______________________________________│________________│_____________│ │ │ │ │ │ BINARY FIXED │ (15,0) │ (31,0) │ │ DECIMAL FIXED │ ( 5,0) │ (15,0) │ │ BINARY FLOAT │ (21) │ (109) │ │ DECIMAL FLOAT │ (6) │ (33) │ │______________________________________│________________│_____________│

Fig. 4.1

Para o atributo MODO e' assumido o REAL.

A seguir apresentar-se-ao alguns dos atributos que sao dados as variaveis por meio do comando DECLARE, comando este que tambem tem como finalidade

Page 21: Manual de PL1 - Completo

reservar espaco de memoria para essas variaveis: REAL, COMPLEX, BINARY, DECIMAL, FIXED, FLOAT, CHARACTER, BIT, VARYING, INITIAL e LABEL.

Cada um desses atributos sera' visto separadamente.

O comando DECLARE se apresenta na seguinte forma: ___________________________________ │ │ │ DECLARE variaveis e atributos ; │ │___________________________________│

Ele permite a abreviatura de DCL e e' do tipo de comando composto pelas tres partes:

- IDENTIFICADOR DE COMANDO - que e' a palavra-chave DCL

- CORPO DE COMANDO - que sao os nomes das variaveis e seus atributos

- PONTO-E-VIRGULA - o sinal de ponto-e-virgula (;)

4. DECLARACOES DE VARIAVEIS

Page 27

4.2. REAL DECIMAL FIXED(P,Q) ____________________________

Uma variavel declarada "decimal de ponto fixo com precisao (p,q)", onde p e' o numero total de digitos e q o numero total de digitos da parte fracionaria (q e' tambem chamado fator de escala), deve representa cons- tantes que sao "strings" de digitos decimais, com ou sem ponto decimal, de no maximo 15 digitos e com ou sem sinal.

Por exemplo: 9.65 +240 027. -0.1 .0001 -.8 55987

Assim, para uma constante cujo valor armazenado fosse igual a 12345.678, ter-se-iam os seguintes valores numericos assumidos por determinadas variaveis, cujos atributos de precisao fossem:

(p,q) valores

(8,3) 12345.678 (5,0) ou (5) 12345 (7,0) ou (7) 0012345 (7,2) 12345.67 (6,3) 345.678 (6,4) 45.6780 (1,1) .6 (5,-2) 12300

Este ultimo caso fica armazenado sob a forma 123F+2, sendo importante salientar que o ponto decimal nao ocupa lugar na memoria em nenhum dos casos.

Veja-se no caso, para melhor exemplificar:

Seja o comando DECLARE AVA DECIMAL FIXED(4,1); se o valor de uma cons- tante a ser armazenado na variavel AVA for 5365.76, ou por um comand de leitura (GET LIST(AVA)), ou por um comando de atribuicao (AVA=5365.76), o que se tera', na realidade, sera' o valor 365.7 para a variavel AVA men- cionada.

O atributo DECIMAL pode ser abreviado para DEC,apenas.

A forma completa de declaracao da variavel AVA seria DCL AVA REAL DECIMAL FIXED(4,1); onde os atributos REAL, DECIMAL e FIXED podem aparecer em qualquer ordem, menos o de precisao (4,1), que devera' vir sempre depois de um atributo de base ou de escala (isto sera' explicado quando se tra-

Page 22: Manual de PL1 - Completo

tar de ordenacoes denominadas ARRAYS). O fato de um atribut nao aparecer no comando DECLARE sera' visto mais adiante, no topico "Declaracao par- cial de variaveis", como aconteceu no atributo REAL na primeira declaracao da variavel AVA.

4. DECLARACOES DE VARIAVEIS

Page 28

4.3. REAL BINARY FIXED(P,Q) ___________________________

Uma variavel declarada "real e binaria de ponto fixo com precisao (p,q)", onde p e' o numero total de digitos e q o numero de digitos da parte fracionaria (tambem chamado fator de escala), deve representar constantes que sao "strings" de digitos binarios, com ou sem ponto decimal, de no maximo 31 digitos e seguidos pela letra B.

Por exemplo: 10110110B 11.0001B -1.01B 101.B +.01B

Assim para uma constante cujo valor armazenado fosse igual a 110.11B, ter-se-iam os seguintes valores numericos assumidos por determinadas variaveis, cujos atributos de precisao declarados fossem: (p,q) valores (5,0) ou (5) 00110B (7,4) 110.1100B (5,2) 110.11B (3,0) ou (3) 110B (2,2) .11B (1,1) .1B

E' importante acrescentar que nem a letra B nem o ponto decimal ocupam lugar de memoria.

As mesmas observacoes feitas para o caso de variaveis com o atributo REAL DECIMAL FIXED(p,q) sao validas para esses atributos.

Um exemplo de uma declaracao para uma variavel poder armazenar valores de constantes binarias, reais, de ponto fixo e de precisao(p,q), seria: DCL VALORES REAL BINARY FIXED(10,5); onde o atributo BINARY pode ser abre- viado por BIN.

4.4. REAL DECIMAL FLOAT(P) __________________________

Uma variavel declarada "decimal, real, de ponto flutuante e de precisao(p)", onde p e' o numero de digitos significativos a ser conside- rado, deve representar constantes que sao "strings" de digitos decimais, com ou sem sinal, de no maximo 16 digitos seguidos por uma letra E, indi- cativa de expoente na base 10, e seu respectivo expoente.

Por exemplo:

20.E3 representando a constante de ponto fixo, decimal 20000 11E2 representando 1100 3.05E-2 representando0.0305 -.1E2 representando -10

Assim, para uma constante cujo valor armazenado fosse igual a 12345.678,ter-se-iam os seguintes valores numericos assumidos por deter- minadas variaveis, cujos atributos de precisao fossem:

4. DECLARACOES DE VARIAVEIS

Page 29

Page 23: Manual de PL1 - Completo

(p) valores

(6) 1.23456E+04 (8) 1.2345678E+04 (10) 1.234567800E+04 (5) 1.2345E+04 (4) 1.234E+04 (3) 1.23E+04

representando, respectivamente as constantes decimais de ponto fixo: 12345.6 12345.678 12345.67800 12345 12340 12300

Deve-se observar que o expoente, alem de permitir no maximo dois algarismos, so pode variar no intervalo de -78 a +76.

4.5. REAL BINARY FLOAT(P) _________________________

Esse atributo tem as mesmas caracteristicas do atributo visto ante- riormente, REAL DECIMAL FLOAT(p), com apenas a diferenca nos digitos,que sao binarios, e a letra B, final na constante.

Por exemplo: 1101.1E+04B representando 11011000B

-1001.E-02B representando -10.01B

1101E+03B representando 1101000B

4.6. COMPLEX ____________

As variaveis declaradas "complexas" admitem os mesmos atributos que as reais, apenas com a diferenca de que, tendo duas partes (real e imaginaria),os atributos declarados sempre se referirao as duas partes, isto e', apenas uma lista de atributos para as variaveis complexas. Nao se pode declarar um tipo de atributo para a parte real e outro para a parte imaginaria.

Uma variavel complexa deve representar constantes reais e imaginarias juntas ou apenas uma delas (real puro e imaginario puro).

Nao existe variavel imaginaria - existe a constante imaginaria e a cons- tante real que, quando juntas, formam um tipo de constante a ser armazenada na variavel complexa.

Uma constante imaginaria e' qualquer tipo de constante visto ante- riormente, imediatamente seguida pela letra I, como:

2I -3.45I 1101.0 1E-02BI 1.23E+01I 67.89E+02I -1000.01BI

4. DECLARACOES DE VARIAVEIS

Page 30

Assim, uma variavel complexa pode conter valores como:

3-5I -10B+101BI 7.12+1.23I 6-2I +3E01+1E02

O comando DCL YY COMPLEX FIXED DEC(6,1); declara a variavel YY como sendo uma variavel complexa, com ambas as partes, real e imaginaria, sendo constantes decimais de ponto fixo e de precisao (6,1).

Abrevia-se o atributo COMPLEX para CPLX.

4.7. CHARACTER(N)

Page 24: Manual de PL1 - Completo

_________________

Uma variavel declarada "carater de comprimento n" deve representar cons- tantes do tipo "string" de caracteres.

Assim, para uma constante cujo valor armazenado fosse o string de carac- teres 'SALA DE AULA NR. 2', teriamos os seguintes valores literais assumidos por determinadas variaveis, cujos comprimemtos fossem:

(n) valores

(10) SALA DE AU (15) SALA DE AULA NR (17) SALA DE AULA NR 2 (20) SALA DE AULA NR 2bbb

Como exemplo de uma declaracao de uma variavel carater (literal) pode-se citar: DCL VOGAL CHARACTER(1); podendo, entao, armazenar nessa variavel denominada VOGAL uma das 5 vogais do alfabeto, A, E, I, O ou U, como, por exemplo, VOGAL = 'E';

Pode-se abreviar o atributo CHARACTER para CHAR.

4.8. BIT(N) ___________

Esse atributo e' exatamente igual ao atributo CHAR, apenas e aplicado a "string de bits".

4.9. VARYING ____________

O atributo VARYING, que se abrevia por VAR, e' usado em variaveis possuidoras do atributo CHAR ou BIT. Ele faz com que o comprimento, espe-

4. DECLARACOES DE VARIAVEIS

Page 31

cificado em um desses atributos (CHAR ou BIT), seja variavel desde o tamanho zero (string nulo) ate' o tamanho especificado.

Veja-se um caso: DCL NOME CHAR(12) VAR; se se tiver uma constante literal cujo valor seja 'COPO D"AGUA' (de comprimento igual a 11), e se se fizer com que esse valor seja armazenado na variavel NOME, essa variavel tera' para comprimento exatamente o comprimento da constante, ou seja, 11. Se, a seguir, se armazenar um outro valor de constante literal,como, por exemplo, 'BRASIL', a variavel passara' a ter comprimento igual a 6, que e' o comprimento da constante.

Um string nulo e' formado por apenas dois apostrofos e tem, consequentemente, comprimento zero, de tal sorte que, se se fizer a variavel NOME = ", esta passara' a ter o comprimento igual a zero.

Tudo o que foi exposto se aplica perfeitamente as variaveis com o atri- buto BIT (bit string).

4.10. INITIAL(M) ________________

O atributo INITIAL, que se abrevia por INIT, serve para dar valores iniciais as variaveis. Seu uso pode ser substituido pelo comando de atribuicao correspondente, por exemplo: DCL F BIT(3) VAR; F = '11'B; po- dera' ser substituido por DCL F BIT(3) VAR INIT('11'B);

Mais alguns exemplos do atributo INIT:

Page 25: Manual de PL1 - Completo

- DCL A CHAR(3) INIT('SIM');

- DCL B BIT(5) INIT('11011'B);

- DCL C DEC FIXED(5,2) INIT(004.30);

ou DCL C DEC FIXED(5,2) INIT(4,3);

- DCL E DEC FLOAT(4) INIT(3.213E+01);

ou DCL E DEC FLOAT(4) INIT(32.13);

- DCL F BIN FIXED(4) INIT(1011B);

ou DCL F BIN FIXED(4) INIT(11);

- DCL G BIN FLOAT(3) INIT(101E+00B);

ou DCL G BIN FLOAT(3) INIT(5);

4. DECLARACOES DE VARIAVEIS

Page 32

4.11. LABEL ___________

Uma variavel declarada LABEL so' podera' assumir valores de rotulos (ou labels) de comandos.

Um rotulo de comando e' denominado "constante label" e a variavel decla- rada com o atributo LABEL e' denominada "variavel label".

O atributo LABEL permite, alem do uso do atributo INITIAL, uma outra forma, que e' a de se indicar, logo apos a palavra LABEL, entre parenteses, os valores de constantes labels que ela podera' assumir du- rante a execucao do programa.

Esses valores de constantes labels devem ser nomes de rotulos, obrigatoriamente existentes no mesmo "procedimento" em que a variavel foi declarada.

Assim, pode-se ter:

DCL XYZ LABEL;

DCL A LABEL INIT(SEGUE);

DCL L LABEL(LAB1,LAB2,LAB3);

DCL LAB LABEL(L1,L2,LL,FIM) INIT(LL);

4.12.DECLARACAO PARCIAL DE VARIAVEIS ____________________________________

Se, num comando DECLARE, faltar um ou mais atributos para uma variavel, dir-se-a' que a variavel foi parcialmente declarada e esses atributos in- existentes serao definidos automaticamente pelo compilador, de acordo com a seguinte regra:

- Se nao for declarada a BASE - sera' assumido DECIMAL

- Se nao for declarada a ESCALA - sera' assumido FLOAT

Page 26: Manual de PL1 - Completo

- Se nao for declarado o MODO - sera' assumido REAL

- Se nao for declarada a PRECISAO - sera' assumida a precisao de acordo com a Fig. 4.1

Assim, se se tiver, por exemplo:

4. DECLARACOES DE VARIAVEIS

Page 33

DCL BAIXO FLOAT; sera assumido DEC(6) e REAL

DCL ALTO DEC; sera assumido FLOAT(6) e REAL

DCL BI FIXED; sera assumido DEC(5,0) e REAL

DCL TRI BIN FIXED; sera assumido (15,0) e REAL

DCL POLI BIN; sera assumido FLOAT(21) e REAL

DCL XYZ CLPX FLOAT; sera assumido DEC(6) para ambas as partes

DCL ABCD FLOAT(10); sera assumido DEC e REAL

DCL A; sera' assumido DEC, FLOAT, (6) e REAL

4.13. ORDEM DOS ATRIBUTOS NO COMANDO DECLARE ____________________________________________

E' permitido usar, no comando DECLARE, qualquer tipo de fatoracao com os atributos e as variaveis a serem declaradas, por exemplo: DCL (A,B,C) FIXED(3,1), (X INIT(32,3), Y) DEC FLOAT(8); nesses casos, as variaveis A,B e C terao atributos DEC FIXED(3,1) e REAL cada uma e as variaveis X e Y terao atributos DEC FLOAT(8), sendo que a variavel X e' inicializada com o valor 32.3.

O que foi feito para os atributos de variaveis numericas tambem e' valido para qualquer tipo de atributos visto ate' agora, como CHAR, BIT, COMPLEX, VAR etc.

4.14. MAIS EXEMPLOS DE APLICACAO DO COMANDO LIST ________________________________________________

1) Sendo DCL A CHAR(3) INIT('NAO'); GET LIST(A); se o cartao a ser lido contiver as perfuracoes do carater string 'SIM', comecando em qualquer coluna, apos essa leitura, a variavel A que inicialmente continha o string de caracteres 'NAO', passara' a conter o string 'SIM'. Repare-se no uso dos apostrofos no dado perfurado (e' uma constante literal).

2) Sendo DCL ALFA(5) CHAR(1); pode-se ter um cartao com as seguintes perfuracoes:

__________________________________________________ / / b...b 'A' b...b 'E' b...b 'T' b...b 'O' b...b 'U' │

e um comando GET LIST(ALFA); lera' os 5 valores A, E, I, O e U e o dispo- sitivo de leitura ficara posicionado imediatamente apos a coluna em que

4. DECLARACOES DE VARIAVEIS

Page 34

estava perfurado o ultimo apostrofo (depois da letra U), para a proxima

Page 27: Manual de PL1 - Completo

leitura que podera ocorrer.

3) Seja DCL (A,B) FLOAT; se se tivesse que ler 3 vezes esse par de valo- res e se os cartoes tivessem as seguintes perfuracoes:

__________________________________________________ / 1. cartao / b..b 1E + 10bb2E + 02bb2E + 05 b....b │

__________________________________________________ / 2. cartao / 25E + 02bbb32E + 03bb5E + 02bb7.3E + 02b...b │

Os valores contidos em A e B apos cada leitura feita atraves do GET LIST(A,B); seriam:

1a. leitura - A = 1E + 10 e B = 2E + 02

2a. leitura - A = 2E + 05 e B = 25E + 02

3a. leitura - A = 32E + 03 e B = 5E + 02

Conforme se pode observar, o ultimo valor perfurado (7.3E + 02) nao foi lido, o que e' explicado por ter acabado a lista de variaveis no comando LIST (6 valores = 3 vezes os 2 valores). O proximo comando GET LIST que aparecer no programa tentara ler esse valor. Agora note-se o detalhe: se a variavel do proximo comando tiver atributo compativel com essa cons- tante (7.3E + 02), esse valor sera' lido; se nao tiver, havera' impressao de uma mensagem de erro de conversao na leitura. Por exemplo, se essa tal variavel fosse declarada com o atributo CHAR, daria esse tipo de erro uma vez que deveria, para ela, ter sido perfurado no lugar dessa constante (7.3E + 02) um string de caracteres, entre apostrofos.

4) Uma constante do tipo REAL, DECIMAL, FLOAT e de PRECISAO(4), por exemplo, podera' ser perfurada em cartao de uma das seguintes maneiras: 5E + 01 5.E + 01 5.0E + 01 5E1 5.E1 5.0E1 5 + 1 5. + 1 5.0 + 1 representando o valor 50.0

5) Seja DCL A FIXED INIT(10), B CHAR(3) INIT('XYZ'); o comando PUT LIST(B,A); causara uma impressao do tipo:

___________________________________ │ │ XYZ 10 │ │ │ '---> posicao 1 _________/ │___________________/

4. DECLARACOES DE VARIAVEIS

Page 35

6) DCL C CHAR(50) INIT('X'); o valor da variavel C, que e' um string de caracteres formado por brancos, tendo na primeira posicao o carater X, sera' impresso a partir da posicao 1, deixando a proxima posicao disponivel, a de numero 73.

_____________________________________________ │ │ Xb...................b ? │ │ │ │ +-> posicao 1 +-> posicao 73 │ _________________ │__________________________/

O string de caracteres, por ter o comprimento igual a 50, abrange as

Page 28: Manual de PL1 - Completo

posicoes 1, 25 e 49.

7) PUT LIST('ANO',1972,1973,1974,1975); implica a impressao:

_________________________________________________ │ │ ANO 1972 1973 1974 1975 │ │ │ │ │ │ │ +->pos1 +->pos25 +->pos49 +->pos73 +->pos97 │

Na verdade, as constantes 1972, 1973, 1974 e 1975 sairao deslocadas mais 3 posicoes para a direita (ver-se-a' a explicacao para esse fato mais adiante, quando se tratar de conversoes de campos numericos para campos literais).

4. DECLARACOES DE VARIAVEIS

Page 36

DESCRICAO DE DADOS ____________________________________________________________________ │ Caracteristicas │ Definicoes │ Atributos │ Exemplos │ │______________________│___________________│______________│__________│ │BASE │DECIMAL │Composto dos digi-│ DECIMAL │ 3324.51 │ │ │ │tos do sistema nu -│ │ │ │ │ │merico decimal:0,1,│ │ │ │ │ │2,3,4,5,6,7,8,9 │ │ │ │ │______________│___________________│______________│__________│ │ │BINARIO │Composto dos digi-│ BINARY │Deve ser│ │ │ │tos do sistema bi -│ │seguido p/│ │ │ │nario: 0 e 1 │ │B: 1101B │ │_______│______________│___________________│______________│__________│ │ESCALA │PONTO FIXO │Composto por digi-│ FIXED │ 322.6 │ │ │ │tos e um unico pon-│ │ │ │ │ │to que especifica o│ │ │ │ │ │inicio da fracao │ │ │ │ │______________│___________________│______________│__________│ │ │PONTO FLUTUAN-│Um campo de digitos│ FLOAT │Deve con-│ │ │TE │seguido pela letra│ │ter a le-│ │ │ │E, seguida por um│ │tra E: │ │ │ │expoente decimal│ │4788.2E2 │ │ │ │sinalizado opcio-│ │ │ │ │ │nalmente │ │ │ │_______│______________│___________________│______________│__________│ │PRECISAO │a) Em um numero de│ │ │ │ │ponto fixo, o 1.nr.│ │ │ │ │maximo de digitos│ │ │ │ │que a variavel pode│ (n ,n ) │ (5,3) │ │ │conter; o 2. espe -│ 1 2 │ 99,999 │ │ │cifica o nr. destes│ │ │ │ │'a direita do pto. │ │ │ │ │___________________│______________│__________│ │ │b)Em um nr. de pon-│ │ │ │ │to flutuante, espe-│ │ │ │ │cifica o numero de│ (n) │ (5) │ │ │digitos antes da│ │+9.9999E+-│ │ │letra E │ │99 │ │______________________│___________________│______________│__________│

Page 29: Manual de PL1 - Completo

4. DECLARACOES DE VARIAVEIS

Page 37

____________________________________________________________________ │ Caracteristicas │ Definicoes │ Atributos │ Exemplos │ │______________________│___________________│______________│__________│ │STRINGS│De Caracteres │Uma sequencia co-│ │Deve vir│ │ │ │nectada de caracte-│ │sempre en-│ │ │ │res que pode in-│ │tre apos-│ │ │ │cluir qualquer di-│ │trofos │ │ │ │gito, letra ou ca-│CHARACTER │'CONCURSO │ │ │ │rater especial re-│ │ 1' │ │ │ │conhecido pelo Sist│ │ │ │ │ │Oper. entre apos-│ │ │ │ │ │trofos │ │ │ │ │______________│___________________│______________│__________│ │ │Comprimento │Indica o nr. de ca-│ │'CONCURSO │ │ │ │racteres no string │ (n) │1' -> n=10│ │ │______________│___________________│______________│__________│ │ │De Bits │Uma sequencia de│ │ │ │ │ │digitos binarios│BIT │'10110'B │ │ │ │entre apostrofos e│ │ │ │ │ │seguida pela letra│ │ │ │ │ │B │ │ │ │ │______________│___________________│______________│__________│ │ │Comprimento │Indica o nr. de di-│ │'10110'B │ │ │ │gitos binarios │ (n) │n = 5 │ │ │______________│___________________│______________│__________│ │ │de Caracteres │Usado para inicia -│INITIAL (*) │INITIAL(9)│ │ │e de Bits │lizar valores │ │ou │ │ │ │ │ │INIT ('A')│ │ │ │___________________│______________│__________│ │ │ │Usado para especi -│ │ │ │ │ │ficar comp. varia-│ │CHAR(50) │ │ │ │vel │VARYING │VAR │ │_______│______________│___________________│______________│__________│ │LABEL ou rotulo │E' a declaracao de│ │Prefixado │ │ │uma variavel como│LABEL │a um co-│ │ │sendo um rotulo va-│ │mando e│ │ │riavel de comando │ │ separado│ │ │ │ │por dois│ │ │ │ │pontos │ │______________________│___________________│______________│__________│

(*) Usado tanto para 'string' como para dados numericos

FIG. 4.2

4. DECLARACOES DE VARIAVEIS

Page 38

5. CONVERSOES EM EXPRESSOES ARITMETICAS _______________________________________

5.1. INTRODUCAO _______________

Um comando de atribuicao significa que o valor da expressao do lado

Page 30: Manual de PL1 - Completo

direito do sinal de atribuicao (sinal de igual) e' calculado e guardado no local de memoria cujo nome simbolico e' o identificador colocado no lado esquerdo do sinal.

Tal procedimento leva em consideracao os atributos das variaveis da expressao do lado direito e os das variaveis do lado esquerdo, respeitando certas regras e a hierarquia das operacoes.

Em PL/I, os operandos devem ter os mesmos atributos para que uma expressao possa ser avaliada ou para que um comando de atribuicao possa ser executado. Entretanto, podem-se escrever expressoes com varias combinacoes de operandos (atributos diferentes), uma vez que algumas conversoes sao automaticamente efetuadas.

Ver-se-ao, a seguir, algumas das conversoes que podem ser efetuadas e as condicoes em que elas ocorrem.

BASE - Se dois operandos tiverem atributos de base diferentes, o operando decimal sera' transformado em binario.

____________________________________________________________________ │ DEC FIXED(p,q) -> DEC FLOAT - p │ │____________________________________________________________________│ │ DEC FIXED(p,q) -> BIN FIXED - 3.32p + 1 , 3.32q │ │____________________________________________________________________│ │ DEC FIXED(p,q) -> BIN FLOAT - 3.32p │ │____________________________________________________________________│ │ DEC FLOAT(p) -> BIN FLOAT - 3.32p │ │____________________________________________________________________│ │ BIN FIXED(p,q) -> BIN FLOAT - p │ │____________________________________________________________________│ │ BIN FIXED(p,q) -> DEC FLOAT - p/3.32 │ │____________________________________________________________________│ │ BIN FIXED(p,q) -> DEC FIXED - p/3.32 + 1 , q/3.32 │ │____________________________________________________________________│ │ BIN FLOAT(p) -> DEC FLOAT - p/3.32 │ │____________________________________________________________________│

FIG. 5.1

ESCALA - Se dois operandos tiverem atributos de escala diferentes, o operando de ponto fixo sera' transformado em ponto flutuante.

PRECISAO - Se um operando for transformado, sua precisao sera' tambem transformada, segundo a FIG. 5.1

5. CONVERSOES EM EXPRESSOES ARITMETICAS

Page 39

5.2. EXEMPLOS _____________

Seguem-se alguns exemplos para elucidar melhor essas regras.

1) DCL A DEC FIXED(8,3), B BIN FIXED(6);

A * B - para B - nao ha' conversao para A - e' convertido para BIN FIXED(28,10) - p = 3.32 X 8 + 1 = 26.56 + 1 = 27.56 = 28 q = 3.32 X 3 = 9.96 = 10 (consultando a Fig. 5.1)

2) DCL A DEC FLOAT(5), B DEC FLOAT(6), C BIN FLOAT(5);

A / B - nao ha' conversao

Page 31: Manual de PL1 - Completo

A / C - ha' conversao de A para BIN FLOAT(17) - p = 3.32 X 5 = 16.6 = 17

B * C - ha' conversao de B para BIN FLOAT(20) - p = 3.32 X 6 = 19.92 = 20

3) DCL A DEC FLOAT(4), B BIN FIXED(5,2);

A + B para A - e' convertido para BIN FLOAT(14) - p = 3.32 X 4 = 13.28 = 14 para B - e' convertido para BIN FLOAT(5) - p = 5

Essas regras dizem respeito 'as conversoes de atributos nos operandos de uma expressao.

Pois bem, uma vez efetuadas essas conversoes, ver-se-ao a seguir as regras que existem para as operacoes a serem efetuadas entre operandos com atributos FIXED e entre operandos com atributos FLOAT, no que concerne a precisao do resultado.

FLOAT - Se os operandos, convertidos de uma operacao aritmetica forem de ponto flutuante, a precisao do resultado in- terno dessa expressao sera' a maior precisao das duas variaveis (dois operandos).

Voltando aos exemplos dados anteriormente, nr. 2 e 3, tem-se:

nr.2 - A/B o resultado tera' precisao de p=6 A/C o resultado tera' precisao de p=17 B*C o resultado tera' precisao de p=20 nr.3 - A+B o resultado tera' precisao de p=14

5. CONVERSOES EM EXPRESSOES ARITMETICAS

Page 40

FIXED - Se os operandos, convertidos de uma operacao aritimeti- ca, forem de ponto fixo, a precisao do resultado inter- no dependera' da operacao que estiver sendo efetuada, de acordo com a FIG. 5.2

____________________________________________________________________ │ OPERACAO │ p │ q │ │____________________________│___________________│___________________│ │ Adicao ou Subtracao │ 1 + PQ + Q │ Q │ │____________________________│___________________│___________________│ │ Multiplicacao │ p1 + p2 + 1 │ q1 + q2 │ │____________________________│___________________│___________________│ │ Divisao │ 15(se decimal) │ p - ((p1-q1) + q2)│ │ │ 31(se binario) │ │ │____________________________│___________________│___________________│ │ Potenciacao │ (p1 + 1) X (valor │ q1 X (valor do ex-│ │ │ do expoente) - 1 │ poente) │ │____________________________│___________________│___________________│

FIG. 5.2

Simbologia usada na FIG. 5.2:

p1 = numero total de digitos do 1. operando

p2 = numero total de digitos do 2. operando

q1 = numero de digitos da parte fracionaria do 1. operando

Page 32: Manual de PL1 - Completo

q2 = numero de digitos da parte fracionaria do 2. operando

PQ = o maior valor entre (p1 - q1) e (p2 - q2)

Q = o maior valor entre q1 e q2

A potenciacao e' valida somente para expoente sem sinal e base sem parte fracionaria (q1 = 0).

Assim, se se tiver: DCL A DEC FIXED(4,2), B DEC FIXED(6,1); o resultado da expressao A-B tera para atributos o seguinte: DECIMAL, FIXED e precisao (8,2), pois: p = 1 + 5 + 2 = 8 onde 5 e' o maior valor entre (6-1) e (4-2) e q = 2 que e' o maior valor entre 2 e 1.

Para complementar essas nocoes, seguem-se alguns casos de expressoes for- madas apenas por constantes.

® ADICAO(ouSUBTRACAO)

(12345.1234 + 123.12345) p1=9 p2=8 q1=4 q2=5 p = 1 + maximo de (p1-q1 e p2-q2) + maximo de (q1 e q2)= 1 + 5 + 5 = 11 q = maximo entre q1 e q2 = 5 Logo, a precisao sera' (11,5)

5. CONVERSOES EM EXPRESSOES ARITMETICAS

Page 41

® MULTIPLICACAO

(123.123 * 12.12) p1=6 q1=3 p2=4 q2=2 p = p1 + p2 + 1 = 6 + 4 + 1 = 11 q = q1 + q2 = 3 + 2 = 5 Logo, a precisao sera' (11,5)

® DIVISAO

(123.123 / 2) p1=6 q1=3 p2=1 q2=0 p = 15 (por ser decimal) q = 15 - (p1 - q1) + q2 = 15 - (6 - 3) + 0 = 15 - 3 = 12 Logo, a precisao sera' (15,12)

® EXPONENCIACAO

(32 ** 5) p1=2 q2=0 p =((p1 + 1) X (valor do expoente)) - 1=((2+1)*5)-1 = 15 - 1 = 14 q = q1 X valor do expoente = 0 * 5 = 0 Logo, a precisao sera' (14,0)

5. CONVERSOES EM EXPRESSOES ARITMETICAS

Page 42

6. ARRAY ________

Page 33: Manual de PL1 - Completo

6.1 INTRODUCAO ______________

E' uma colecao de dados homogeneos em relacao aos seus atributos.

Um "array", tambem chamado TABELA,MATRIZ,LISTA,VETOR etc., tem um identi- ficador que o representa e deve sempre constar no comando DECLARE.

Por exemplo, se der 'a colecao das vogais A,E,I,O e U o nome de VOGAIS, ter-se-a' formado um array, cujos elementos serao referenciados pelo nome do array, seguido do indice correspondente entre parenteses,como VOGAIS(1), VOGAIS(2), VOGAIS(3), VOGAIS(4) e VOGAIS(5), representando, cada uma, uma das 5 vogais do alfabeto.

Assim, tendo-se VOGAIS(1) = 'A'; VOGAIS(2) = 'E';... VOGAIS(5) = 'U'; diz-se que os elementos que compoem a colecao de nome VOGAIS sao as 5 vogais do alfabeto, constituindo constantes literais de comprimento um, cada uma, e ordenadas de acordo com um criterio determinado (no caso, a ordem natural das vogais: a, e, i, o, u).

Para indicar que uma variavel representa um array, ou seja, uma colecao de dados e nao uma variavel simples, sua declaracao devera' constar do comando DECLARE, seguida do numero de elementos entre parenteses, imediatamente apos o nome da variavel.

No caso ora em apresentacao, DCL VOGAIS(5) CHAR(1);

DCL TAB(10) DEC FIXED(3); especifica que todos os 10 elementos do array denominado TAB sao variaveis decimais de ponto fixo, reais, e de precisao igual a 3.

Repare-se nos dois exemplos a seguir:

DCL A(6) DEC FLOAT; e' completamente diferente de DCL A DEC FLOAT(6); no primeiro, declara-se um array de nome A com 6 elementos que sao variaveis decimais, de ponto flutuante e de precisao igual a 6 digitos signifi- cativos, enquanto que, no segundo, se declara uma variavel de nom A, de- cimal, de ponto flutuante e de precisao igual a 6 digitos signifitivos. No primeiro exemplo, foram assumidos, automaticamente, os atributos REAL e a precisao(6), no segundo, apenas o atributo REAL.

O atributo de precisao (6), no segundo exemplo, poderia aparecer em qualquer ordem -- DCL A DEC(6) FLOAT; ou DCL A DEC FLOAT(6); mas nunca depois do nome da variavel A, o que faria com que esta representasse um nome de array e nao um nome de uma variavel simples, como e' pretendido.

As declaracoes que se seguem sao identicas:

DCL LISTA(1000) REAL DECIMAL FLOAT(6); DCL LISTA(1000) REAL FLOAT(6); DCL LISTA(1000) DECIMAL(6);

6. ARRAY

Page 43

DCL LISTA(1000) FLOAT(6); DCL LISTA(1000) REAL DECIMAL(6); DCL LISTA(1000) REAL(6); DCL LISTA(1000);

6.2. DIMENSAO DE ARRAYS _______________________

Um array pode ter qualquer numero de dimensao.

Page 34: Manual de PL1 - Completo

Todos os exemplos vistos ate' agora constituem exemplos de arrays de uma dimensao.

Uma colecao arranjada em uma tabela de dupla entrada pode ser represen- tada por um array de duas dimensoes, em que a 1a. dimensao diz respeito 'as linhas e a 2a. dimensao diz respeito 'as colunas da matriz por exemplo: DCL MATRIZ(2,3) BIN FIXED(3); representando uma matriz de nome MATRIZ, com 2 linhas e 3 colunas, totalizando 6 elementos, sendo todos variaveis binarias, de ponto fixo e de precisao (3).

Assim pode-se ter:

DCL ARR(3); array de 1 dimensao com 3 elementos;

DCL ARR(5,3); array de 2 dimensoes com 15 elementos;

DCL ARR(4,3,2); array de 3 dimensoes com 24 elementos;

DCL ARR(3,2,3,3); array de 4 dimensoes com 54 elementos;

e assim por diante.

A localizacao de um elemento, em um array, e' dada pelo indice usado en- tre parenteses depois do nome do array. Esse indice e' denominado "subs- crito da variavel array".

O subscrito de uma variavel array pode ser constante, variavel ou expressao. Entao, no comando A = AA(N*2,5); o elemento situado na (N*2)-esima linha e na 5a. coluna da ordenacao denominada AA sera' atribuido 'a variavel denominada A.

O resultado de uma expressao, quando usada como subscrito, sera' sempre convertido para o maior inteiro, menor que o resultado da expressao ou igual a ele. Por exemplo, se (N*2) fosse igual a 3.6, esse resultado se- ria transformado para 3.

6. ARRAY

Page 44

6.3. EXEMPLOS DE ARRAYS _______________________

1)DCL (TABELA(5), TAB1(4,3), VETOR(3)) DEC FIXED; todos os elementos dos tres arrays -- TABELA, TAB1 e VETOR -- sao variaveis decimais, de ponto fixo e de precisao (5,0).

2)DCL (TAB1,TAB2,TAB3) (100) BIN; todos os tres arrays -- TAB1, TAB2 e TAB3 -- sao arrays de uma dimensao e contem cada um 100 elementos que sao variaveis binarias, de ponto flutuante e de precisao (21).

3)DCL LISTA(3) FIXED INIT(1,2,3); representando: LISTA(1) = 1, LISTA(2) = 2 e LISTA(3) = 3.

4)DCL C(5) FIXED INIT((3) 1, (2) 0); representando C(1) = 1, C(2) = 1, C(3) = 1, C(4) = 0 e C(5) = 0.

5)DCL (A(2) INIT(10,20), B(3)) BIN FIXED(2); apenas os dois elementos do array A sao inicializados -- A(1)=10 e A(2)=20. Esses doi elementos e os tres do array B sao variaveis binarias, de ponto fixo e d precisao (2), cada uma.

6)DCL LETRA(6) CHAR(2) INIT((6)(1)' '); ou DCL LETRA(6) CHAR(2) INIT((6)(2)''); ou DCL LETRA(6) CHAR(2) INIT((6)(1)''); representando inicializar os 6 elementos do array, denominado LETRAS, por brancos.

Page 35: Manual de PL1 - Completo

O fator de repeticao antes de um string (de bits ou de caracteres) faz com que o string seja expandido, como por exemplo:

(3)'A' significa 'AAA' (4)'101'B significa '101101101101'B

Assim, quando um elemento string deve ser repetido como inicializacao dos elementos de um array, este devera' conter o seu fator de expansao, mesmo que seja igual a 1.

7)DCL TAB(3) CHAR(3) VAR INIT('ARY','ALFREDO','SA'); representando TAB(1)='ARY', TAB(2)='ALF' e TAB(3)='SA'.

8)DCL CAR(3) CHAR(1) INIT((3) '0'); apenas o primeiro elemento sera' inicializado com o valor literal '0', pois o fator de repeticao (3) e' para expansao do string e nao um fator de repeticao para o numero de ele- mentos do array. Assim, o string sera' expandido para '000' que, quando atribuido 'a variavel CAR(1) sera' truncado 'a direita, uma vez que esta tem atributo CHAR(1).

9)DCL L(3) LABEL; indicando ser um array que contera' 3 valores de cons- tantes label.

10)DCL LAB(2) LABEL INIT(SEGUE,PULO1); significando que os dois elemen- tos do array de labels foram inicializados com os valores de label cons- tantes SEGUE e PULO1, respectivamente, 1o. elemento e 2o. elemento.

11)DCL MAT(3,2) CHAR(1) INIT((4)(1)'X','Y','Z'); implicando:

6. ARRAY

Page 45

MAT(1,1) = MAT(1,2) = MAT(2,1) = MAT(2,2) = 'X', MAT(3,1) = 'Y' e MAT(3,2) = 'Z'. Isto porque um array e' armazenado, na memoria, numa ordem que corres- ponde `a variacao mais rapida nos indices da direita para a esquerda.

12)DECLARE FONE (2,3,2) INIT(1,2,3,4,5,6,6,5,4,3,2,1); resultando em:

FONE(1,1,1) = 1, FONE(1,1,2) = 2, FONE(1,2,1) = 3, FONE(1,2,2) = 4, FONE(1,3,1) = 5, FONE(1,3,2) = 6, FONE(2,1,1) = 6, FONE(2,1,2) = 5, FONE(2,2,1) = 4, FONE(2,2,2) = 3, FONE(2,3,1) = 2, FONE(2,3,2)=1,

6.4. LIMITES INFERIORES E SUPERIORES NA DIMENSAO DE ARRAYS __________________________________________________________

Uma outra maneira de se declarar a dimensao de um array e' pelo uso dos limites inferiores e superiores dos elementos que compreendem a dimensao do referido array.

Assim, ao inves de se declarar o numero de elementos, em cada dimensao, declaram-se os limites da dimensao, os quais deverao vir separados por dois pontos (: no conjunto de 60 ou .. no conjunto de 48 caracteres usados pelo PL/1).

Uma declaracao do tipo A(3) poderia ser feita usando esta nova modalidade da seguinte maneira: A(1:3). Ate' ai', nada de mais. Porem, se for pre- ciso trabalhar com valores de indices variando em intervalos, nao necessariamente de inteiros naturais, poder-se-a' lancar mao desse re- curso, declarando convenientemente a dimensao do array, como no caso de se desejarem, por exemplo, os coeficientes a0, a1, a2, de um polinomio do 2o. grau, armazenados numa colecao cujos indices devam variar com a mesma indicacao. Nesse caso, ter-se-a' o seguinte comando:

DCL COEFICIENTES(0:2) FLOAT

representando um array denominado COEFICIENTES, com 3 elementos que sao

Page 36: Manual de PL1 - Completo

variaveis decimais, de ponto flutuante e de precisao (6), representados por: COEFICIENTES(0), COEFICIENTES(1) e COEFICIENTES(2).

Podem-se ter, com isso, varios tipos de variacoes, tais como:

DCL A(-2:2,-1:1); um array de 5 x 3 elementos DCL B(-3:0,4); um array de 4 x 4 elementos DCL C(-5:1); um array de 7 elementos DCL ANOS(1968:1976); um array de 9 elementos DCL XYZ(1:12,1938:1948); um array de 12 x 11 elementos DCL W(-1:1,-2:2,-3:3); um array de 3 x 5 x 7 elementos

O leitor deve observar que os exemplos foram dados para variaveis com atributos DEC, FLOAT, precisao (6). Isso ocorreu apenas para facilidade

6. ARRAY

Page 46

de exposicao, podendo ser aplicado a qualquer tipo de variaveis ja' visto ate' agora.

6.5. USO DE ARRAY EM EXPRESSOES E NO COMANDO LIST _________________________________________________

Um elemento de um array tem precisamente as mesmas propriedades que uma variavel simples, isto e', podem-se ter comandos de atribuicao como:

C=A(3,5); B=D(2,2,1); E=A(2,1) + B(1,1,1); F(3,4) = C

Os elementos podem ser usados numa lista de variaveis de um comando de entrada e saida como o comando LIST ja' visto.

Por exemplo, GET LIST(A(1),A(2),A(5)); implicara' a leitura dos elementos 1o., 2o. e 5o. de um array denominado A. Da mesma forma, no comando PUT LIST(A(1),A(2),A(5)); implicara' a impressao desses elementos.

Se, na lista de variaveis, constar o nome do array, sem subscrito, todos os elementos, em ordem, do array serao lidos ou impressos.

DCL LET(4) CHAR(1); o comando GET LIST(LET); fara' com que sejam lidos os 4 elementos do array denominado LET, na ordem: LET(1), LET(2), LET(3) e LET(4).

Da mesma forma, no comando PUT LIST(LET); serao impressos os elementos LET(1), LET(2), LET(3) e LET(4), nessa ordem.

Sempre que um nome de array aparecer sem o subscrito, uma referencia a esse array sera' para todos os seus elementos, na ordem do seu armazenamento.

Assim, se A e B sao dois arrays de mesma dimensao, se seus subscritos tem os mesmos limites de variacao e se C e' uma variavel simples, podem-se ter os seguintes comandos:

A = B; sendo o mesmo que A(1,1) = B(1,1); A(1,2) = B(1,2); A(2,1) = B(2,1); etc...

A = B + C; sendo o mesmo que A(1,1) = B(1,1) + C; A(1,2) = B(1,2) + C; A(2,1) = B(2,1) + C; etc...

A = -B + C * B; sendo o mesmo que A(1,1) = -B(1,1) + C * B(1,1); A(1,1) = -B(1,2) + C * B(1,2); A(2,1) = -B(2,1) + C * B(2,1);

Page 37: Manual de PL1 - Completo

etc...

6. ARRAY

Page 47

Os comandos a seguir tem o mesmo significado:

1) DCL TABELA(3) DEC FIXED(2) INIT((3) 0);

2) TABELA(1), TABELA(2), TABELA(3) = 0;

3) TABELA = 0;

Veja-se um exemplo, mais detalhado, de uso de array em expressao.

Seja DCL A(2,3) FIXED(1) INIT(1,2,3,4,5,6), B(2,3) FIXED(1) INIT ((6) 1);

Para o comando A = B + A(1,3); a matriz A ficara' com os seguintes ele- mentos:

A(1,1) = B(1,1) + A(1,3) = 1 + 3 = 4 A(1,2) = B(1,2) + A(1,3) = 1 + 3 = 4 A(1,3) = B(1,3) + A(1,3) = 1 + 3 = 4 A(2,1) = B(2,1) + A(1,3) = 1 + 4 = 5 A(2,2) = B(2,2) + A(1,3) = 1 + 4 = 5 A(2,3) = B(2,3) + A(1,3) = 1 = 4 = 5

6.6. USO DO ASTERISCO EM ARRAYS (CROSS SECTIONS) ________________________________________________

Um asterisco pode ser usado no lugar de um ou mais subscritos de um array para indicar a variacao continua da fila correspondente a esses subscri- tos.

Seja DCL A(2,3,4); entao:

A(1,3,*) representa, em ordem, os elementos A(1,3,1), A(1,3,2), A(1,3,3) e A(1,3,4)

A(*,3,4) representa, em ordem, os elementos A(1,3,4) e A(2,3,4)

A(2,*,4) representa, em ordem, os elementos A(2,1,4), A(2,2,4) e A(2,3,4)

A(*,*,4) representa, em ordem, os elementos A(1,1,4), A(1,2,4), A(1,3,4), A(2,1,4), A(2,2,4), A(2,3,4)

A(*,*,*) representa, em ordem, todos os elementos do array, ou seja, A(1,1,1), A(1,1,2), A(1,1,3), A(1,1,4), A(1,2,1), A(1,2,2), A(1,2,3), A(1,2,4), A(1,3,1), A(1,3,2), A(1,3,3), A(1,3,4), A(2,1,1), A(2,1,2), A(2,1,3) ...

Se quiser fazer todos os elementos da 4a. linha de uma tabela declarada T(5,3) iguais a 0.12E-2, ter-se-a' T(4,*) = .12E-2;

Veja-se uma outra aplicacao. Seja copiar os elementos de uma determinada coluna de uma matriz para um vetor. A matriz e' declarada como sendo

6. ARRAY

Page 48

MAT(4,3) e o vetor como VET(4). A coluna a ser copiada e' a segund da ma- triz MAT, assim: VET = MAT(*,2); implicara' VET(1) = MAT(1,2), VET(2) = MAT(2,2), VET(3) = MAT(3,2) e VET(4) = MAT(4,2)

Page 38: Manual de PL1 - Completo

Uma outra facilidade do uso do asterisco em array e' o seu uso no atri- buto INITIAL como DCL A(8) FIXED INIT((4)(1,*)); implicando a inicializacao, apenas, dos elementos A(1), A(3), A(5) e A(7) com o valor 1.

6.7. APLICACOES _______________

1) Seja escrever uma sequencia de comandos que programara' a operacao de colocar o maior elemento de cada posicao correspondente de dois arrays num terceiro array.

DCL (A(3) INIT(1,3,5), B(3) INIT(-1,3,7), C(3)) FIXED(1); C = A + (B GT A) * (B - A);

A B C _____ _____ _____ 1 -1 1+(0)*(-1-1) = 1 1 3 3 3+(0)*(3-3) = 3 3 5 7 5+(1)*(7-5) = 7 7

2) Seja escrever um programa para imprimir as trajetorias possiveis da pedra TORRE, de um jogo de xadrez, a partir de uma posicao determinada. O tabuleiro de xadrez sera' simulado por uma de 25 posicoes (5 linhas e 5 colunas) e a posicao da pedra sera' lida em cartao perfurado. Entao:

6. ARRAY

Page 49

EX1C6: PROC OPTIONS(MAIN); DCL XAD(5,5) CHAR(1) INIT((25)(1)'.') ,(I,J) FIXED(1) ; GET LIST(I,J); XAD(I,*) = '*'; XAD(*,J) = '*'; XAD(I,J) = 'T'; _ PUT LIST(XAD(1,*)); │ PUT LIST(XAD(2,*)); │ PUT LIST(XAD(3,*)); │> ou PUT LIST(XAD(*,*)); PUT LIST(XAD(4,*)); │ ou PUT LIST(XAD); PUT LIST(XAD(5,*)); _│ END EX1C6;

Se fossem lidos de cartao os valores 2 e 3, respectivamente, para I e J, ter-se-ia para saida a seguinte disposicao:

_____________________________________________________ │ │ │ . . * . . │ * * T * * │ . . * . . │ . . * . . │ . . * . . │ . _______________

Page 39: Manual de PL1 - Completo

. . . . ._______________________________.

3) Suponha-se que se queira representar um array contendo os 3 nomes: PARANA', CABEDELO e SAO LUIZ.

Sabendo-se como um array e' armazenado, pode-se optar por uma das tres maneiras a seguir:

6. ARRAY

Page 50

_________________ _________________ _________________ 1 │ P A R A│N A │ │ P A│R A│N A│ │ │ P│A│R│A│N│A│ │ │ │________│________│ │____│___│___│____│ │__│_│_│_│_│_│_│__│ 2 │ C A B E│D E L O │ │ C A│B E│D E│L O │ │ C│A│B│E│D│E│L│O │ │________│________│ │____│___│___│____│ │__│_│_│_│_│_│_│__│ 3 │ S A O │L U I Z │ │ S A│O │L U│I Z │ │ S│A│O│ │L│U│I│Z │ │________│________│ │____│___│___│____│ │__│_│_│_│_│_│_│__│ . . . . . . . . . . . . . . . . . .______. .______. .__. ._. ._. .__. __ . . . . . . __ ' ' ' ' ' ' ' ' ' ' ' ' ' ' 1 2 1 2 3 4 1 2 3 4 5 6 7 8

(3,2) (3,4) (3,8) CHAR(4) CHAR(2) CHAR(1)

Se o identificador do array fosse, por exemplo, PORTOS, ter-se-ia:

DCL PORTOS(3,2) CHAR(4); ou DCL PORTOS(3,4) CHAR(2); ou DCL PORTOS(3,8) CHAR(1);

6. ARRAY

Page 51

7. COMANDOS DE DESVIOS ______________________

7.1. INTRODUCAO _______________

Em geral, em um procedimento PL/1, os comandos sao executados na sequencia em que eles aparecem na escrita do programa.

Ha', entretanto, alguns comandos que fazem com que essa execucao sequencial seja alterada, isto e', deixe de ser executada sequencialmente, passando a executar um outro comando, por meio de des- vios.

Page 40: Manual de PL1 - Completo

7.2. COMANDO DE DESVIO INCONDICIONAL (GOTO) ___________________________________________

Dentre os tipos de desvios que existem -- condicional e incondicional -- o comando GOTO e' usado para o caso de desvio incondicional. Sua forma e' "GOTO label" onde label pode ser uma constante label ou uma variavel label simples ou array.

Assim, num programa, ao ser encontrado um comando do tipo GOTO, a sequencia de execucao e' desviada para o comando cujo rotulo esta' espe- cificado no GOTO.

Eis um exemplo: Suponha-se que se deseje imprimir os elementos de uma colecao ou o quadrado dos elementos de uma outra colecao, tendo com informacao inicial um codigo de identificacao das colecoes.

Assim, poder-se-ia ter o seguinte programa, e o leitor, apos uma analise de seus comandos, deduzira' quais os tipos das colecoes e a tecnica usada com o comando GOTO.

EX1C7: PROC OPTIONS(MAIN); DCL LAB(2) LABEL INIT(LAB1,LAB2) ,I FIXED(1) ,A(5) DEC FIXED(3) ,B(10) BIN FLOAT(4) ; GET LIST(I); GOTO LAB(I); LAB1: GET LIST(A); PUT LIST(A); GOTO FIM; LAB2: GET LIST(B); _ B = B ** 2; │__ ou PUT LIST(B**2); PUT LIST(B); _│ FIM;

7. COMANDOS DE DESVIOS

Page 52

END EX1C7;

O comando GOTO nao tem grande aplicabilidade dentro das tecnicas da programacao estruturada, ou melhor dizendo, a necessidade de seu uso e' praticamente nula, pela simples configuracao da logica construida na programacao estruturada. Nao obstante, pode-se usar o comando GOTO com alguma disciplina, desde que nao prejudique a clareza e o bom entendimento da logica do programa, nao ferindo, com isso, os conceitos da programacao estruturada.

7.3. COMANDOS DE DESVIOS CONDICIONAIS _____________________________________

Normalmente, o comando GOTO e' usado em conjuncao com outros comandos de desvios condicionais, como o IF e o ON, que se verao a seguir.

7.3.1. COMANDO "IF"

Sua forma geral e':

________________________________________________________ │ │

Page 41: Manual de PL1 - Completo

│ {label:} IF expressao THEN unidade-1 ELSE unidade-2 │ │________________________________________________________│

onde expressao e' qualquer tipo de expressao aritmetica, logica ou de comparacao.

As unidades 1 e 2 podem ser um comando qualquer da linguagem ou um grupo de comandos e, nesse caso, eles tem que pertencer ao grupo DO, o qual tem a seguinte representacao: DO; (comandos) END;

1) IF A GT B THEN PUT LIST(A); ELSE PUT LIST(B); (expressao) (unidade-1) (unidade-2)

2) IF A GT B THEN PUT LIST(A); ELSE DO; B=B+1; PUT LIST(B); END;

O comando faz com que a expressao seja avaliada, executando a unidade-1 ou a unidade-2, se o resultado foi verdadeiro ou falso, respectivamente. Em termos de fluxograma, tem-se:

7. COMANDOS DE DESVIOS

Page 53

.. . . . . . Testa se a . <--- sim -------< expressao e' >------ nao ---> │ . verdadeira . │ │ . . │ │ . . │ │ .. │ ____│____________ ___________│________ │ Executa a │ │ Executa a │ │ │ │ │ │ unidade-1 │ │ unidade-2 │ │ │ │ │ │ (THEN) │ │ (ELSE) │ │_________________│ │____________________│ │ │ │ ___________________ │ │ │ │ │ V________________│ COMANDO │_______________V │ SEGUINTE │ │ │ │___________________│ │ │ │

Porem, nem sempre numa descricao de logica se tem necessidade de , dada uma expressao, executar as duas unidades, opcionalmente, e nesse caso usa-se o comando nulo (formado apenas pelo ponto-e-virgula) na unidade correspondente, por exemplo:

1) IF A = C THEN; ELSE GOTO SEGUE;

2) IF B = O THEN GOTO ADIANTE; ELSE;

O comando IF pode tambem aparecer sob a forma que se segue, contendo somente a unidade-1:

IF expresao THEN unidade-1

Note-se que a forma contendo apenas a unidade-2 nao existe. Se se tivesse

Page 42: Manual de PL1 - Completo

um caso como o mostrado no exemplo da expressao A = C, e se se quisesse usar a forma simplificada do comando IF, somente com a unidade- poder-se-ia, por uma simples modificacao da expressao, escrever: IF A NE C THEN GOTO SEGUE; ou, na forma completa: IF A NE C THEN GOTO SEGUE; ELSE;

Seguem-se alguns exemplosa de aplicacao do comando IF.

7. COMANDOS DE DESVIOS

Page 54

1) IF A LE B THEN DO; │ X = 2*A; │ ..... unidade 1 Y = Y**3; │ END; │

ELSE X = X + Y; ..... unidade 2

Y = Y - C; ..... comando seguinte

2) IF A LT C THEN Y = Y + 1; ..... unidade 1

ELSE X = X + 1; ..... unidade 2

X,Y = Z; ..... comando seguinte

3) IF B = C THEN ; ..... unidade 1

ELSE A = B + C; ..... unidade 2

X = Y; ..... comando seguinte

4) IF X = Y AND X = Z THEN PUT LIST (X,Y,Z); .. unidade 1

Y = Z; ..... comando seguinte

7. COMANDOS DE DESVIOS

Page 55

5) IF X = Y THEN IF A GT D THEN IF C LE A THEN X = X1; ELSE X = X2; ELSE X = X3;

C = A + B;

│ ** FLUXO DA SEQUENCIA DOS COMANDOS . . .

Page 43: Manual de PL1 - Completo

F . . V <---. X = Y .----> │ . . │ │ . . . │ . . . │ F │ . . V │ │<---. A > D .---> │ │ . . │ │ │ . . . │ │ . . . │ │ │ F . . V │ │ │<--. C <= A . -> │ │ │ . . │ │ │ │ . . │ │ │ │ . │ │ │ │ │ │ ___│____ ___│____ ___│____ │ │ X = X3 │ │ X = X2 │ │ X = X1 │ │ │________│ │________│ │________│ │ │ │ │ │ │ '--------->.<---------' │ │ │ │ │ │ '---------'----->.<--------------' │ │ │ ________│________ │ │ │ C = A + B │ │_________________│ │ │

7. COMANDOS DE DESVIOS

Page 56

6)Escrever um programa para determinar, entre dois valores lidos em cartao, qual o maior e qual o menor.

Seguem-se duas solucoes para o problema: │ EX2C7: │ EX3C7: PROC OPTIONS (MAIN); │ PROC OPTIONS (MAIN); DCL (X,Y,MAIOR,MENOR) │ DCL (X,Y,MAIOR,MENOR) FLOAT; │ FLOAT; GET LIST (X,Y); │ GET LIST (X,Y); IF X GT Y THEN │ IF X GT Y THEN MAIOR = X; │ DO; ELSE │ MAIOR = X; MAIOR = Y; │ MENOR = Y; IF X GT Y THEN │ END; MENOR = Y; │ ELSE ELSE │ DO; MENOR = X; │ MAIOR = Y; PUT LIST ('MAIOR =',MAIOR, │ MENOR = X; 'MENOR =',MENOR); │ END; END EX2C7; │ PUT LIST ('MAIOR =',MAIOR, │ 'MENOR =',MENOR); │ END EX3C7; │

7) Se a expressao constante do comando IF for um "string" de bits cons- tante ou variavel de comprimento igual a 1 (um), ou seja, se so' puder assumir os valores '0'B ou '1'B, poder-se-a' escrever:

Page 44: Manual de PL1 - Completo

........... DCL ABC BIT (1); ........... ........... IF ABC THEN A = A1 ; /* EXECUTAR SE ABC ='1'B */ ELSE A = A2 ; /* EXECUTAR SE ABC ='0'B */

Segue-se um programa para calcular o valor de uma das quatro operacoes aritimeticas, ao serem dados 2 valores e o nome da acao que indicara' a operacao desejada.

EX4C7: PROC OPTIONS (MAIN); DCL (A,B,C) FLOAT (10), /* areas de entrada e saida */ TITULO CHAR (11) VAR, /* tipo de operacao */ TIT (4) CHAR (11) VAR INIT ('SOMAR','SUBTRAIR','MULTIPLICAR', 'DIVIDIR'), OPERACAO (4) CHAR (12) VAR INIT ('MAIS','MENOS','VEZES', 'DIVIDIDO POR') ; /*ler operacao e valores */ GET LIST (TITULO,A,B);

7. COMANDOS DE DESVIOS

Page 57

/*se operacao for soma, soma e lista */ IF TITULO = TIT(1) THEN DO; C = A + B; PUT LIST ( A,OPERACAO (1),B,'IGUAL',C); END; /*senao, se operacao for subtracao, subtrai e lista */ ELSE IF TITULO = TIT(2) THEN DO; C = A - B; PUT LIST(A,OPERACAO(2),B,'IGUAL',C); END; /*senao, se operacao for multiplicacao, multiplica e lista */ ELSE IF TITULO = TIT(3) THEN DO; C = A * B; PUT LIST (A,OPERACAO(3),B,'IGUAL',C); END; /*senao, se operacao for divisao, divide e lista */ ELSE IF TITULO = TIT(4) THEN DO; C = A / B; PUT LIST (A,OPERACAO(4),B,'IGUAL',C); END; ELSE PUT LIST ('ERRO NO TITULO DA OPERACAO'); END EX4C7;

Assim para um conjunto de dados de entrada da forma:

_________________________ / │ 'MULTIPLICAR' 12 10 │

teriamos a seguinte saida impressa:

_________________________________________________________ │ │ 1.20000e+1 VEZES 1.00000e+01 IGUAL 1.20000E+02 │ _______________________________

Page 45: Manual de PL1 - Completo

│_________ ___ ___________

7.3.2. COMANDO "ON"

E' usado para especificar a acao a ser tomada sempre que uma interrupcao de execucao do programa ocorrer.

7. COMANDOS DE DESVIOS

Page 58

Na linguagem PL/I, ha' varias condicoes que sao automaticamente verifi- cadas pelo conjunto de circuitos do Sistema Operacional (hardware) e pe- los programas do Sistema Operacional (software).

Essas condicoes sao controladas por meio do comando ON usado na programacao PL/I, onde se especifica a acao a ser tomada pelo Sistema ao ser detectada uma condicao de erro.

Se o comando ON nao tiver sido executado antes de ocorrer uma interrupcao, uma acao-padrao do Sistema ocorrera' - e' a condicao ERROR.

A forma do comando ON e': "ON condicao acao", onde a condicao e' uma das que se verao adiante, como, por exemplo, a ERROR, que e' a padrao do Sis- tema. A acao e' um comando simples da linguagem ou um grupo de comandos formando um bloco BEGIN, cuja forma e' BEGIN; comandos... END;

Por exemplo:

ON ERROR GOTO FIM; - condicao ERROR - acao GOTO FIM

Este comando faz com que, ao ser detectada uma condicao de erro qualquer no programa, a sequencia de execucao seja desviada para o comando cujo label e' FIM.

ON ERROR BEGIN; PUT LIST ('ERRO,NO PROGRAMA,DESCONHECIDO'); GOTO FIM; END;

fazendo com que, ao ser detectada uma condicao de erro qualquer no pro- grama, seja impresa a mensagem 'ERRO,NO PROGRAMA,DESCONHECIDO' e a sequencia de execucao desviada para o comando cujo rotulo e' FIM.

As condicoes se dividem nos seguintes tipos:

1) condicoes computacionais;

2) condicoes de entrada e saida;

3) condicoes de check;

4) condicoes-padrao do sistema (condicao ERROR).

7.3.2.1. CONDICOES COMPUTACIONAIS

Sao aquelas que podem ocorrer durante um calculo de uma expressao, como,por exemplo, divisao por zero, conversao de constantes numericas, estouro da capacidade de armazenamento de um campo, etc.

7. COMANDOS DE DESVIOS

Page 59

Page 46: Manual de PL1 - Completo

A fig.7.1 apresenta algumas dessas condicoes:

7. COMANDOS DE DESVIOS

Page 60

_______________________________________________________________ │ CONVERSION │ Carater ilegal para conversao de contanstan- │ │ ( CONV ) │ tes numericas │ │_______________│_______________________________________________│ │ FIXEDOVERFLOW │ Valor excedendo a capacidade maxima permiti- │ │ ( FOFL ) │ da do campo │ │_______________│_______________________________________________│ │ OVERFLOW │ Valor excedendo a capacidade maxima permiti- │ │ ( OFL ) │ da do campo │ │_______________│_______________________________________________│ │ UNDERFLOW │ Valor excedendo a capacidade minima permiti- │ │ ( UFL ) │ da do campo │ │_______________│_______________________________________________│ │ ZERODIVIDE │ Tentativa de divisao por zero │ │ ( ZDIV ) │ │ │_______________│_______________________________________________│ │ SIZE │ Atribuicao de valores a campo nao suficien - │ │ │ temente grande │ │_______________│_______________________________________________│

FIG. 7.1

7.3.2.2. CONDICOES DE ENTRADA E SAIDA

Sao aquelas que podem ocorrer durante uma operacao de E/S, ou seja, na transmissao de dados, como, por exemplo, tentativa de ler um registro quando o arquivo ja' atingiu o fim de registros, etc.

A fig. 7.2 apresenta algumas dessas condicoes:

_______________________________________________________________ │ ENDFILE │ Ao ser detectado o fim de arquivo │ │ ( nome do arquivo )│ │ │_____________________│_________________________________________│ │ ENDPAGE │ Ao ser detectado o fim da pagina │ │ ( nome do arquivo )│ │ │_____________________│_________________________________________│ │ NAME │ Ao ser detectado um nome errado │ │ ( nome do arquivo )│ │ │_____________________│_________________________________________│

FIG. 7.1

Page 47: Manual de PL1 - Completo

7. COMANDOS DE DESVIOS

Page 61

7.3.2.3. COMANDOS DE " CHECK "

Sao aquelas que podem ocorrer por ocasiao de erros em strings, em dimensionamento de arrays e em caso de depuracao de programas.

A figura 7.3 apresenta algumas dessas condicoes:

_________________________________________________________________ │ CHECK │ Toda vez que houver uma modificacao no vlr. de │ │ ( lista ) │ alguma variavel da lista, ou referencia a elas │ │_______________│_________________________________________________│ │SUBSCRIPTRANGE │ Subscrito fora dos limites definidos para o │ │ ( SUBRG ) │ array │ │_______________│_________________________________________________│ │ STRINGRANGE │ Comprimento errado do argumento string em │ │ ( STRG ) │ SUBSTR │ │_______________│_________________________________________________│

FIG. 7.3

Algumas condicoes sao ditas "enabled" e outras sao ditas "disabled", ter- mos esses que significam, respectivamente, disponiveis e nao disponiveis automaticamente pelo Sistema, ou entao sao mais comumente conhecidas por LIGADAS e DESLIGADAS.

Das condicoes vistas anteriormente, as condicoes de CHECK estao todas DESLIGADAS e as demais estao LIGADAS, com excecao da de nome SIZE, uma das condicoes computacionais, que esta' desligada.

Algumas condicoes podem ser desligadas ou ligadas. A condicao ERROR e as condicoes de entrada e saida nao podem ser desligadas, sao permanen- temente ligadas. Ja' as de check e as computacionais podem.

Uma vez a condicao estando em estado de ligada, podera' ser usada diretamente no comando ON, conforme se pode ver:

EX5C7: PROC OPTIONS (MAIN); DCL SOMA FIXED (10) INIT(0), XAV BIT (1) INIT ('1'B); ON ENDFILE (SYSIN) XAV = '0'B; LER: GET LIST (VALOR); IF XAV THEN DO; SOMA = SOMA + VALOR; GOTO LER; END; ELSE PUT LIST('SOMA= ',SOMA); END EX5C7;

7. COMANDOS DE DESVIOS

Page 62

O comando ON deve ficar num lugar do programa que, pelo menos uma vez, na execucao, o fluxo logico passe por ele, para ativa-lo,sem o que, ao ocorrer a interrupcao, a acao especificada no comando nao sera' tomada.

Da mesma forma,um outro comando ON colocado em outro trecho do programa fara' com que a acao do anterior seja desfeita, passando a prevalecer

Page 48: Manual de PL1 - Completo

esta ultima. Se novamente o fluxo passar pelo comando anterior, a mudanca sera' feita no sentido de desfazer a acao do ultimo comando ON.

Uma caracteristica importante nos comandos ON e' que , ao ser efetuada a acao especificada neles, o fluxo de execucao do programa volta ao comando seguinte ao ponto que deu origem 'a condicao, a menos que,na acao a ser tomada, exista um comando de desvio, como o GOTO, por exemplo.

No caso do exemplo EX5C7, numa eventual leitura, atraves do comando GET LIST(VALOR); sera' detectado o fim do arquivo de entrada-padrao do Sis- tema (SYSIN), arquivo de cartoes perfurados, e nesse momento a acao espe- cificada, que e' colocar na variavel XAV o valor do bit string '0'B , e' efetuada e o fluxo logico e' desviado para o comando seguinte (comando IF), ao ponto que deu origem 'a condicao (comando GET LIST( VALOR);).

7.4. PREFIXO DE CONDICAO ________________________

O prefixo de condicao pode ser usado para fazer com que uma determinada condicao seja ligada ou desligada,dependendo do seu estado atual,durante a execucao do programa, de algunas comandos ou mesmo de um unico comando.

O prefixo de condicao e' o nome da condicao (se for para ligar) ou o nome da condicao apos a palavra NO ( se for para desligar ), colocado entre paranteses e seguido por dois pontos.

E' prefixado ao comando ou label do comando.

Pode-se ligar uma determinada condicao em procedimento (proc) e desliga'-la em alguns comandos dentro desse mesmo procedimanto.

Por exemplo:

(NOFIXEDOVERFLOW,SUBSCRIPTRANGE): A: PROC OPTIONS (MAIN); ......... ......... (FIXEDOVERFLOW): M= I ** N; ......... ......... (NOSUBSCRIPTRANGE): L: B = P(I) + P(J);

7. COMANDOS DE DESVIOS

Page 63

.......... END A;

Neste exemplo, a condicao FIXEDOVERFLOW, que normalmente e' ligada, per- manecera' desligada para todos os comandos da proc-A, exceto no comando M = I ** N. A condicao SUBSCRIPTRANGE permanecera' ligada para todos os co- mandos da proc-A, exceto no comando de rotulo L, ou seja B = P(I) + P(J);

No exemplo, para que seja tomada uma determinada acao, deverao existir na proc-A os comandos ON para as condicoes previstas ( fixedoverflow e subscriptrange), caso contrario apenas terao sido ligadas e desligadas as condicoes,e , se houver uma interrupcao de um desses tipos, a acao a ser tomada sera' a acao-padrao do sistema dada pela condicao ERROR. Essa acao-padrao consiste na impressao de uma mensagem a respeito da interrupcao e o cancelamento do programa imediatamente.

Ja' a condicao CHECK tem um tratamento diferente das demais condicoes. Quando usada como prefixo de condicao, ela permite que seja acrescentada

Page 49: Manual de PL1 - Completo

ao seu nome uma lista de variaveis, entre parenteses, indicando que, ao mesmo tempo em que ela estiver sendo ligada, essas variaveis serao impressas, com seus respectivos valores, sempre que houver uma modificacao, em seus valores.

Se a variavel for um label, seu nome sera' impresso toda vez que houver uma referencia ao seu nome, ou pela simples passagem do fluxo logico do programa por esse label.

Pode tambem ser usada no comando ON, mas sempre acompanhada da lista de variaveis. Por exemplo: ON CHECK (A,B) acao ; significando que, ao serem impressas as variaveis A e/ou B, uma acao devera', tambem, ser executada.

7.5 APLICACOES ______________

1) Esse programa e' semelhante ao programa EX5C7, apenas com uma outra apresentacao, inclusive nao aconselhada dentro das novas tecnicas de programacao estruturada, pelo uso do BEGIN na on-condition ( ver Ap. A)

EX6C7: PROC OPTIONS (MAIN); DCL SOMA FIXED (10) INIT (0), XAV BIT(1) INIT ('1'B); ON ENDFILE (SYSIN) BEGIN; PUT SKIP (5); PUT LIST ('SOMA =',SOMA); XAV = '0'B; END; GET LIST (VALOR); DO WHILE (XAV); SOMA = SOMA + VALOR;

7. COMANDOS DE DESVIOS

Page 64

GET LIST (VALOR); END; END EX6C7;

Para os dados de entrada: 1 2 3 4 5 6 7 8 9 10, ter-se-ia a seguinte saida impressa:

_________________________________ │ SOMA = 55 │ │ │ │ │ │ +---> col. 1 +--> col.25 │ │_________________________________│

2) Programa para teste da condicao SUBSCRIPTRANGE usada somente uma vez e desviando o controle do programa para 2 pontos distintos por meio do uso de 'label' variavel.

EX7C7: (SUBSCRIPTRANGE): PROC OPTIONS (MAIN); DCL A (-1:1) FLOAT, SEGUE LABEL (SEG1,SEG2) INIT (SEG1) ; ON SUBSCRIPTRANGE BEGIN ; PUT SKIP (3) LIST (I); GOTO SEGUE; END; DO I = -3 to 3; A(I) = I; SEG1:

Page 50: Manual de PL1 - Completo

END; PUT SKIP (3) LIST(A); SEGUE = SEG2; DO I = 1 TO 4; A(I) = A(I-1); SEG2; END; PUT SKIP (3) LIST (A); END EX7C7;

7. COMANDOS DE DESVIOS

Page 65

Obteria-se, como saida, o seguinte:

________________________________________________ │ - 3 │ │ - 2 │ │ 2 │ │ 3 │ │ - 1.0000E + 00 0.00000E + 00 1.00000E + 00│ │ 2 │ │ 3 │ │ 4 │ │ - 1.0000E + 00 0.00000E + 00 0.00000E + 00│ │ │ │________________________________________________│

3) Programa para testar o uso da "on-condition" CHECK onde a mesma e' ativada todas as vezes que 'as variaveis A(array) e I sao atribuidos va- lores durante o processamento, conforme se pode verificar pela saida apresentada a seguir.

EX8C7: PROC OPTIONS (MAIN); DCL (A(10),I) FIXED ; A = 0; (CHECK(A,I)): BEGIN; DO I = 1 TO 5; A(I) = 3*I; END; END; END EX8C7;

S A I D A D O P R O G R A M A - EX8C7

I = 1 A(1)= 3 A(2)= 0 A(3)= 0 A(4)= 0 A(5)= 0 A(6)= 0 A(7)= 0 A(8)= 0 A(9)= 0 A(10)= 0

I = 2 A(1)= 3 A(2)= 6 A(3)= 0 A(4)= 0 A(5)= 0 A(6)= 0 A(7)= 0 A(8)= 0 A(9)= 0 A(10)= 0

I = 3 A(1)= 3 A(2)= 6 A(3)= 9 A(4)= 0 A(5)= 0 A(6)= 0 A(7)= 0 A(8)= 0 A(9)= 0 A(10)= 0

I = 4 A(1)= 3 A(2)= 6 A(3)= 9 A(4)= 12 A(5)= 0 A(6)= 0 A(7)= 0 A(8)= 0 A(9)= 0 A(10)= 0

Page 51: Manual de PL1 - Completo

7. COMANDOS DE DESVIOS

Page 66

I = 5 A(1)= 3 A(2)= 6 A(3)= 9 A(4)= 12 A(5)= 15 A(6)= 0 A(7)= 0 A(8)= 0 A(9)= 0 A(10)= 0

I = 6

7. COMANDOS DE DESVIOS

Page 67

8. COMANDO " DO " _________________

8.1. COMANDO DE EXECUCAO DE 'LACOS' ___________________________________

Uma outra maneira de se desviar o fluxo logico de um programa, alem dos comandos de desvios vistos - GOTO, IF e ON, e' usando a tecnica de lacos ('looping'). Pode-se entender como laco a execucao de um conjunto de co- mandos varias vezes.

Eis um caso simples. O programa que se segue usa um laco para ler 5 va- lores, perfurados em cartao, um de cada vez, e esse laco e' controlado pelo comando IF que, de acordo com uma condicao baseada num contador, fara' o programa seguir sua sequencia logica normal, abandonando o laco para imprimir os 5 valores lidos e terminar o programa.

EX1C8: PROC OPTIONS (MAIN); DCL A(5) DEC; I = 0; -----> VOLTA: │ I = I + 1; │ IF I > 5 THEN │ GOTO FORA; --------> │ GET LIST (A(I)); │ desvio para fora <----- GOTO VOLTA; │ do laco FORA: <-------- PUT LIST (A); END EX1C8;

8.2. O COMANDO 'DO' ___________________

Page 52: Manual de PL1 - Completo

O mesmo programa poderia ser reescrito usando o comando DO, que e' o co- mando que serve para programar Lacos, como mostrado a seguir:

EX2C8: PROC OPTIONS(MAIN); DCL A(5) DEC; DO I = 1 TO 5 BY 1; <-------- GET LIST(A(I)); │ Laco END; --------> PUT LIST(A); END EX2C8;

O comando DO, assim usado, significa executar o comendo GET LIST tantas vezes quantas forem as variacoes da variavel I, desde o valor 1 ate' o valor 5, com incrementos de 1 em 1, ou seja, o comando sera' executado 5 vezes.

8. COMANDO " DO "

Page 68

Formas do comando "DO":

DO variavel de controle = especificacao ; (comandos); (comandos); END;

ou

DO WHILE(expressao); (comandos); (comandos); END;

ou ainda combinando-se as duas formas.

Na primeira forma, a variavel de controle pode ser uma variavel ou uma pseudovariavel (isso sera' visto mais tarde, quando se tratar de builtin) e pode ser usada dentro do laco como subscrito de arrays. A especificacao pode apresentar-se de duas maneiras:

1. expressao-1, expressao-2, ..., expressao-n Especifica que o comando (ou comandos) existente no laco-DO sera' executado, em primeiro lugar, com o valor da variavel de controle igual ao valor da expressao-1, em seguida com o valor igual ao da expressao-2, e assim, sucessivamente, ate' ter assumido o valor da expressao-n.

Exemplos:

. DO KONT = 1,2,3,4,5; X(KONT) = 0; END;

. DO IJK = 12,20,28,10,20,25; VALOR = VALOR + B(IJK); END;

. DO L = I,I+1,I+2,10; GET LIST(A(I)); END;

2. expressao-1 TO expressao-2 BY expressao-3 ou expressao-1 BY expressao-3 TO expressao-2

Especifica que o comando (ou comandos) existentes no laco-DO sera' executado com o valor da variavel de controle inicialmente assumindo o valor da expressao-1, em seguida incrementando esse valor com o va-

Page 53: Manual de PL1 - Completo

lor da expressao-3, e assim sucessivamente, enquanto for menor ou igual ao valor da expressao-2.

Exemplo:

8. COMANDO " DO "

Page 69

DO I = 1 TO 5 BY 1; X(I) = 0; END;

Se BY expressao-3 for omitido, sera' assumido o valor 1 para o incre- mento.

Veja-se a segunda forma de apresentacao do comando DO. DO WHILE (expressao)

Especifica que o comando (ou comandos) no laco-DO sera' executado repetitivamente, ate' que a condicao seja falsa, ou seja, sera' executado enquanto o valor da expressao for verdadeiro.

Exemplo:

I = 1; DO WHILE (I <= 5); X(I) = 0; I = I + 1; END;

Finalmente, pode-se ter qualquer tipo de combinacoes das formas apresentadas para o comando DO.

8.3. EXEMPLOS _____________

1 ) I = 1; DO J = 1 BY 1 WHILE(I <= 5); X(J) = 0; I = I + 1; END;

2 ) DO I = 1,2,5 BY 1 TO 10,12 BY 2 WHILE(I LE 16),3,4; PUT LIST(I); END;

Nesse exemplo, a variavel I assumira' os seguintes valores:

1,2, 5,6,7,8,9,10, 12,14,16, 3,4

3 ) I = 5; DO I = 1 TO I + 2; Y(I) = I; END;

Esse exemplo e' o mesmo que DO I = 1 TO 7; Y(I) = 1; END; pois a expressao (I + 2) e' avaliada antes de entrar no laco-DO e a variavel de

8. COMANDO " DO "

Page 70

controle do laco-DO, a variavel I, nao mais interferira' na expressao (I + 2).

4 ) DO I = 1 TO 1000; SOMA = SOMA + I;

Page 54: Manual de PL1 - Completo

END;

Para que esse exemplo funcione corretamente, e' necessario ter inicializado a variavel SOMA com o valor zero, ou pelo INIT no comando DECLARE ou por comando de atribuicao.

5 ) DO I = 1 TO 10 WHILE (A LT B); (a) (comandos) END; DO I = 1 TO 10, WHILE (A LT B) (b) (comandos) END;

No caso (a), o laco se repetira' 10 vezes, a menos que A seja maior ou igual a B, quando entao estara' terminado o laco-DO.

No caso B, o laco se repetira' 10 vezes e continuara' dai em diante, ate' que A seja maior ou igual a B.

6 ) DO I = 1 TO 4, 9 TO 8 BY -0,2; (comandos) END; DO X = 1 TO 4, 9 TO 8 BY -0,2; (comandos) END;

As variaveis de controle dos dois lacos-DO assumirao os seguintes valo- res: I = 1,2,3,4,9,8 X = 1.,2.,3.,4.,9.,8.8,8.6,8.4,8.2,8.0

7 ) Se ABC foi declarada como CHAR, pode-se ter:

DO ABC = 'A', 'B', 'C', 'D'; (comandos) END;

8 ) DO A = B+2*C TO D**2, X, Y; (comandos) END;

9 ) Pode-se usar o comando DO tambem nos comandos GET e PUT LIST. Tendo-se DCL C(5) FIXED(1); os seguintes comandos sao

8. COMANDO " DO "

Page 71

identicos:

a) GET LIST(C);

b) DO I = 1 TO 5; GET LIST(C(I)); END;

c) DO I = 1,2,3,4,5; GET LIST(C(I)); END;

d) I = 1; DO WHILE(I GT 5); GET LIST(C(I)); I = I + 1; END:

e) GET LIST((C(I) DO I = 1 TO 5));

Page 55: Manual de PL1 - Completo

O ultimo caso e' a aplicacao do DO implicito no comando GET. Tambem pode ser usado no comando PUT.

Podem-se ter varios lacos-DO, uns dentro dos outros, formando o que se chama de DO aninhado. ________ │ SOMA = 0; │ SOMA = 0; │ - DO I = 1 TO 10; │ - D: DO I = 1 TO 10; ' │ ' ' - DO J = 1 TO 5; │ '------ DO J = 1 TO 5; ' ' │ ' ' ' - DO K = 1 TO 3; │ '--------- DO K = 1 TO 3; ' ' ' │ ' ' ' ' SOMA=SOMA+D(I,J,K); │ ' SOMA=SOMA+D(I,J,K); ' ' ' │ ' ' ' - END; │ '--- END D; ' ' │ ' - END; │ ' │ - END; │

Essas duas apresentacoes sao perfeitamente validas. Na primeira, usou-se um END para cada DO. Na segunda, usou-se apenas um END para os tres DO e, nesse caso, foi preciso usar um label no primeiro DO e no END tambem.

Essa operacao e' permitida quando todos os lacos terminam num mesmo ponto.

Nao se pode, de qualquer que seja o ponto de um programa, entrar num laco de DO, a menos que se tenha saido e retornado ao ponto imediatamente seguinte.

8. COMANDO " DO "

Page 72

Esquematizando-se, tem-se:

<-+ _ ___DO _│ pode ___DO │ nao __L: DO <--+ │ │ <-+ │ <--+ │ │ __DO │ __DO │___DO _│ │ ││ _ ││ _ │ <-+ │ pode ││ _DO │ nao ││ _DO │ nao │___DO │ │ │││ <-+ │││ <-+ │ _│ │ │││ │││ │ __│ │││_END │││_END │___END L; ││ <-+ ││ ││__END │ ││__END │ │ nao │ │___END _│ │___END

_DO _DO │ - _____ │ - _______ │ │ │ │ │ - <-+ │ │ - <---+ │ │ │ │ pode │ │ │ │ │ │ │ │ │ pode │ │ │ │ │ │ │_END │ │ │_END │ │ _│ │ │ │ - <---+ - <----+--+ - │ - │ - _____│

Ao terminar um laco-DO, a variavel de controle sempre contera' o valor

Page 56: Manual de PL1 - Completo

acrescido do valor do incremento do laco (expressao-3).

__DO I = 1 TO 5 __DO J = 2 TO 7 BY 3; __DO K = 1 TO 5 BY 2; │ │ │ │__END; │__END; │__END;

( a ) ( b ) ( c )

Nos casos apresentados, ter-se-ao os seguintes valores para as variaveis de controle, I, J e K, apos a execucao dos lacos-DO:

( a ) I = 6 ( b ) J = 8 ( c ) K = 7

Se o valor da expressao-1 for maior que o valor da expressao-2, o laco nao sera' executado.

Se o valor da expressao-1 for igual ao valor da expressao-2, o laco sera executado apenas uma vez.

8. COMANDO " DO "

Page 73

8.4. APLICACOES _______________

1 ) Escrever um grupo DO para calcular os quadrados dos inteiros pares positivos ate' 1 000, atribuindo cada valor calculado aos elementos de um array denominado QUADRADOS.

Solucao: DO I = 2 TO 1000 BY 2; QUADRADOS (I/2) = I * I; END;

2 ) Escrever um laco-DO para acumular a soma dos inteiros multiplos de 3, entre 1 e 1 000 .

Solucao: SOMA = 0; DO I = 3 TO 1000 BY 3; SOMA = SOMA + I; END;

3 ) Escrever um laco-DO para calcular as areas dos circulos de raios 3.2, 8.9, 10.5 e dos circulos de raios variando de 3/4 a 3 polegadas, com incrementos de 1/4 de polegada.

Solucao: J = 1; DO X = 3.2,8.9,10.5, 0.75 TO 3.0 BY 0.25; AREAS(J) = 3.14 * X **2; J = J + 1; END;

4 ) Escrever um trecho de programa para imprimir o quadrado, o cubo, a quarta potencia e a quinta potencia dos numeros de 1 a 10, assim como os proprios numeros.

Solucao: DO Y = 1 TO 10; PUT LIST(Y,Y**2,Y**3,Y**4,Y**5); END;

Outra Solucao:

PUT LIST((Y,Y**2,Y**3,Y**4,Y**5 DO Y = 1 TO 10));

5 ) Um programa completo escrito em apenas um cartao:

P: PROC OPTIONS(MAIN);PUT LIST((Y,Y*Y,Y**.5,1/Y,2*Y

Page 57: Manual de PL1 - Completo

│ DO Y = 1 TO 10)); END; +--> col. 2 ou mais │ no max. col. 72 <--+

8. COMANDO " DO "

Page 74

9. FUNCOES INTERNAS ___________________

9.1. INTRODUCAO _______________

Sao "procedures" prontas, existentes na linguagem, de facil manejo para o programador, que ajudam na resolucao de determinados tipos de problemas. Essas "procedures" evitam laboriosos esforcos de programacao.

Sao referenciados pelos seus proprios nomes, podendo ter ou nao argumen- tos.

Por exemplo, SQRT(x) e' o nome de uma BUILT-IN FUNCTION que calcula a raiz quadrada do argumento x.

Assim, se se tiver A = SQRT(B); o valor da raiz quadrada da variavel B sera' armazenado na variavel A. Da mesma forma, o comando PUT LIST( SQRT(Y)); fara' com que o valor da raiz quadrada da variavel Y seja impresso.

Para esse tipo de built-in function, o argumento 'x' podera' ser uma expressao, como, por exemplo, no calculo de uma das raizes da equacao do segundo grau: X1 = ( -B + SQRT( B * B - 4 * A * C )) / ( 2 * A )

Serao vistas aqui apenas algumas destas funcoes.

9.2. FUNCOES ARITMETICAS ________________________

® ABS ( arg ) ---

Retornando o valor absoluto do argumento. Se X = -32.5; entao B = ABS(X); implica B = 32.5 .

® ADD ( arg1, arg2, p, q ) ---

Retornando um valor, soma dos argumentos, com precisao ( p,q ) se os argumentos forem FIXED e com precisao p se forem FLOAT. Se A e B sao DEC FIXED e, A = 3.5 e B = 1.4, o comando C = ADD ( A, B, 3, 2 ); implica C = 4.90, com precisao ( 3, 2 ) Essa built-in pode ser usada tambem para a subtracao: ADD (arg1,-arg2,p, q).

® DIVIDE ( arg1, arg2, p, q ) ---

Identica 'a ADD. E' usada para a divisao.

® MULTIPLY ( arg1, arg2, p, q ) ---

Identica 'a ADD. E' usada para a multiplicacao. Eis alguns exemplos praticos:

9. FUNCOES INTERNAS

Page 75

1) DCL A FIXED BINARY(31) INIT(8831);

Page 58: Manual de PL1 - Completo

DCL B FIXED DECIMAL(8,6) INIT(13.031); DCL C FIXED BINARY(31) INIT(0); C = A+B; implicara' a condicao de erro FIXEDOVERFLOW. C = ADD(A,B,31,0) implicara' o valor 8844.31 para a varia - vel C, mantendo a mesma precisao inicial.

2) DCL (X,Y) DEC FIXED(7,0), Z DEC FIXED(15,15); X = 1; Y = 3; Z = X/Y; implicara' o valor .333333300000000 para Z Z = DIVIDE(X,Y,15,15); implicara' o valor .333333333333333 para Z

3) DCL (X,Y,Z) DEC FIXED(10,9); X = 1.0; Y = 1.0; Z = X*Y; implicara' a condicao de erro de FIXEDOVERFLOW Z = MULTIPLY(X,Y,10,9); implicara' o valor 1.000000000 para Z

® CEIL ( arg ) ---

Retornando o menor inteiro maior ou igual que o valor do argumento. Se A = -1.23; o comando B = CEIL(A); implica B = -1 Se A = 4.9; B = CEIL(A); implica B = 5.0

® FLOOR ( arg ) ---

Retornando o maior inteiro menor ou igual que o valor do argumento. Se B = 4.9; o comando C = FLOOR(B) implica C = 4.0

® TRUNC ( arg ) ---

Retornando o valor de CEIL(arg) se arg for menor que zero; retornando o valor de FLOOR(arg) se arg for maior ou igual a zero.

® FIXED ( arg, p, q ) / FLOAT ( arg, p ) ---

Retornando a conversao correspondente do argumento para a precisao indicada. Se P e Q forem omitidos, a precisao sera' a declarada de cada tipo.

Se A FIXED(3,2) e B FLOAT(4) e A = 3.2; o comando B= FLOAT(A); impli- cara' B = 3.200E+00. Se a seguir se tiver A = FIXED(B,5), o valor de A sera' 00003.

® SIGN ( arg ) ---

Retornando os seguintes valores: -1, 0 e 1 se o argumento for ne- gativo, nulo ou positivo, respectivamente.

® MAX ( arg1, ... , arg n ) / MIN ( arg1,... , arg n ) ---

Retornando, respectivamente, o maior e o menor valor da lista de ar- gumentos. Se B = 2, c = 3 e D = -4, os comandos:

9. FUNCOES INTERNAS

Page 76

E = MAX (B,C,D); implicara' E = 3 F = MIN (B,C,D); implicara' F = -4

Outro exemplo interessante e' o de se determinar o maior e o menor elemento de um array.

Solucao: ( para o caso do maior elemento ) MAIOR = B(1); DO I = 2 TO N; E = B(I); MAIOR = MAX (MAIOR,E);

Page 59: Manual de PL1 - Completo

END;

® ROUND ( arg , n ) ---

Retornando o valor arredondado do argumento, na n-esima casa. Se A e B sao DEC FIXED(7,4) e A = 123.4567, entao os comandos que se seguem tem as seguintes implicacoes:

B = ROUND(A,3) 123.4570 B = ROUND(A,2) 123.4600 B = ROUND(A,1) 123.5000 B = ROUND(A,0) 124.0000 B = ROUND(A,-1) 120.0000 Se C = 9.99 o comando B = ROUND(C,0) implica B = 10.00

O valor do argumento podera' ser positivo ou negativo.

® MOD ( arg1 , arg2 ) ---

Retornando o resto da divisao do Arg1 pelo Arg2, respeitando a seguinte regra:

" se os sinais do dividendo e do divisor forem: iguais - o valor retornado sera o resto da divisao; desiguais - o valor retornado sera' a diferenca entre o divisor e o resto, ignorando os sinais, ou seja, em valores absolutos. "

Se B = 29 e C = 6, o comando D = MOD (B,C); implicara' o valor 5 para a variavel D (29/6 = 4 X 6 + 5).

Se B = -29 e C = 6, o comando E = MOD (B,C); implicara' o valor 1 para a variavel E (29/6 = 4 X 6 + 5 .: 6 - 5 = 1)

9.3. FUNCOES MATEMATICAS ________________________

® LOG ( arg ) ---

9. FUNCOES INTERNAS

Page 77

Retornando o logaritmo neperiano do argumento. Se A = 2, o comando B = LOG (A); implicara' o valor 0.693147 para B .

® LOG10 ( agr ) ---

Retornando o logaritmo decimal do argumento. Se B = 200, o comando C = LOG10 (B); implicara' C = 2.30103 .

Se B = 0.002 C = LOG10 (B); implicara' C = -2.69896 ( logaritmo ne- gativo) .

® LOG2 ( arg ) ---

Retornando o logaritmo na base 2 do argumento. Se D = 2, o comando G = LOG2 (D); implicara' G = 1.0

® SIN (arg) / SIND ( arg ) ---

Retornando o seno do argumento em radianos e em graus, respecti- vamente .

® COS ( arg ) / COSD ( arg ) ---

Retornando o co-seno do argumento em radianos e em graus, respecti-

Page 60: Manual de PL1 - Completo

vamente .

® TAN ( arg ) / TAND ( arg ) ---

Retornando a tangente do argumento em radianos e em graus, respecti- vamente .

® ATAN ( arg ) / ATAND ( arg ) ---

Retornando o arco tangente do argumento em radianos e em graus res- pectivamente.

® EXP ( arg ) ---

Retornando o valor de E elevado a ARG , sendo E a base neperiana de valor aproximado igual a 2,718281828 .

9.4 FUNCOES " STRING " ______________________

® INDEX ( arg1 , arg2 ) ---

Retornando a posicao que o argumento2 ocupa no argumento1 . Se B = 'ABCDEF', o comando C = INDEX (B,'D') implicara' C = 4 .

Se o argumento2 nao existir, o valor retornado sera' igual a zero .

Para o mesmo valor de B, o comando a seguir, D = INDEX (B,'CDE'); im- plicara' D = 3 .

9. FUNCOES INTERNAS

Page 78

Outro exemplo seria A = 'BC'; E = INDEX (B,A); -> E = 2

® LENGTH ( arg ) ---

Retornando um valor igual ao comprimento do argumento . Se B = 'COMPRIMENTO' e C = LENGTH (B); entao C = 11 .

® SUBSTR ( arg , p , c ) ---

Retornando um sub-string de comprimento c, a partir da posicao p, no string que compoe o argumento . Se c for omitido, o comprimento do sub-string sera' o da posicao p ate' o final do string argumento .

Se C = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', o comando B = SUBSTR (C,3,5); implicara' o sub-string 'CDEFG' para a variavel B .

® REPEAT ( arg , c ) ---

Retornando um string formado pela concatenacao do argumento com c vezes seu valor .

Se B = 'XY' o comando C = REPEAT (B,2); implicara' o seguinte valor de string para C: 'XYXYXY'

® VERIFY ( arg1 , arg2 ) ---

Retornando um valor de acordo com a seguinte regra: "Se todos os caracteres que compoem o argumento1 existirem no argumento2, retornara' o valor 0 (zero). Se um caracter do argumento1 nao existir no argumento2, retornara' a posicao deste caracter no argumento1."

Se B CHAR (26) contiver todas as 26 letras do alfabeto e em C existir o string 'AVESTRUZ', o comando D = VERIFY (C,B) implicara' o valor

Page 61: Manual de PL1 - Completo

zero para a variavel D, enquanto que, se em C existir, por exemplo, o string 'PP2QQ3', o mesmo comando D = VERIFY (C,B); retornara' o valor 3 para a variavel D. o)

Veja-se um outro exemplo, muito utilizado na pratica, que serve para fazer consistencia numerica em determinados campos .

Seja B CHAR (10) INIT ('1234567890'), C CHAR (3) e POS BINARY FIXED .

Entao :

POS = VERIFY (C,B); IF POS ¬= 0 THEN PUT LIST ('CAMPO C NAO NUMERICO'); (comandos seguintes)

® TRANSLATE ( arg1 , arg2 , arg3 ) ---

Retornando o string do argumento1, com os caracteres existentes no argumento3, modificados pelos caracteres existentes no argumento2, na

9. FUNCOES INTERNAS

Page 79

ordem de aparecimento desses caracteres. Se A e B sao CHAR (6) e P e Q sao CHAR (1), e mais, B = 'b12bb3', P = '0' e Q = 'b', o comando A = TRANSLATE (B,P,Q); implicara' o string '012003' para a variavel A.

Outro exemplo:

DCL (P,Q) char (3), (A,B) CHAR (6); B = 'b12A+5'; P = '0E-'; Q = 'bA+'; A = TRANSLATE (B,P,Q); A variavel A ficara' com o string = '012E-5', ou seja : b foi substituido por 0 A foi substituido por E + foi substituido por - (obs: 'b' corresponde a branco)

® CHAR ( arg , n ) / BIT ( arg , n ) ---

Retornando um string de caracteres ou de bits, respectivamente de comprimento n, se for especificado. Se nao for especificado o comprimento sera' dado pelas regras de conversoes da linguagem.

Seja I FIXED BINARY (3), C CHAR (6) e D BIT (5). Seja, ainda, I = 7. Entao:

C = BIT (I) implicara' C = '111bbb' C = BIT (I,4) implicara' C = '1110bb' C = CHAR (I) implicara' C = 'bbbb7b' C = CHAR (I,4) implicara' C = 'bbbbbb' Enquanto que C = I implicaria C = 'bbbb7b' e D = I implicaria D = '11100'B D = BIT (I) implicara' D = '11100'B D = BIT (I,4) implicara' D = '11100'B D = CHAR (I) implicara' D = erro de conversao D = CHAR (I,4) implicara' D = erro de conversao (obs: 'b' corresponde a branco)

® HIGH(n) / LOW(n)

Retornando um string de caracteres de comprimento n, formado pelos caracteres mais altos (hexadecimal FF) ou mais baixo (hexadecimal 00) permitidos pela linguagem, respectivamente.

Page 62: Manual de PL1 - Completo

® STRING(arg)

Retornando um string de caracteres formado pela concatenacao de todos os elementos de uma variavel tipo array, estrutura ou mesmo variavel simples. Se um dos elementos da variavel for de comprimento variavel, o string resultante sera' tambem de comprimento variavel.

9. FUNCOES INTERNAS

Page 80

Seja C(3) CHAR(4) INIT ((3)(1)'XYZ'); entao o comando B = STRING(C); implicara' o valor 'XYZ XYZ XYZ' para a variavel B, declarada como CHAR(12),por exemplo.

9.5. FUNCOES DE ARRAYS ______________________

® PROD(arg) / SUM(arg)

Retornando o produto ou a soma,respectivamente, de todos os elementos do array (argumento).

Se A(1) = 3;A(2)=5; A(3)=2; os comandos B=PROD(A); e C = SUM(A); implicarao os valores 30 para a variavel B e 10 para a variavel C.

® POLY(arg1,arg2)

Retornando o valor de um polinomio cujos coeficientes sao os elemen- tos do array que constitui o arg1 e a variavel o arg2. Por exemplo: Sejam os valores 10,30,10 e 20 elementos do array denominado D. Se se tiver X =5; e Y=POLY(D,X); ter-se-a' o valor de 10 + 30 * 5 + 10 * 5**2 + 20 * 5**3 = 10 + 150 + 250 + 2500 = 2910 para a variavel Y. O numero de elementos do array determina o numero de termos do polinomio. Tudo se passa como se se tivesse a seguinte programacao:

S = 0; DO I=0 TO (N-M); S = S + ARRAY(M+I)*X**I; END;

onde N e' o limite superior e M o inferior do ARRAY.

® HBOUND(arg,n) / LBOUND(arg,n)

Retornando o valor do limite superior e o valor do limite inferior, respectivamente, do array especificado como argumento, de sua n-esima dimensao.

DCL D(1:5,10)

B=HBOUND(D,2) implicara' B = 10 C=HBOUND(D,1) implicara' C = 5 E=LBOUND(D,1) implicara' E = 1 F=LBOUND(D,2) implicara' F = 1

DO I = HBOUND(A,1) TO LBOUND(A,1) BY-1; (comandos) END;

e' o mesmo que:

DO I = 10 TO -10 BY -1; (comandos)

9. FUNCOES INTERNAS

Page 63: Manual de PL1 - Completo

Page 81

END;

se A foi declarada como: DCL A(-10:10);

® DIM(arg,n)

Retornando o valor da n-esima dimensao do array especificado como ar- gumento.

Se DCL D(10,-1:3,15,30) entao o comando B=DIM(D,3) implicara' valor 15 para a variavel B.

O comando C=DIM(D,2) implicara' o valor 5 para C.

9.6. FUNCOES SEM ARGUMENTOS ___________________________

® DATE

Retornando um string de caracteres da forma 'AAMMDD', onde AA sao dois caracteres referentes ao ano, MM dois referentes ao mes e DD dois referentes ao dia. E' a data do dia corrente.

Assim, o comando E = DATE; implicara' o string '851218' indicando 18 de dezembro de 1985. A variavel E deve ter sido declarada como CHAR(6), por exemplo.

® TIME

Retornando um string de caracteres da forma 'HHMMSSCCC', onde HH sao dois caracteres referentes as horas, MM dois referentes aos minutos, SS dois referentes aos segundos e CCC tres caracteres referentes a milesimos de segundo.

9.7. PSEUDOVARIAVEIS ____________________

Algumas das "BUILT-IN FUNCTION" podem ser usadas como variaveis, isto 'e, podem ser usadas do lado esquerdo do sinal de atribuicao, na lista de variaveis de um comando de saida(como o PUT LIST e outros que serao vis- tos mais adiante) etc.

Se se tiver: DCL D CHAR(5) INIT('NORMA'); SUBSTR(D,1,1) = 'F'; apos a execucao do comando acima, a variavel D contera' o string 'FORMA'.

A Built-in Function STRING tambem pode ser usada como pseudovariavel.

9. FUNCOES INTERNAS

Page 82

9.8. APLICACOES _______________

1) Programa para calcular o produto entre duas matrizes.

EX1C9: PROC OPTIONS(MAIN); DECLARE B(2,3), C(3,2), D(2,2) ; GET LIST(B,C); DO I = 1 TO 2;

Page 64: Manual de PL1 - Completo

DO J = 1 TO 2; D(I,J) = SUM(B(I,*) * C(*,J); END; END; PUT LIST(D); END EX1C9;

2) Programa para determinar a frequencia de aparecimento das letras que compoe uma palavra, ou,mais especificamente, um string de caracteres.

EX2C9: PROC OPTIONS(MAIN); DCL ALFABETO CHAR(26) INIT('ABCDEFGHIJKLMNOPQRSTUVWXYZ') ,SENTENCA CHAR(80) VAR ,LETRA CHAR(1), XAV FIM ARQ BIT(1) ,(FREQ,P,Q,R) FIXED ; ON ENDFILE(SYSIN) XAV FIM ARQ = 'O'B; XAV_FIM_ARQ = '1'B; GET LIST(SENTENCA); DO WHILE(XAV_FIM_ARQ); DO Q = 1 TO 26 BY 1; LETRA = SUBSTR(ALFABETO,Q,1); FREQ = 0; R,P = INDEX(SENTENCA,LETRA); DO WHILE(P NE 0); FREQ = FREQ + 1; P = INDEX(SUBSTR(SENTENCA,R + 1),LETRA); R = R + P; END; PUT LIST(SUBSTR(ALFABETO,Q,1), '=', FREQ)SKIP; END; GET LIST(SENTENCA); END; END EX2C9;

Se a entrada para este programa for o string de caracteres 'INCONSTITUCIONALISSIMAMENTE', valor esse lido para a variavel SENTENCA, ter-se-a para saida a seguinte disposicao:

A = 2

9. FUNCOES INTERNAS

Page 83

B = 0 C = 2 D = 0 E = 2 F = 0 G = 0 H = 0 I = 5 J = 0 K = 0 L = 1 M = 2 N = 4 O = 2 P = 0 Q = 0 ..(etc) │ │ │ V V V col.1 col.25 col.49

3) Programa para testar o uso do asterisco em array,o uso das built-in

Page 65: Manual de PL1 - Completo

SQRT, HBOUND, LBOUND, SUM e PROD. E' um exemplo puramente didatico.

EX3C9: PROC OPTIONS(MAIN); DCL (A(2,3),B(2,3) INIT(1,2,3,4,5,6) ,C(2,3) INIT(3) (1,2))) FIXED(3,1) ; (1) PUT SKIP LIST(B(1,*)); (2) PUT SKIP LIST(B(*,2)); A = B + C; (3) PUT SKIP(2) LIST(A(1,*)); (4) PUT SKIP LIST(A(2,*)); A(*,3) = SQRT(B(*,3)); (5) PUT SKIP(2) LIST(A(*,3)); DCL D FIXED ; D = LBOUND(A,1); (6) PUT SKIP(2) LIST(D); (7) PUT SKIP LIST(HBOUND(A,2)); D = PROD(B); (8) PUT SKIP LIST(D); D = SUM(B);

9. FUNCOES INTERNAS

Page 84

(9) PUT SKIP LIST(D); END EX3C9;

Nesse exemplo ter-se-ao os seguintes resultados:

B = 1.0 2.0 3.0 C = 1.0 2.0 1.0 4.0 5.0 6.0 2.0 1.0 2.0

(1) 1.0 2.0 3.0 (2) 2.0 5.0

A = B + C = 2.0 4.0 4.0 6.0 6.0 8.0

(3) 2.0 4.0 4.0 (4) 6.0 6.0 8.0 _ ____ ____ _ _ _ A(*,3) = SQRT(B(*,3)) = │ V 3.0 V 6.0 │= │ 1.7 2.4│ │_ _│ │_ _│ (5) 1.7 2.4 D=LBOUND(a,1)=1 (6) 1 (7) 3 D=PROD(b)= 1.0 X 2.0 X 3.0 X 4.0 X 5.0 X 6.0 = 720.0 (8) 720 D=SUM(b)= 1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 = 21.0 (9) 21

4) Sejam A, B, C e d arrays de mesma dimensao e: _ _ _ _ │ 10 20 30 │ │ -1 10 2 │ B= │ │ C= │ │ │_40 50 60_│ │_ -40 -5 -10_│ _ _ │30 60 90 │ D= │ │ │_0 60 30_│

Determinar A=B/ABS(C)-10*SIND(D)

Page 66: Manual de PL1 - Completo

_ _ │ 1 10 2 │ Solucao: ABS(C) = │ │ │_40 5 10_│

9. FUNCOES INTERNAS

Page 85

_ _ │ 10 2 15│ B/ABS(C) = │ │ │_ 1 10 6_│ _ ___ _ │ 1/2 V3/2 1 │ SIND(D) = │ ___ │ │_ 0 V3/2 1/2_│

_ __ _ │ 5 5 V 3 10 │ 10 * SIND(D) = │ __ │ │_ 0 5 V 3 5_│

_ __ _ │ 5 2-5 V 3 5 │ A= │ __ │ │_ 1 10-5 V 3 1_│

9. FUNCOES INTERNAS

Page 86

10. COMANDO "DATA" DE ENTRADA E SAIDA _____________________________________

10.1. INTRODUCAO ________________

E' um outro comando usado em operacoes de entrada e saida, ou seja, leitura de dados e impressao de dados. Seu uso e bem semelhante ao co- mando LIST visto anteriormente.

Sua forma geral e' a seguinte:

INPUT - GET DATA(lista de variaveis);

OUTPUT - PUT DATA(lista de variaveis);

Tambem e' permitido o uso dos atributos COPY, SKIP, LINE e PAGE conforme foi visto no comando LIST.

Page 67: Manual de PL1 - Completo

10.2. GET DATA ______________

No comando DATA para entrada de dados, os valores vem no formato de um comando de atribuicao, separados por uma virgula ou pelo menos um espaco em branco e terminados por um sinal de ponto-e-virgula (esse sina e,a combinacao de perfuracoes 11,8 e 6 e nao o conjunto de perfuracoes 0 ,8,3 e 12,8,3, representando o virgula-ponto do conjunto de 48 caracteres).

Para cada ; perfurado, em cartao, o comando GET DATA reconhece um con- junto de variaveis a ser lido. Dai o aparecimento do comando, tambem sob a forma GET DATA;isto e', sem lista de variaveis.

Por exemplo, tendo-se num primeiro cartao as perfuracoes A=1, B=2, C =3, D=4; C=2; A=2 e num segundo cartao B=3, C=5; D=3, A=1; valores esses perfurados em quaisquer posicoes, para que esses valores sejam lidos, devem-se ter 4 comandos GET DATA, pois existem 4 sinais de ponto-e- virgula, que sao os delimitadores das listas de variaveis.

Assim ,o primeiro GET DATA lera' as variaveis A, B, C e D; o segundo, a variavel C; o terceiro, as variaveis A, B e C; e o quarto, as variaveis D e A.

Essas variaveis, se constarem da lista do comando GET DATA, poderao estar em qualquer ordem; por exemplo, o primeiro GET DATA referido podera ser: GET DATA(A,B,C,D) ou GET DATA(B,C,D,A) ou GET DATA(D,A,C,B) etc... podendo ainda nao conter lista alguma,GET DATA;independentemente da ordem em que essas variaveis estejam perfuradas nos cartoes.

Entao, no fluxo normal da sequencia dos comandos no programa, as variaveis lidas assumiriam os seguintes valores:

1. GET DATA - A=1 B=2 C=3 D=4

10. COMANDO "DATA" DE ENTRADA E SAIDA

Page 87

2. GET DATA - A=1 B=2 C=2 D=4

3. GET DATA - A=2 B=3 C=5 D=4

4. GET DATA - A=1 B=3 C=5 D=3

Se se usar, no comando GET DATA, a lista de variaveis, ela devera' conter todos as variaveis perfuradas em cartao, pelo menos, ou seja, ela podera' conter mais variaveis que a perfuradas, mas nunca menos, caso em que dara' uma mensagem de erro de execucao. Por exemplo, o comando GET DATA(X,Y,Z,W,P,R); podera' ser uma ou varias ou todas as variaveis dessa lista, porem nao lera' a variavel D, pois esta nao consta da lista. Assim, se no cartao estiverem perfuradas as variaveis W=4, R=1 e X=3, o comando, ao encontrar o ponto-e-virgula apos essa terceira variavel, pa- rara', considerando a leitura correta. Se, no entanto, no cartao aparecer a lista: W=4, R=1, C=5, X=3; sera emitida uma mensagem de erro sobre nome nao reconhecido pela lista de variaveis no comando GET DATA, acionando a condicao NAME, e,como ela e' uma condicao normalmente ligada, a condicao -padrao do sistema ERROR interrompera' o processamento apos a emissao da mensagem.

Deve-se, ao serem perfurados os valores das variaveis a serem lidas pelo comando GET DATA, respeitar as regras dos atributos, menos as excecoes de conversao.

Se a variavel a ser lida for uma variavel array, ela devera' vir perfurada com seus subscritos: C(1)=3, C(2)=4, C(5)=0, C(4)=1, C(3)=1; e, conforme se pode verificar, em qualquer ordem. E, na lista de variaveis, se existir, ela podera' aparecer com seus subscritos ou, se forem todos os seus elementos, apenas com o nome do array.

Page 68: Manual de PL1 - Completo

Assim, se se quiserem ler todos os 5 elementos do array denominado C, poder-se-a' escrever GET DATA(C); ou GET DATA(C(1),C(4),C(2),C(5),C(3)); ou em qualquer ordem. Se se quiserem ler apenas o 3. elemento e o 2. elemento, sera' preciso escrever GET DATA(C(3),C(2)); ou (C(2),C(3)).

Mais um exemplo: o caso de leitura de variaveis string de caracteres sera' mostrado a seguir.

Suponha-se que se queira ler um string de caracteres formado pelo string 'EXEMPLO NO. 1', para uma variavel de nome TITULO. Apos ter sido decla- rada convenientemente, no programa, a variavel TITULO como sendo CHAR(13), por exemplo, no cartao devera' constar o formato envolvendo o nome da variavel e o valor do string, como se fosse um comando de atribuicao: TITULO = 'EXEMPLO NO. 1';

10. COMANDO "DATA" DE ENTRADA E SAIDA

Page 88

10.3. PUT DATA ______________

O comando PUT DATA so' permite, na lista de variaveis, nomes de variaveis.

Ele faz com que as variaveis especificadas em sua lista sejam impressas no formato de comandos de atribuicao, respeitando a mesma tabulacao que dirige o comando PUT LIST.

Podera', tambem, apresentar-se sem lista de variaveis, e, nesse caso, to- das as variaveis conhecidas no momento do comando serao impressas.

Seja o seguinte trecho de programa:

J=0; DO I = 1 TO 3; PUT DATA (I); GET DATA(K,L); J = J + K - L; END; PUT DATA(J,K,L);

se os dados perfurados em cartao forem: K=1, L=1; L=2; K=3; quais os va- lores impressos , ao ser executado o trecho de programa apresentado?

Solucao:

I=1, I=2, I=3, J=0, K=3, L=2

10.4. APLICACOES ________________

1) Programa para calcular o volume de uma esfera, sendo conhecido o valor do raio (lido em cartao).

EX1C10: PROC OPTIONS(MAIN); GET DATA(RAIO); VOLUME = (4.0 * 3.14 * RAIO**3)/3.0; PUT DATA(VOLUME); END EX1C10;

___________ _________________________ / │ │ │

Page 69: Manual de PL1 - Completo

Sendo │ RAIO = 5; │ a saida sera' │ VOLUME = 5.23333E+02; │ │____________│ │ │ │ │ +---->col.1 │ │_________________________│

10. COMANDO "DATA" DE ENTRADA E SAIDA

Page 89

11. ESPECIFICACAO "PICTURE" ___________________________

11.1. INTRODUCAO ________________

A especificacao PICTURE e' usada, principalmente, em edicao de valores numericos. Com ela conseguem-se impressoes de valores numericos editados com ponto, virgula, barra, espacos em branco, sinais etc., recursos esses que nao era possivel usar, pela propria natureza das constantes numericas vistas ate' agora(FIXED, FLOAT, BIN etc.).

Essa especificacao e' reconhecida pelo uso do atributo PICTURE, que se abrevia por PIC, no comando DECLARE, ou pelo uso do codigo de formato, P, usado no comando EDIT de entrada e saida, que sera' visto no Cap. 13.

A especificacao PICTURE usada como atributo substitui todos os atributos vistos para qualquer tipo de variaveis. Ela faz com que os valores sejam tratados como string de caracteres, ou seja, cada digito e' considerado como se fosse um caracter, dai' o seu uso implicar um processamento mais demorado do que os outros; por outro lado, pode-se lancar mao de todos os recursos que existem sobre manipulacao de strings de caracteres, alem da ja' mencionada vantagem em edicao de valores numericos.

Sua forma de declaracao e': "DCL nome PIC'especificacao';" onde, por especificacao, se entende um conjunto de caracteres que vao definir a PICTURE e que se verao a seguir.

Antes,porem, deve-se tormar conhecimento dos dois tipos de PIC que existem: a PICTURE de caracteres e a PICTURE numerica.

11.2. PICTURE DE CARACTERES ___________________________

Seu uso se assemelha bastante ao do atributo CHAR visto anteriormente PIC de caracter e CHAR tem praticamente a mesma finalidade.

Os caracteres de especificacao usados sao X,A e 9, sendo que o 9 nao po- dera' ser usado sozinho, caso em que transformara' a PICTURE de caracte- res em PICTURE numerica, conforme se vera' mais adiante.

Eis os significados deles:

X Especifica que a posicao correspondente pode conter qualquer carater(alfabetico, numerico ou especial).

A Especifica que a posicao correspondente pode conter qualquer carater alfabetico ou branco.

9 Especifica que a posicao correspondente pode conter qualquer carater numerico ou branco.

11. ESPECIFICACAO "PICTURE"

Page 90

Page 70: Manual de PL1 - Completo

Por exemplo, o string de caracteres 'Xb=Y/12,3', onde b representa o caracter em branco (espaco em branco), pode ser especificado por meio de uma PICTURE de caracteres de 96 modos, ou seja:

2 X 3 X 1 X 2 X 1 X 2 X 2 X 1 X 2 = 96 X b = Y / 1 2 , 3

pois:

X Y pode-se usar X ou A b pode-se usar X ou A ou 9 = / , pode-se usar X 1 2 3 pode-se usar X ou 9

Assim, num comando DECLARE pode-se ter:

DCL ABC PIC'AAXAX99X9'; (um dos 96 casos possiveis) DCL ABC PIC'XXXXXXXXX'; (esse exemplo e' exatamente o mesmo que o atributo CHAR)

Pode-se usar, tambem, o atributo INITIAL para os casos de PIC. Por exemplo: DCL B PIC'XXXXXXXXXXXX' INIT('COPOS D''AGUA');

E' permitido usar dentro de uma PIC o fator de repeticao. No exemplo apresentado poder-se-ia ter escrito PIC'(12)X'

11.3. PICTURE NUMERICA ______________________

Esta picture se refere apenas aos caracteres numericos e aos simbolos de edicao, como a virgula, o ponto, o sinal de cifrao, o sinal de menos etc.

Os caracteres X e A nao podem ser usados como caracteres de especificacao. Os simbolos usados sao varios. Eis alguns:

9 V Y S + - $ , . / B Z *

Veja-se, pois, cada um desses caracteres de especificacao.

Especifica que a posicao correspondente somente podera' conter um 9 carater numerico - 1,2,3,4,5,6,7,8,9,0. DADO PICTURE VALOR 10234 '99999' '10234' 10234 '999' '234' 10234 '(8)9' '00010234'

11. ESPECIFICACAO "PICTURE"

Page 91

Especifica que nessa posicao existe um indicador de ponto decimal. V So' pode aparecer uma vez na PICTURE. Se ausente, e' assumido 'a direita do numero. O valor do caracter "string" nao contem o ponto, apenas uma indicacao. O simbolo V divide o string em dois subcam- pos: a parte inteira e a parte fracionaria do numero. DADO PICTURE VALOR 10234 '99999V' '10234' 10234 'V99999' '00000' 10.234 '99V999' '10234' 10.234 '9V9' '02' 10.234 '9V9999' '02340'

Especifica que a posicao correspondente contem um digito condicio-

Page 71: Manual de PL1 - Completo

Y nal, isto e', se na posicao aparecer 0, este sera' trocado por branco. DADO PICTURE VALOR 10101 'YYYYY' '1 1 1' 10001 'YYYYY' '1 1' 120021 '999Y99' '120 21'

Especifica que a posicao correspondente contem um sinal de + se o S campo for positivo ou zero, e um sinal de - se o campo for ne- gativo. O sinal pode ser ajustado ao numero, com a repeticao do caracter, substituindo posicoes nao significativas por brancos. Se for estatico (nao se repete), pode vir 'a esquerda ou a direita do numero. Se houver supressao de zeros, so' a esquerda. O caracter mais 'a esquerda pode ser substituido pelo sinal ou branco, nunca por um digito.

DADO PICTURE VALOR -3456 'S9999' '-3456' 75 'S9999' '+0075' 75 'SS999' ' +075' 75 'SSSS9' ' +75' -21 '999S' '021-'

Especifica que a posicao correspondente contem um sinal + se o + campo for positivo e branco se for negativo. As regras para ajuste do sinal com supressao de zeros sao as mesmas validas para o caracter 'S'.

DADO PICTURE VALOR 53.1 '+9999V99' '+005310' 53.1 '++++9V99' ' +5310' -22 '+999' ' 022' -22 '999+' '022 '

Especifica que a posicao correspondente contem um sinal - se o - campo for negativo e branco se for positivo. As regras para ajuste do sinal com supressao de zeros sao as mesmas validas para os ca- racteres 'S' e '+'.

11. ESPECIFICACAO "PICTURE"

Page 92

DADO PICTURE VALOR -10.1 '-9999V9' '-00101' -10.1 '----9V9' ' -101' 100 '--99' ' 100' -23 '999-' '023-'

Especifica que a posicao correspondente contem o sinal $. As regras $ para supressao de zeros sao as mesmas validas para os caracteres 'S', '+' e '-'.

DADO PICTURE VALOR 109 '$9999' '$0109' 109 '$$$99' ' $109'

Especificam que a posicao correspondente contem um desses simbolos. ,./B Os caracteres ,./ sao de insercao condicional, isto e', dentro de uma sequencia de caracteres de supressao de zeros, eles tambem podem ser substituidos. O B e' um caracter de insercao incondicio- nal.

Page 72: Manual de PL1 - Completo

DADO PICTURE VALOR 12795 '99,999' '12,795' 12795 '999.99' '127.95' 110976 '99/99/99' '11/09/76' 110976 '99B99B99' '11 09 76'

Especificam que a posicao correspondente contem um branco ou * se Z * for um 0 (ZERO) nao significativo.

DADO PICTURE VALOR 5349 'ZZ99' '5349' 0305 'ZZZ9' ' 305' 0001 'Z999' ' 001' 01.51 'Z9V99' ' 151' 0345 '***9' '*345' 0010 '**99' '**10' 0100 '***9' '*100' 0100 'ZZZZ' ' 100'

Esses simbolos nao podem aparecer juntos (misturados) e nem 'a direita do simbolo 9.

So' podem ser usados junto com os caracteres "S+-$" se estes forem estaticos.

Quando usados juntamente com V, em ambos os subcampos deve haver o mesmo simbolo. Por exemplo:

DADO PICTURE VALOR 1794 '**V*' '940' 0017 '**V**' '1700'

11. ESPECIFICACAO "PICTURE"

Page 93

0000 '**V**' '****' -33 'SZZZ9' '- 33'

Casos errados:

? 'ZZZVZ9' ? ? 'ZZ9ZZ' ? ? '**ZZZ' ?

11.4. CONVERSOES ________________

Conforme o leitor pode verificar, existem duas maneiras de armazenar dados aritmeticos em PL/1 - a forma aritmetica codificada e a forma de carater numerico.

A forma aritmetica codificada e' quando os dados tem seus atributos de base, escala e precisao explicitamente especificados ou assumidos auto- maticamente pelo compilador; a forma de carater numerico e' quando o dados sao armazenados como um 'string' de caracteres; este e' conseguido com o uso da especificacao PICTURE.

Antes que o computador possa efetuar qualquer operacao aritmetica, os dados devem estar na forma aritmetica codificada. Assim, se estiverem na forma de carater numerico (PICTURE), eles serao automaticamente conver- tidos para a forma aritmetica codificada, demandando para isso um certo tempo, dai volto a me referir a esse detalhe, dizer-se que programas com um grande numero de variaveis declaradas com atributo PICTURE sao responsaveis por processamentos mais morosos.

Page 73: Manual de PL1 - Completo

A forma aritmetica codificada mantem os dados na modalidade de armazenamento denominada COMPACTADA enquanto que a forma de carater numerico mantem os dados na modalidade ZONADA. Cada digito de um dado na forma de carater numerico ocupa um byte de memoria; assim, uma variavel declarada PIC'999999' podera' armazenar valores desde 0 a 999999, em seis bytes de memoria, enquanto que, se ela for declarada como FLOAT(6), alem de ocupar somente 4 bytes de memoria, podera' armazenar valores na ordem de 10 elevado a -78 a 10 elevado a 75.

Eis alguns casos de conversoes com variaveis de atributo PIC:

1. DCL A CHAR(10), B PIC'9999.V99'; o comando A=B + 1; implicara' a conversao da variavel B (forma de carater numerico) para a forma de aritmetica codificada e em seguida, por forca do comando de atribuicao, resultado da expressao e' transformado para o atributo CHAR.

2. Em comparacoes, a prioridade de conversao nos tipos e':

STRING DE BITS ---> STRING DE CARACTERES ---> ARITMETICOS

11. ESPECIFICACAO "PICTURE"

Page 94

11.5. APLICACOES ________________

1. Programa para efetuar os calculos referentes a um sistema de um cartao de credito, fazendo uma previsao para uma determinada compra efetuada e para uma quantia minima constante como mensalidade a pagar, sobre o nu- mero de prestacoes, total de juros pagos, mensalidades minimas a pagar e total das mesmas.

Na saida impressa dessa previsao, deve constar o numero e o valor das prestacoes a pagar, o saldo anterior mensal, o saldo atual mensal e os juros cobrados em cada parcela. No final do relatorio devera' constar o total de juros e o de mensalidades pagas.

Nos calculos, os juros sao de 3% sobre o saldo devedor e as mensalidades, quando superiores ao valor da prestacao minima a pagar, sao de 10% sobre o saldo atual e igual 'a quantia minima constante quando forem inferiores 'a referida quantia minima. Entende-se como saldo devedor o saldo atual amortizado da mensalidade minima paga.

Segue-se um exemplo de relatorio de saida para o programa proposto, para o caso de uma compra de Cr$ 2.000,00 e uma amortizacao minima de Cr$ 100,00.

********************************************************************** Num. de prestacoes Saldo Anterior Juros Saldo Atual Mensalidade

********************************************************************** 1 00,00 0,00 2.000,00 200,00 2 1.800,00 54,00 1.854,00 185,40 3 1.668,60 50,05 1.718,65 171,86 ..... ...... ... .... 10 981,55 29,94 1.010,99 101,09 11 909,90 27,29 937,19 100,00 12 837,19 25,11 862,30 100,00 13 762,30 22,86 785,16 100,00 ..... ...... ... .... 20 171,25 5,13 176,38 100,00 21 76,38 2,29 78,67 78,67

********************************************************************** Totais 534,52 2.534,52

Page 74: Manual de PL1 - Completo

************************************************************************

Veja-se, pois, o programa:

EX1C11: PROC OPTIONS(MAIN); DCL (SALDO_ANTERIOR,SALDO_ATUAL,MENSALIDADE_MINIMA , VALOR_COMPRA,JUROS,TOTJUR,MENSALIDADE) PIC'ZZ99V,99' ,ASTERISCOS CHAR(64) INIT((64)'*') ,NUMERO_PRESTACAO FIXED(5)

11. ESPECIFICACAO "PICTURE"

Page 95

; ON ENDFILE(SYSIN) GOTO FIM; DO WHILE('1'B); GET LIST(VALOR_COMPRA,MENSALIDADE_MINIMA); PUT PAGE LIST(ASTERISCOS); PUT SKIP LIST('NUM.PRESTACOES'CAT'SALDO ANTERIOR' CAT'JUROS'CAT'SALDO ATUAL'CAT'MENSALIDADE'); PUT SKIP LIST(ASTERISCOS); PUT SKIP; SALDO_ANTERIOR=0; JUROS=0; NUMERO_PRESTACAO=0; TOTJUR=0; SALDO_ATUAL=VALOR_COMPRA; DO WHILE(SALDO_ATUAL GT MENSALIDADE_MINIMA); MENSALIDADE=SALDO_ATUAL/10; IF MENSALIDADE LE MENSALIDADE_MINIMA THEN MENSALIDADE=MENSALIDADE_MINIMA; NUMERO_PRESTACAO=NUMERO_PRESTACAO + 1; PUT SKIP LIST(NUMERO_PRESTACAO CAT (8)' ' CAT SALDO_ANTERIOR CAT(5)' ' CAT JUROS CAT (3)' ' CAT SALDO_ATUAL CAT ' ' CAT MENSALIDADE); SALDO_ANTERIOR= SALDO_ATUAL = MENSALIDADE; JUROS=SALDO_ANTERIOR * 0,03; SALDO_ATUAL=SALDO_ANTERIOR + JUROS; TOTJUR=TOTJUR + JUROS; END; MENSALIDADE= SALDO_ATUAL; NUMERO_PRESTACAO=NUMERO_PRESTACAO + 1; PUT SKIP LIST(NUMERO_PRESTACAO CAT(8)' ' CAT SALDO_ANTERIOR CAT (5)' ' CAT JUROS CAT(3)' ' CAT SALDO_ATUAL CAT' ' CAT MENSALIDADE); PUT SKIP(1) LIST(ASTERISCOS); VALOR_COMPRA = VALOR_COMPRA + TOTJUR; PUT SKIP LIST(ASTERISCOS); END; FIM: PUT SKIP(2) LIST('FIM DO TRABALHO'); END EX1C11;

O leitor devera analisar cuidadosamente essa programacao para observar os detalhes da mesma no que se refere ao uso do atributo PIC numerico, sendo usado como CHAR nas expressoes de concatenacao nas listas de variaveis do comando PUT LIST e as mascaras de edicao no DCL.

11. ESPECIFICACAO "PICTURE"

Page 96

Page 75: Manual de PL1 - Completo

12. ESTRUTURAS ______________

12.1. INTRODUCAO ________________

E' uma outra maneira de armazenar dados na memoria do computador, alem das que ja' conhecemos: as variaveis simples e os arrays (variaveis com subscritos).

Como ja' foi visto, os arrays eram colecoes de dados contendo, todos, os mesmos atributos. Uma estrutura e' tambem uma colecao de dados, porem contendo os mais variados atributos.

Uma outra diferenca entre um array e uma estrutura e' que um array e' simplesmente um agregado, uma lista, uma colecao de dados mantendo uma determinada ordenacao em seus elementos, e uma ESTRUTURA e' uma colecao de dados hierarquica, ou seja, possui niveis de hierarquia, podendo um ou mais itens da estrutura ser arrays.

Para melhor se entender uma estrutura, eis um exemplo:

______ │ TV │ │______│ │ _____________│__________________________________ │ │ │ │ ______ ____________ ______________ __________ │ NOME │ │ RESIDENCIA │ │ ESTADO CIVIL │ │ CANAL-TV │ │______│ │____________│ │______________│ │__________│ │ │ │ │ _____________ ____________ │ │ │ │ ________ __________ ___________ ________ │ ULTIMO │ │ PRIMEIRO │ │ RUA E NUM │ │ BAIRRO │ │________│ │__________│ │___________│ │________│

Essa estrutura apresenta tres niveis de hierarquia: o nivel 1 compreendendo o item TV; o nivel 2 compreendendo os itens NOME, RESIDEN- CIA, ESTADO CIVIL e CANAL-TV; e o nivel 3 compreendendo os itens ULTIMO, PRIMEIRO, RUA E NUM e BAIRRO.

Uma estrutura desse tipo seria empregada, por exemplo, num levantamento estatistico sobre o canal de TV mais sintonizado num determinado horario, em uma determinada cidade.

Repare-se que os itens que serao preenchidos: ULTIMO, PRIMEIRO, RUA E NUM, BAIRRO, ESTADO CIVIL e CANAL-TV constituem os itens elementares da estrutura e os demais constituem os niveis da estrutura, sendo que o item TV e' o que constitui o nivel maior da estrutura.

12. ESTRUTURAS

Page 97

Ao nivel maior da estrutura denominamos ESTRUTURA MAIOR e aos demais niveis denominamos ESTRUTURAS MENORES ou subestruturas.

O PL/1 permite declarar uma variavel que represente uma estrutura.

Para o exemplo dado, ter-se-ia:

DCL 1 TV, 2 NOME, 3 ULTIMO CHAR(10), 3 PRIMEIRO CHAR(20), 2 RESIDENCIA, 3 RUA_E_NUM CHAR(30), 3 BAIRRO CHAR(15),

Page 76: Manual de PL1 - Completo

2 ESTADO_CIVIL CHAR(8), 2 CANAL_TV CHAR(10);

onde o leitor podera' notar a existencia dos numeros 1, 2 e 3 indicando os niveis da estrutura.

Com relacao a esses numeros, o importante e' saber que o primeiro nivel da estrutura deve ser sempre o numero 1 e que os demais niveis devem ser numeros em ordem crescente, mas nao necessariamente consecutivos.

O nome da estrutura e', portanto, o identificador usado no nivel maior (no exemplo, o nome TV), e os elementos dessa VARIAVEL ESTRUTURA sao os itens elementares (no exemplo, os nomes ULTIMO, PRIMEIRO, RUA_E_NUM,BAIRRO, EST_CIVIL e CANAL_TV) e sao exatamente os itens que terao seus atributos declarados. Os demais niveis apenas indicarao a hierarquia da estrutura (no exemplo, os nomes NOME e RESIDENCIA). Todos esses nomes sao identificadores e, por conseguinte, devem satisfazer as regras existentes na linguagem.

Assim, ao se referir a um nome de um nivel de uma estrutura, esta-se referindo a todos os itens elementares desse nivel. Por exemplo, uma re- ferencia ao nome RESIDENCIA implica uma referencia 'as variaveis RUA_E_NUM e BAIRRO, nessa ordem; uma referencia ao nome NOME implica uma referencia 'as variaveis ULTIMO e PRIMEIRO, nessa ordem; e uma referencia ao nome TV implica uma referencia 'as variaveis ULTIMO, PRIMEIRO, RUA_E_NUM , BAIRRO, ESTADO_CIVIL e CANAL_TV, nessa ordem.

Nao obstante, e' possivel referir-se a um item elementar qualquer da estrutura simplesmente, como se ele nao pertencesse 'a estrutura.

Quando se diz que se pode referir a um nome, isso significa que se pode usar esse nome em comandos da linguagem, como, por exemplo:

GET LIST(TV); GET LIST(NOME,RESIDENCIA,ESTADO_CIVIL,CANAL_TV); GET LIST(ULTIMO,PRIMEIRO,RUA_E_NUM,BAIRRO,ESTADO_CIVIL, CANAL_TV); GET LIST(NOME,RUA_E_NUM,BAIRRO,ESTADO_CIVIL,CANAL_TV); GET LIST(ULTIMO,PRIMEIRO,RESIDENCIA,ESTADO_CIVIL,CANAL_TV);

tem, exatamente, o mesmo significado, ou seja, qualquer um deles lera' as variaveis ULTIMO, PRIMEIRO, RUA_E_NUM, BAIRRO, ESTADO_CIVIL e CANAL_TV, nessa ordem.

12. ESTRUTURAS

Page 98

Se se quisesse, numa referencia qualquer, mudar essa ordem, bastaria tro- car a ordem da referencia; por exemplo, suponha-se que se deseje ler essa estrutura trocando a ordem do nome com a da residencia. Entao, poder-se-ia escrever qualquer um dos comandos mencionados, com excessao do primeiro, trocando, na lista de variaveis, a ordem das variaveis NOME e RESIDENCIA.

Eis uma apresentacao mais explicita para a declaracao de uma VARIAVEL ESTRUTURA:

DECLARE 1 TV, 2 NOME, 3 ULTIMO CHAR(10), 3 PRIMEIRO CHAR(20), 2 RESIDENCIA, 3 RUA_E_NUM CHAR(30), 3 BAIRRO CHAR(15), 2 ESTADO_CIVIL CHAR(8), 2 CANAL_TV CHAR(10) ;

Page 77: Manual de PL1 - Completo

12.2. REFERENCIA QUALIFICADA ____________________________

A linguagem PL/1 permite que se use um nome de variavel pertencente a uma estrutura como nome de uma outra variavel (variavel simples, variavel pertencente a uma outra estrutura ou subestrutura, array etc.) no mesmo programa.

Tal recurso e' permitido devido ao uso da referencia qualificada, que e' a referencia a uma variavel pela sua posicao hierarquica na estrutura.

Assim, a variavel BAIRRO, por exemplo, podera' ser referenciada por uma das tres maneiras a seguir:

1) BAIRRO - Se nao existir outra variavel com mesmo nome no programa; 2) RESIDENCIA.BAIRRO - Se existir uma outra variavel no programa denominada BAIRRO. 3) TV.RESIDENCIA.BAIRRO - Se existir uma outra variavel no programa denominada BAIRRO e pertencente a uma outra estrutura ou subestrutura denominada RESIDENCIA.

Pode-se, entao, referir a uma variavel de uma estrutura por meio de uma referencia qualificada, total, ou parcialmente ou mesmo simplesmente pelo seu nome, se nao existir uma ou outra variavel no programa com esse mesmo nome; caso contrario, dever-se-a' usar uma referencia qualificada qualquer que identifique a variavel da estrura.

Sempre que num programa existirem duas ou mais variaveis com mesmo nome, a referencia somente ao nome da variavel (sem referencia qualificada) in-

12. ESTRUTURAS

Page 99

dicara' uma referencia 'a variavel simples. Se nao existir a variavel simples, isto e', se as variaveis de mesmos nomes pertencerem a estruturas ou subestruturas, sera' emitida uma mensagem de erro sobre duplicidade de nomes de variaveis e o programa sera' interrompido.

Apenas como lembranca, nos tres exemplos dados aparecem os tres tipos de referencias, ou seja:

1) referencia simples; 2) referencia parcialmente qualificada; 3) referencia totalmente qualificada.

Segue-se um exemplo pratico do uso de estruturas.

O programa escrito a seguir traduz o seguinte problema: Um sistema de contabilidade para uma instalacao de computadores e' organizado como tendo uma estrutura de nome JOB, cujos itens elementares sao numero de contabilidade , saldo disponivel do analista, custo de corrida de pro- grama e tempos de compilacao e de execucao do programa.

Para cada servico executado, o sistema tera' o numero de contabilidade do analista, o saldo atual seu, o tempo que o servico (programa) levou na compilacao, o tempo que levou executando e o custo unitario do programa (custo em funcao da linguagem usada).

O programa calculara' o custo do servico, abatendo esse valor da quantia correspondente ao saldo do analista, e imprimira' os dados correspondentes ao servico.

EX1C12: PROC OPTIONS(MAIN); DCL XAV BIT(1) INIT('1'B), 1 JOB,

Page 78: Manual de PL1 - Completo

2 NUM_CONTAB FIXED, 2 SALDO FIXED(6,2), 2 TEMPO, 3 COMPILAR FLOAT(3), 3 EXECUTAR FLOAT(3), 2 CUSTO FIXED(5,2); ON ENDFILE(SYSIN) XAV = '0'B; GET LIST(JOB); DO WHILE(XAV); SALDO = SALDO - (CUSTO*EXECUTAR + .5*CUSTO*COMPILAR); PUT SKIP DATA(JOB); GET LIST(JOB); END; END EX1C12;

Por ter sido usado o comando LIST, para entrada, os dados deverao vir perfurados em cartao, separados por virgula ou pelo menos um branco e deverao estar na mesma ordem em que eles foram definidos na estrutura, o seja, o primeiro valor para a variavel NUM_CONTAB, o segundo para a

12. ESTRUTURAS

Page 100

variavel SALDO, o terceiro para a variavel COMPILAR, o quarto valor para a variavel EXECUTAR e o quinto para a variavel CUSTO.

O comando DATA, usado para saida das informacoes, imprimira' os valores das variaveis da estrutura JOB, na forma de referencia qualificada com- pletamente e respeitando a tabulacao automatica do PL/1.

12.3. ARRAY DE ESTRUTURAS _________________________

Conforme o proprio nome indica, significa uma colecao de estruturas, isto e', o nome da estrutura tera' um indice e uma estrutura qualquer da colecao sera' referenciada pela variacao do subscrito do array (estrutura maior).

______________ _____________│ CLASSIFICACAO│______________ . │______________│ . . │ . ______ . __________________│__________________ . _______ │ NOME │. │ CURSO(1),CURSO(2),CURSO(3),CURSO(4) │ .│ MEDIA │ │______│ │_____________________________________│ │_______│

Em programacao poder-se-a' escrever:

DCL 1 CLASSIFICACAO, 2 NOME CHAR(30), 2 CURSO(4) PIC'99V.9', 2 MEDIA FLOAT(3);

Tem-se, pois, uma estrutura com 2 niveis e 6 itens elementares: NOME, as quatro notas que compoem o array CURSO e MEDIA.

Assim, para um determinado aluno, ter-se-ia essa estrutura definida. Porem, se se quisesse montar essa estrutura para uma colecao de alunos, ou seja, criar uma colecao de estruturas, dever-se-ia colocar uma dimensao no nivel 1 da estrutura ora apresentada, ficando:

DCL 1 CLASSIFICACAO (30), 2 NOME CHAR(30), 2 CURSO(4) PIC'99V.9', 2 MEDIA FLOAT(3);

O array de estrutura formado preve uma colecao de ate' 30 alunos (30

Page 79: Manual de PL1 - Completo

estruturas).

Tudo o que foi visto ate' agora sobre arrays e sobre estruturas e' valido para o array de estruturas.

12. ESTRUTURAS

Page 101

O comando NOTA = CLASSIFICACAO(5).CURSO(3); implica a atribuicao, 'a variavel denominada NOTA, do valor da nota do terceiro curso do quinto aluno da colecao.

Quanto 'a referencia qualificada em arrays de estruturas, vale a pena de- morar um pouco mais, para que haja melhor entendimento sobre o assunto.

12. ESTRUTURAS

Page 102

DCL 1 A(2), 2 B(3), 3 E(2,3), 3 F, 2 C(2), 3 E(2), 3 G;

Esta estrutura tem a seguinte disposicao de armazenamento:

DIAGRAMA INDICE DOS ELEMENTOS __________________________________ │ A(1) │ B(1) │ E(1,1) │ 1,1,1,1 │ │ │ E(1,2) │ 1,1,1,2 │ │ │ E(1,3) │ 1,1,1,3 │ │ │ E(2,1) │ 1,1,2,1 │ │ │ E(2,2) │ 1,1,2,2 │ │ │ E(2,3) │ 1,1,2,3 │ │ │_______________│ │ │ │ F │ 1,1 │ │________│_______________│ │ │ B(2) │ E(1,1) │ 1,2,1,1 │ │ │ E(1,2) │ 1,2,1,2 │ │ │ E(1,3) │ 1,2,1,3 │ │ │ E(2,1) │ 1,2,2,1 │ │ │ E(2,2) │ 1,2,2,2 │ │ │ E(2,3) │ 1,2,2,3 │ │ │_______________│ │ │ │ F │ 1,2 │ │________│_______________│ │ │ B(3) │ E(1,1) │ 1,3,1,1 │ │ │ E(1,2) │ 1,3,1,2

Page 80: Manual de PL1 - Completo

│ │ │ E(1,3) │ 1,3,1,3 │ │ │ E(2,1) │ 1,3,2,1 │ │ │ E(2,2) │ 1,3,2,2 │ │ │ E(2,3) │ 1,3,2,3 │ │ │_______________│ │ │ │ F │ 1,3 │ │________│_______________│ │ │ C(1) │ E(1) │ 1,1,1 │ │ │ E(2) │ 1,1,2 │ │ │_______________│ │ │ │ G │ 1,1 │ │________│_______________│ │ │ C(2) │ E(1) │ 1,2,1 │ │ │ E(2) │ 1,2,2 │ │ │_______________│ │ │ │ G │ 1,2 │_________│________│_______________│

Continuando o diagrama e os indices dos elementos, ter-se-ia uma outra parte identica a esta, para o segundo elemento (estrutura) da colecao (array de estruturas).

12. ESTRUTURAS

Page 103

Pode-se referir a um elemento de um array de estruturas de diversas maneiras, por exemplo:

(a) A(1).B(2).E(2,3) (b) A(1,2).E(2,3) A(1,2).B.E(2,3) A(1,2,2,3).E A(1,2,2,3).B.E A.E(1,2,2,3) A.B(1,2).E(2,3) (c) B(1,2).E(2,3) A.B.E(1,2,2,3) B(1,2,2,3).E A.B(1,2,2,3).E B.E(1,2,2,3) (d) E(1,2,2,3)

Os casos constantes do item (a) constituem exemplos de referencias qualificadas totalmente e os casos dos itens (b), (c) e (d) constituem exemplos de referencias qualificadas parcialmente. Todas elas significam uma referencia ao elemento (2,3) do array E, que, por sua vez, e' o se- gundo elemento do array B que, por sua vez, e' o primeiro elemento do array A.

Assim se se quisesse referir ao elemento G do primeiro elemento de C, do segundo elemento de A, poder-se-ia escrever:

A(2).C(1).G A(2,1).C.G A.C(2,1).G A.C.G(2,1) A(2).C.G(1) A.C(2).G(1)

todas representando referencias qualificadas totalmente, ou entao usando referencias qualificadas parcialmente, como:

A(2).G(1) C(2,1).G A.G(2,1) C(2).G(1) G(2,1) A(2,1).G C.G(2,1)

Nao ha' referencia qualificada para label variavel.

12.4. EXPRESSAO DE ESTRUTURAS _____________________________

Os nomes de estruturas ou subestruturas podem ser usados em

Page 81: Manual de PL1 - Completo

expressoes.Ja' foi visto que se A,B e C fossem declarados arrays de mesmas dimensoes, o comando A=B+C;implicaria A(1)=B(1)+C(1);....... A(n)=B(n)+C(n);onde n seria a dimensao dos tres arrays.Sendo estruturas, elas devem ter as mesmas organizacoes: mesmos niveis,mesmas dimensoes de arrays etc.

DCL 1 A1,2 A2,2 A3,2 A4; DCL 1 B1,2 B2,2 B3,2 B4;

12. ESTRUTURAS

Page 104

DCL 1 C1,2 C2,2 C3,2 C4;

o comando A1=B1+C1;implicara A2=B2+C2;A3=B3+C3;A4=B4+C4;

Da mesma maneira,se cada uma fosse de dimensao 5,por exemplo, o comando A1(2)=B1(5)-C1(1) ;implicaria os seguintes comandos:

A2(2)=B2(5)-C2(1); A3(2)=B3(5)-C3(1); A4(2)=B4(5)-C4(1);

Numa declaracao do tipo: DCL 1 A,2 B,2 C,2 D,3 F,3 G;as expressoes D**5,A-G e B+D sao exemplos de expressoes de estruturas,enquanto que a expressao C*F/2 nao, pois e' formada apenas por itens elementares(C e F), constituindo-se,assim,numa expressao de elementos.

Seja a estrutura 1 A, 2 B,2 C,3 D,3 E;Na expressao C**2 identificam-se os itens elementares B, D e E como operandos.

Entao,pode-se resumir todo o exposto,a respeito de expressao de estruturas, no seguinte: sendo B e C estruturas, uma funcao de B e C sera' uma expressao de estruturas validas, se tiverem as mesmas estruturas menores e o mesmo numero e mesma posicao dos seus elementos e arrays.

Segue-se uma aplicacao.Seja DCL 1 REGISTRO:

2 S, 3 T(2,2), 3 U, 2 V;

Sendo T=│1 4│ ,U=3 e V=2,calcular:REGISTRO=REGISTRO*T(1,2); │0 1│

Solucao: T(1,1)=T(1,1)*T(1,2)=1*4=4 T(1,2)=T(1,2)*T(1,2)=4*4=16 T(2,1)=T(2,1)*T(1,2)=0*16=0 T(2,2)=T(2,2)*T(1,2)=1*16=16 U = U *T(1,2)=3*16=48 V = V *T(1,2)=2*16=32

12.5. BY NAME _____________

O atributo BY NAME,quando usado complementando uma expressao de estruturas,faz corresponder os itens das estruturas envolvidas,de mesmos nomes e mesmos niveis.

E' uma forma de usar, em expressoes de estruturas, estruturas que nao tenham as mesmas configuracoes, bastando, para isso, que os itens que vao

12. ESTRUTURAS

Page 105

Page 82: Manual de PL1 - Completo

ser relacionados tenham os mesmos nomes e estejam nos mesmos niveis de hierarquia.

Por exemplo,dada as seguintes estruturas:

DCL 1 B, DCL 1 C, DCL 1 D, DCL 1 E, 2 B1, 2 C1, 2 D1, 2 D1, 2 B2, 2 B2, 2 B2, 2 B2, 2 B3, 2 C3, 2 D3, 2 E3, 3 B4, 3 B4, 3 B4, 3 B4, 3 B5; 3 B5, 3 B5, 3 B5, 2 E6; 2 E6; 2 E6;

o comando B=C*D-E,BY NAME; implicara' as seguintes correspondencias entre os itens elementares das estruturas(operandos):

B.B2 = C.B2 * D.B2 - E.B2; B.B4 = C.B4 * D.B4 - E.B4; B.B5 = C.B5 * D.B5 - E.B5;

Deve-se ter bastante atencao quando os itens elementares das estruturas nao estao no mesmo nivel,pois poderao acontecer coisas do tipo mostrado a seguir.

DCL 1 AAA, DCL 1 P, (1)O comando AAA=P,BY NAME; 2 BBB, implicara em: 2 CCC, 2 CCC, AAA.CCC.DDD=P.CCC.DDD 3 DDD 3 DDD, 3 EEE, (2)O comando AAA.FFF= P,BY NAME; 2 FFF, implicara em: 3 GGG; 2 GGG; AAA.FFF.GGG=P.GGG

A referencia qualificada aplicada aos nomes das subestruturas permite mo- dificar os niveis de hierarquia na estrutura.

No caso mostrado, a variavel GGG, na estrutura AAA, pertence ao seu 3o. nivel e a outra variavel de mesmo nome GGG, na estrutura P, pertence ao 2o. nivel de P. Assim, quando se faz AAA.FFF, esta'-se referindo a um ni- vel imediatamente abaixo de AAA, que, no caso, e' o nivel da variavel GGG.

Entao, a variavel GGG de P esta' no 2o.nivel de P e a outra variavel GGG de AAA esta no 3o. nivel de AAA ou 2o. nivel de AAA.FFF e, nesse caso, pode-se usar o BY NAME para fazer referencias as variaveis GGG de P e de AAA, conforme o item (2)apresentado.

12.6. LIKE __________

O atributo LIKE serve para declarar estruturas ou subestruturas, total ou parcialmente, a partir de uma outra, tomada como base. Por conseguinte,

12. ESTRUTURAS

Page 106

o atributo LIKE e' usado no comando DCL, ao se declararem estruturas que vao ter parte ou partes, ou mesmo todas as partes, de uma outra ja' de- clarada.

Por exemplo,a estrutura TAXAS declarada a seguir como:

1 TAXAS, 2 FEDERAL, 3 DIRETA, 3 INDIRETA, 2 ESTADUAL, 3 DIRETA, 3 INDIRETA, 2 MUNICIPAL, 3 DIRETA, 3 INDIRETA;

poderia ter sido declarada,usando o atributo LIKE,como:

Page 83: Manual de PL1 - Completo

1 TAXAS, 2 FEDERAL, 3 DIRETA, 3 INDIRETA, 2 ESTADUAL LIKE FEDERAL, 2 MUNICIPAL LIKE FEDERAL;

ou com qualquer outra combinacao possivel.

Outro exemplo:

DCL 1 A1, DCL 1 A2, DCL 1 A3 LIKE A2; 2 B1, 2 B2, DCL 1 B LIKE A2.B2; 3 C1, 3 C2, 3 D1; 3 D2;

Pelas declaracoes apresentadas,as estruturas A3 e B terao as seguintes organizacoes:

1 A3, 1 B, 2 B2, e 2 C2, 3 C2, 2 D2; 3 D2;

Finalmente, o atributo LIKE copia tambem, alem da organizacao, os valores de inicializacao dos itens usados no atributo INITIAL, por exemplo: DCL 1 D, 2 B INIT (6); DCL 1 C LIKE D;. A estrutura C declarada, como a estrutura D, tera', alem da mesma organizacao que a estrutura D,tambem o valor 6 como inicializacao do item elementar B, ou seja: 1 C, 2 B INIT(6);

Um cuidado especial que se deve ter e' nas referencias aos elementos das estruturas, quando se usa o atributo LIKE. No ultimo exemplo visto, as referencias aos elementos das estruturas D e C, denominados B, deveriam ser feitas usando uma referencia qualificada, que no caso seria: D.B e C.

No caso de se usar o atributo LIKE para arrays de estruturas,deve ser salientado que a dimensionalidade do array de estrutura basico nao sera' copiada e assim para se declarar um outro array de estrutura, exatamente identico a um outro array de estrutura, ate' mesmo na dimensionalidade, deve-se indicar a dimensionalidade na declaracao do array a ser decla- rado, como,por exemplo:

Seja DCL 1 LETRAS(100),2 VOGAIS CHAR(1),2 CONSOANTES CHAR(1);

12. ESTRUTURAS

Page 107

1) DCL 1 LET LIKE LETRAS;implicara' em: DCL 1 LET,2 VOGAIS CHAR(1);2 CONSOANTES CHAR(1);

2) DCL 1 LET(100) LIKE LETRAS;implicara' em: DCL 1 LET(100),2 VOGAIS CHAR(1),2 CONSOANTES CHAR(1);ou seja, exatamente igual a estrutura LETRAS.

3) DCL 1 LET(20) LIKE LETRAS:implicara' em: DCL 1 LET(20),2 VOGAIS CHAR(1),2 CONSOANTES CHAR(1);

Uma estrutura, quando declarada com o atributo LIKE, se torna identica a que foi considerada como base (menos a dimensionalidade do array-base) e, nessa condicao, podem ser usadas em expressoes de estruturas, pois tem a mesma configuracao, inclusive quando aos itens variaveis arrays, nao necessitando, pois, do uso do atributo BY NAME, uma vez que seus itens sao todos com mesmos nomes e mesmas ordens de hierarquia.

12.7. APLICACAO _______________

1) Programa para mostrar uma aplicacao dos atributos LIKE e BY NAME.

Page 84: Manual de PL1 - Completo

EX2C12: PROC OPTIONS(MAIN); DCL 1 DADOS_PESSOAIS ,2 NOME CHAR(25) ,2 NASCIMENTO ,3 DIA FIXED(2) ,3 MES FIXED(2) ,3 ANO FIXED(2) ,2 IDADE FIXED(2) ,2 ESTATURA ,3 ALTURA FIXED(3,2) ,3 PESO FIXED(2) ,2 ENDERECO ,3 RUA CHAR(15) ,3 NUMERO FIXED(5) ,3 CASA_APTO FIXED(4) ,2 LOCALIDADE ,3 BAIRRO CHAR(10) ,3 CIDADE CHAR(10) ,3 ESTADO CHAR(10) ; DCL 1 LOCALIZACAO ,2 ENDERECO LIKE DADOS_PESSOAIS.ENDERECO ,2 LOCALIDADE LIKE DADOS_PESSOAIS.LOCALIDADE 1 ANIVERSARIO ,2 NASCIMENTO LIKE DADOS_PESSOAIS.NASCIMENTO 1 DADOS_FISICOS ,2 IDADE FIXED(2) ,2 ESTATURA LIKE DADOS_PESSOAIS.ESTATURA ;

12. ESTRUTURAS

Page 108

GET FILE(SYSIN) EDIT(DADOS_PESSOAIS) (COL(1),A(25),4 F(2),F(3,2),F(2),A(15),F(5),F(4),3 A(10)); LOCALIZACAO = DADOS_PESSOAIS,BY NAME; ANIVERSARIO = DADOS_PESSOAIS,BY NAME; DADOS_FISICOS = DADOS_PESSOAIS,BY NAME; PUT FILE(SYSPRINT) SKIP(2) DATA(DADOS_PESSOAIS); PUT FILE(SYSPRINT) SKIP(2) DATA(LOCALIZACAO); PUT FILE(SYSPRINT) SKIP(2) DATA(ANIVERSARIO); PUT FILE(SYSPRINT) SKIP(2) DATA(DADOS_FISICOS); END EX2C12;

12. ESTRUTURAS

Page 109

13. COMANDO 'EDIT' DE ENTRADA E SAIDA _____________________________________

Page 85: Manual de PL1 - Completo

13.1. INTRODUCAO ________________

E' mais um comando de entrada e saida. A exemplo dos outros dois vistos anteriormente, o LIST e o DATA, apresenta-se na forma GET EDIT, quando usado para entrada, e na forma PUT EDIT, quando usado para saida de informacoes.

Sua forma geral e':

label: GET EDIT(lista de variaveis) (lista de formato) (lista de variaveis) (lista de formato) (lista de variaveis) (lista de formato);

label: PUT EDIT(lista de variaveis) (lista de formato) (lista de variaveis) (lista de formato) (lista de variaveis) (lista de formato);

sendo, tambem, permitido o uso dos atributos COPY (para o GET), SKIP, LINE e PAGE(para o PUT), como foi visto nos comandos LIST e DATA.

Na lista de variaveis do comando PUT EDIT e' tambem permitido o uso de expressoes ,"built-ins" ,pseudovariaveis e string de caracteres, alem de variaveis simples ou arrays ou estruturas, exatamente como foi visto parao comando LIST de saida (PUT LIST). Apenas nao foram feitas referen- cias a "built-ins", pseudovariaveis e estruturas, por nao se ter tido conhecimento, na ocasiao, dos seus significados.

Contudo, este comando envolve um conceito novo, que e' o de lista de formato.

Pode-se entender como lista de formato uma lista de codigos, denominados itens de FORMAT, separados por virgula, que se referem a cada um dos ti- pos de variaveis, em ordem, e que constituem a lista de variaveis do comando.Eles servem para determinar quais os tipos e como os elementos das listas de variaveis vao ser lidos e impressos; servem tambem para controle das unidades de entrada e saida no que se refere 'a disposicao dos campos, que conterao os valores dos elementos da lista de variaveis.

Devido a essas duas utilizacoes dos itens de FORMAT, eles se dividem em dois tipos: itens de FORMAT de controle e itens de FORMAT de dados.

13.2. ITENS DE FORMAT DE CONTROLE _________________________________

Sao os seguintes: PAGE, SKIP(w) e LINE(w), tendo os mesmos significados dos atributos opcionais usados nos comandos de entrada e saida vistos, quando usados dentro da lista de formato. Eles podem ser usados dentro e/ou fora da lista de formato. E mais X(w),especificando que w brancos

13. COMANDO 'EDIT' DE ENTRADA E SAIDA

Page 110

vao ser saltados antes do proximo elemento da lista de variaveis ser lido ou impresso,e COLUMN(w), que se abrevia por COL(w), significando que a leitura ou impressao do proximo elemento da lista de variaveis se dara' a partir da w-esima coluna do cartao ou da impressao, respectivamente.

Exemplos desses itens de FORMAT serao vistos mais adiante, quando se tra- tar dos codigos do tipo itens de FORMAT de dados.

Quando os itens de FORMAT de controle, SKIP, PAGE e LINE, sao usados fora da lista de formato, ou seja, como opcoes dos comandos de entrada e saida vistos (LIST,DATA e EDIT), somente o PAGE e o LINE podem ser usados em combinacao. Por exemplo: PUT SKIP LIST ... ou PUT LINE(w) LIST.. ou PUT PAGE LIST...ou PUT PAGE LINE(w) LIST ... As combinacoes SKIP LINE(w) ou

Page 86: Manual de PL1 - Completo

LINE(w) SKIP nao sao permitidas. Quando usadas dentro da lista de formato, tal fato nao ocorre, pois, sendo os codigos de formato separados por virgulas, a acao sera' tomada para cada codigo separadamente, podendo ter, assim, situacoes como: SKIP,LINE(w),... ou LINE(w),SKIP... ou ...,PAGE,SKIP(w),... etc.

Assim, se no terceiro elemento de uma lista de formato, houver o item de format SKIP(2) e os dois elementos da lista forem ITENS DE FORMAT DE DADOS, antes da leitura ou impressao do 3o. elemento da lista de variaveis, e se esse 3o. elemento existir, sera' saltado um cartao ou uma linha, respectivamente.

13.3. ITENS DE FORMAT DE DADOS ______________________________

Os itens de format de dados sao:

1) PICTURE FORMAT,cuja forma e' P'especificacao',onde 'especificacao' e' uma das ja' vistas quando foi apresentado o atributo PICTURE;e' usado para variaveis com atributos declarados por meio do atributo PIC ou quando se deseja editar uma entrada ou saida de dados, representados por variaveis com outros atributos.

Por exemplo, se B e' FIXED(6,2) DECIMAL, um valor de 1.000,00 e' armazenado em B como sendo a constante 1000.00; se se deseja que a impressao dessa constante, por meio da variavel B, seja exatamente como se esperava, isto e', 1.000,00 em vez de 1000.00, pode-se usar o item de formato P, na lista de itens de formato do comando PUT EDIT, com a seguinte especificacao: P'9.999V,99', onde o ponto decimal da constante 1000.00 e' alinhado na posicao do caracter V, da PICTURE. O caracter ponto (.) da PICTURE e' inserido e os digitos alinhados com os 9's da PICTURE. Entao:

DCL B DEC FIXED(6,2); B = 1000.00; PUT EDIT(B) (P'9.999V,99');

seria um trecho de programa para representar tudo o que foi descrito.

13. COMANDO 'EDIT' DE ENTRADA E SAIDA

Page 111

Vejamos mais um exemplo: Seja (D,E) FLOAT;D=1.25;E=6.5; o comando PUT EDIT(D,E) (lista de formato); implicara' as seguintes saidas, de acordo com estas listas de formato:

Listas de formatos Impressoes

(P'9V.99',P'S9V.9') 1 . 2 5 - 6 . 5 (P'999V,9',P'ZZZV,99') 0 0 1 , 2 6 , 5 0 (P'$$$9V.99',P'SSS9V,') $ 1 . 2 5 - 6 , (P'--9V,99',P'++9V,99') 1 , 2 5 6 , 5 0

O item de formato PICTURE, quando usado na leitura, exige que todas as posicoes do campo a ser lido com esse item tenham o caracter correspondente a posicao definida na especificacao PICTURE, isto e', se na posicao do campo,correspondente ao caracter virgula na especificacao, nao houver uma virgula perfurada, sera' emitida uma mensagem de erro e o programa sera' interrompido. Outro caso muito comum, e' um campo, quando lido com a especificacao contendo o carater 9, conter um branco na posicao correspondente. Assim, se a especificacao for, por exemplo, P'999', o campo tera' que ter algarismos entre 0 e 9, nas tres posicoes, mesmo que se queira ler a constante 3, quando entao se tera' que preencher o campo a esquerda com zeros: 003.

2) FIXED POINT FORMAT,cuja forma e' F(w,d,p), onde w representa o tamanho

Page 87: Manual de PL1 - Completo

do campo,d o numero de digitos que seguem o ponto decimal e p um fator de escala, podendo ser positivo ou negativo, representando multiplicar ou dividir o valor interno por 10**p.

O item de formato F, quando usado no comando de leitura, nao oferece dificuldade alguma, pois, uma vez especificado o tamanho do campo que contera' o valor da constante a ser lida (a especificacao w), pode-se perfurar a constante de qualquer maneira dentro do campo, desde que ela contenha o ponto decimal, com o qual sera' feito o alinhamento do ponto decimal do item de formato.

Se a constante nao contiver o ponto decimal, entao o alinhamento se dara' pela especificacao do item de formato d,indicando que as d colunas da direita, no campo, constituirao a parte fracionaria da constante.

Por exemplo: para o valor de constante igual a 3.2 e para a especificacao F(5,2),tem-se os seguintes tipos de campos perfurados:

12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 3.2 3.2 3.2 32 320 00320 003.2 03.20 3.200 00320

Um detalhe: se o campo estiver totalmente em branco, sera' lido o valor zero para a variavel correspondente na lista de variaveis.

Os exemplos a seguir ilustrarao os efeitos do item F na saida.

13. COMANDO 'EDIT' DE ENTRADA E SAIDA

Page 112

Valor interno FORMAT Impressao

+2567.89 F(4) 2568 -2891.432 F(5) -2891 -2891.432 F(7) bb-2891 -2891.432 F(8,3) 2891.432 -2891.432 F(8,2) -2891.43 +1234.5678 F(3) 235 -5641.21 F(11,3,2) -564121.000 1204.129 F(10,1,2) bb120412.9

3) FLOATING POINT FORMAT,cuja forma e' E(w,d{,s}),onde w representa o comprimento do campo de entrada ou saida,d o numero de digitos que seguem o ponto decimal e s o numero de digitos que devem aparecer antes do simbolo E,indicativo do expoente.

Quando usado em entrada de dados (comando GET EDIT),nao oferece dificuldade alguma,pois,uma vez especificado o comprimento do campo,pela especificacao w,a constante podera' ser perfurada em qualquer parte do campo, inclusive sem o expoente E, tendo que existir, nesse caso, o sinal menos ou mais entre a constante e o expoente, por exemplo: a constante 45.3E01 poderia estar perfurada em um dos modos:

123456789 123456789 123456789 123456789 45.3E01 45.3E01 45.3E01 45.3+01

ou ainda completando-se os campos com zeros, ou alinhando-se o ponto de- cimal em outra ordem qualquer, precisando apenas respeitar o comprimento do campo, o qual, na especificacao E, para esse caso, deve ter sido defi- nido como 9 (valor de w). Esse formato nao e' usado normalmente em en- trada. Seu uso mais constante, e assim mesmo mais em aplicacoes cientificas do que em aplicacoes comerciais, e' na saida de informacoes, o que se vai exemplificar:

Valor interno FORMAT Valor impresso

+397.7841 E(16,5) bbb397.78410E+00

Page 88: Manual de PL1 - Completo

+397.7841 E(16,6) bb397.784100E+00 +397.7841 E(16,7) b397.7841000E+00 +397.7841 E(16,8) 397.78410000E+00 +397.7841 E(16,9) 39.778410000E+01 +397.7841 E(16,10) 3.9778410000E+02 +397.7841 E(16,11) .39778410000E+03 +397.7841 E(17,10,12) 39.7784100000E+01 +397.7841 E(16,10,11) 3.9778410000E+02 +397.7841 E(16,10,10) .3977841000E+03

Todos esses exemplos sao validos tambem para as constantes negativas, e nesse caso, havendo espaco no campo, o sinal menos e' impresso; caso con- trario, ele nao e' impresso. Assim, se o valor interno dado fosse -397.7841, somente nos tres primeiros casos sairia o sinal menos.

13. COMANDO 'EDIT' DE ENTRADA E SAIDA

Page 113

Apenas como um adendo, qualquer constante perfurada na forma (+/-)a (+/-)b representa uma constante decimal de ponto flutuante (+/-)a E (+/-)b.

4) CHARACTER STRING FORMAT, cuja forma e' A{(w)}, onde w representa o comprimento do campo de entrada ou de saida para variaveis cujo atributo foi declarado como sendo CHAR(n).

Quando o item de formato A e' usado para entrada de valores, e' obrigatorio o uso da especificacao w, ou seja, e'-se obrigado a especifi- car o comprimento do campo que contera' um valor de constante string de caracteres.

Quando usado para saida, seu uso e' opcional, significando que, quando nao usado, o comprimento assumido para o campo de impressao sera' o do elemento da lista de variaveis do comando PUT EDIT.

Na entrada de dados nao oferece dificuldade alguma, pois, ao ser respeitado o comprimento do campo, o string de caracteres sera' alinhado pela sua posicao mais a esquerda do campo. Por exemplo, para um codigo de formato A(5) o string de caracteres 'bbXYb' so' tera uma posicao dentro do campo, que e':

12345 XY

Na saida, eis uma exemplificacao:

Valor interno FORMAT Valor impresso 'ABCDEF' A ou A(6) ABCDEF 'ABCDEF' A(5) ABCDE 'ABCDEF' A(8) ABCDEFbb 'bBCD' A(6) bBCDbb 'ABCDEFGH' A(3) ABC

5) BIT STRING FORMAT, cuja forma e' B(w), onde w representa o comprimento do campo de entrada ou de saida para variaveis declaradas com atributo BIT(n).

Seu uso e' identico ao caso anterior, do codigo A(w).

6) COMPLEX FORMAT, cuja forma e' C(i), onde i e' um dos itens de formato para constantes numericas ja' visto.

Seu uso e' identico aos casos dos itens de formato numericos vistos, ape- nas com a particularidade da duplicidade de campos, uma vez que um valor complexo e' composto de duas partes: a real e a imaginaria. O PL/I sempre considera o complexo com suas duas partes, mesmo que seja o complexo do tipo real puro ou do tipo imaginario puro, respectivamente com a cons-

Page 89: Manual de PL1 - Completo

tante imaginaria igual a zero e com a constante real igual a zero.

Eis alguns exemplos do uso de formato C(i) na saida:

Valor interno FORMAT Valor impresso -0.4+0I C(F(12,2)) -0.40 0.00

13. COMANDO 'EDIT' DE ENTRADA E SAIDA

Page 114

1.2-1I C(F(2)) 1 -1 3.45-1.4I C(E(9,4)) .3450E+01 .1400E+01

13.4. EXEMPLOS ______________

1) GET EDIT(C,D) (SKIP,F(9,2),E(10,3)); significa que o primeiro cartao sera' saltado e que no segundo cartao, nas primeiras nove colunas, sera' lida uma constante de ponto fixo, e nas dez colunas seguintes sera' lida uma constante de ponto flutuante. O primeiro cartao saltado poderia con- ter uma descricao dos valores perfurados no segundo, como um tipo de identificacao de massa de dados. Esse tipo de coisa e' muito usado quando se tem inumeras massas de dados e se quer identifica'-las. Colocando-se um cartao no inicio de cada massa, com qualquer informacao perfurada ou mesmo escrita, estamos identificando as referidas massas e ao serem submetidas a leitora, para constituirem entrada para um determi- nado processamento, o codigo de format de controle, SKIP, fara' com que esse cartao seja ignorado, nao afetando assim o referido processamento.

2) GET EDIT(D,G,H) (F(5),F(5),F(5)); poderia ser escrito de uma das seguintes maneiras:

GET EDIT(D,G,H) ((3)F(5));ou GET EDIT(D,G,H) (3 F(5));

E' o uso do fator de repeticao na lista de codigo de formato.

A diferenca entre o fator de repeticao usado entre parenteses ou nao explica-se pelo fato de que ele, ao ser usado como variavel, devera' vir sempre entre parenteses, e, ao ser usado como constante, como no exemplo dado anteriormente, podera' vir sem ou com os parenteses. Se vier sem parenteses, devera' ter pelo menos um branco entre ele e o codigo ao qual pertence. Um exemplo de fator de repeticao variavel seria:

DO I = -2 TO 2; PUT EDIT(A,B,C) ((I)F(6),(1-I)F(8),(2-I)E(15,6)); END;

Nesse exemplo, os valores das variaveis A,B e C serao impressos com os codigos de format dependendo do valor da variavel de controle I, do laco DO. E' importante salientar que, quando o fator de repeticao for nulo ou negativo,ele anulara' o codigo ao qual pertence. Assim, conforme o laco-DO for variando, obter-se-ao as seguintes listas de format para impressao das tres variaveis A,B e C: A B C Lista de format I=-2 F(8) F(8) F(8) ((-2)F(6),(3)F(8),(4)E(15,6)) nulo (3)F(8) excesso I=-1 F(8) F(8) E(15,6) ((-1)F(6),(2)F(8),(3)E(15,6)) nulo (2)F(8),(3)E(15,6)) I=0 F(8) E(15,6) E(15,6) ((0)F(6),(1)F(8),(2)E(15,6)) nulo (1)F(8),(2)E(15,6)) I=1 F(6) E(15,6) F(6) ((1)F(6),(0)F(8),(1)E(15,6))

13. COMANDO 'EDIT' DE ENTRADA E SAIDA

Page 115

Page 90: Manual de PL1 - Completo

(1)F(6) nulo (1)E(15,6) I=2 F(6) F(6) F(6) ((2)F(6),(-1)F(8),(0)E(15,6)) (2)F(6) nulo nulo

Conforme se pode verificar pelos exemplos dados, ha' momentos em que a lista de variaveis e' maior do que a lista de format, ou que a lista de variaveis e' menor do que a lista de format ou ainda que as duas sao iguais.

Quando elas forem iguais, nao havera' problema, porque a cada variavel correspondera' um item de formato de dado.

Quando a lista de variaveis for menor que a lista de formato, esta sera' abandonada,exatamente no momento em que o codigo de format de dado satisfazer ao ultimo elemento da lista de variaveis, o que significa que, se depois desse codigo de format aparecerem mais codigos de format, eles serao simplesmente abandonados, mesmo que seja um codigo de format de controle (SKIP, X(w), COL(w), etc...).

Quando a lista de variaveis for maior que a lista de formato, a lista de format sera' repetida ate satisfazer a todos os itens da lista de variaveis. Essa repeticao fara' com que esse caso recaia em um dos dois vistos, isto e', listas iguais ou listas de variaveis menores que a lista de format.

Eis alguns exemplos:

(a) PUT EDIT(A,B,C,D) (F(5,2),X(3),A(7),F(5),COL(80),A(1)); 1 2 3 4 1 2 3 4

(b) GET EDIT(X,Y,Z) (COL(1),A(3),A(2),E(9,3),F(4),X(10),F(1)); 1 2 3 1 2 3

(c) PUT EDIT(B,C,D,E,F) (F(7,1));a lista de format se repetira 5 vezes 1 2 3 4 5 PUT EDIT(B,C,D,E) (2 A,(F(1));a lista se repetira 2 vezes, ou seja, 1 2 3 4 3 e como se fosse: (2 A,F(1),2 A,F(1)) ou (A,A,F(1),A,A,F(1)) 1 2 3 4 recaindo no caso (b).

3) Nos codigos de format, w, d e s podem ser constantes (todos os casos vistos ate' agora), podem ser expressoes ou podem ser variaveis. Por exemplo:

DCL A CHAR(5) VAR, B FIXED(3);

GET EDIT(I,A,J,B) (F(2),A(I),F(2),F(J));

onde o valor da variavel I especificara' o comprimento da variavel A a ser lida e o valor da variavel J especificara' o comprimento do campo onde estara' perfurado o valor da constante de ponto fixo que sera' lida para a variavel B.

13. COMANDO 'EDIT' DE ENTRADA E SAIDA

Page 116

4) O comando PUT EDIT(A,B,C,D)(A(3),X(4),A(10),X(2),A(5),X(2),A(20)); e' identico ao comando escrito a seguir, onde foram substituidos os codigos de format de controle X(w), pelos comprimentos especificados nos codigos de format de dados A(w), englobando, assim, os espacos em branco que deveriam ser saltados na impressao, ou seja:

PUT EDIT(A,B,C,D) (A(7),A(12),A(7),A(20));

isso porque se sabe que um string de caracteres e' sempre alinhado a esquerda do campo. Se fossem constantes numericas, que se sabe nao serem

Page 91: Manual de PL1 - Completo

sempre alinhadas 'a direita do campo, ter-se-ia:

PUT EDIT(A,B,C,D) (F(3),X(4),F(10),X(2),F(5),X(2),F(20));

o qual poderia ser substituido pelo comando:

PUT EDIT(A,B,C,D) (F(3),F(14),F(7),F(22));

No entanto, deve-se ter cuidado nessas transformacoes, uma vez que nem sempre se podem incorporar os espacos em branco aos comprimentos especi- ficados nos codigos de format de dados para os elementos de uma lista de variaveis. Isso acontece realmente, quando nesses espacos em branco estao perfuradas algumas informacoes, nao so' de esclarecimento como tambem de interesse para posteriores leituras, por exemplo:

NOMES (esclarecimento) NOTA % frequencia MATERIA 12345678901234567890123456789012345678901234567890123456789012... 1 2 3 4 5 6 ______________________________________________________________ / ALFREDO LUIZ │N O T A =│ 8,25 │ 90.5 │ INGLES │ / │ │ │ │ │ / │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ (1) (2) (3) (4) (5)

O cartao apresentado significa o registro dos seguintes dados e seus res- pectivos campos:

NOMES -- col.1 a col.20 NOTA -- col.31 a col.35 FREQ -- col.40 a col.44 MATERIA -- col.51 a col.60

Um comando de leitura para as variaveis NOMES, NOTA e MATERIA poderia ser escrito como:

GET EDIT(NOMES,NOTA,MATERIA) (A(20),X(10),P'99V99',X(16),A(10));

13. COMANDO 'EDIT' DE ENTRADA E SAIDA

Page 117

onde os codigos de format de controle usados foram necessarios, uma vez que os campos saltados por eles continham informacoes desnecessarias : o primeiro campo saltado continha informacao de esclarecimento a respeito do campo a ser lido em seguida, e o segundo campo saltado continha informacao sobre percentagem de frequencia, a ser lido por um outro co- mando no mesmo programa ou em outro programa. Apenas como ilustracao, a lista de format desse comando poderia ser tambem escrita da seguinte maneira:

(A(20),COL(31)P'99V,99', COL(51),A(10))

5) Quando se desejar ler ou imprimir varios campos, de tal modo que eles nao completem 80 posicoes do cartao ou 120 da impressora, por varios cartoes ou impressoes, dever-se-a' ter suficiente cuidado para nao inco- rrer num erro muito comum, que e' completar a lista de itens de formato com o codigo X(w), por exemplo:

LER: GET EDIT(NOME,HORAS) (A(20),F(5),X(55));

GO TO LER;

Essa lista de codigos de format nao fara' com que a proxima leitura se verifique na coluna 1 do proximo cartao como se deseja, pois, uma vez satisfeita a lista de variaveis, a lista de formato e' abandonada ( ver

Page 92: Manual de PL1 - Completo

caso de lista de variaveis menor do que a lista de format) exatamente no momento em que o codigo F(5) foi executado.

Para se conseguir tal evento, e' necessario que no inicio da lista de codigos de formato exista o codigo COL(w), que no caso w deve ser igual a 1. Assim, GET EDIT(NOME,HORAS) (COL(1),A(20),F(5)); seria a solucao.

6) Se os campos especificados pela lista de format nao couberem num cartao ou numa linha de impressao, poderao ser continuados nos cartoes seguintes ou nas linhas de impressao seguintes, sempre considerando que, apos a coluna 80, vira' a coluna 1 do cartao seguinte, ou, apos a coluna 120, vira' a coluna 1 da linha seguinte, continuamente. Assim, por exemplo, se tivermos: DCL 1 EST, 2 A CHAR(50), 2 B, 3 B1 CHAR(25), 3 B2 CHAR(10), 2 D CHAR(40); o comando GET EDIT(EST)(A(50),A(25),A(10),D(40)) fara' com que sejam lidos, continuamente, dois cartoes, o primeiro comecando na coluna 1 (considerando que o cursor esteja posicionado nessa coluna) e o segundo terminando na coluna 45.

Se a estrutura declarada fosse um array de estrutura, e se se quisesse que todos os elementos fossem lidos pelo comando apresentado, bastaria que se colocasse o codigo de controle, COL(1), no inicio da lista de formato, ou entao, especialmente neste caso, bastaria que se colocasse o codigo de controle, X(35), no final da lista de formato, pois, apenas como lembranca, estamos num caso em que a lista de variaveis e' maior que a lista de formato, e assim, a lista de formato sera' repetida ate' aca- bar a lista de variaveis (composta por todos os elementos do array de estrutura EST).

13. COMANDO 'EDIT' DE ENTRADA E SAIDA

Page 118

13.5. FORMAT REMOTO ___________________

Uma outra maneira de se especificar uma lista de formato e' atraves da modalidade denominada FORMAT remoto. Sua forma e' (R(label)), onde label e' o rotulo de um comando, denominado comando FORMAT, cuja forma e': FORMAT(lista de formato).

Assim, se se tiver uma lista de formato a ser usada em mais de um comando de entrada e saida EDIT, para que essa lista nao seja repetida nos coman- dos todas as vezes que se desejar usa'-la, poder-se-a' escreve-la no co- mando FORMAT apenas uma vez, e usa'-la nos comandos de E/S, referenciando-se a ela por meio do format remoto. Eis um exemplo:

LL1: FORMAT(A(5),SKIP,F(7,4),X(13),F(4)); ....... GET EDIT(X,Y,Z) (R(LL1); ....... PUT LINE(5) EDIT(A,B,C) (R(LL1)); ....... GET EDIT(I,J) (R(LL1));

Podemos, ainda, combinar essa forma com quantos codigos de formato quisermos ou com quantos FORMAT remoto desejarmos:

PUT EDIT(A,B,C) (R(FORM),A(3),R(FORM),F(5,2)); onde FORM e' o label do comando FORMAT remoto definido em algum lugar no programa.

A definicao do FORMAT remoto podera' conter outros FORMAT remotos:

F1: FORMAT(A(2),F(3,1));

F2: FORMAT(X(3),R(F1),F(2));

F3: FORMAT(R(F2),R(F1));

Page 93: Manual de PL1 - Completo

Para terminar a apresentacao do FORMAT remoto, lembramos que o label re- ferenciado podera' ser um label variavel, de tal modo que poderiamos ter: GET EDIT(....) (R(F)); onde, em qualquer momento, F tenha sido definido com o valor de F1, F2 ou F3.

13.6. APLICACOES ________________

1) Vejamos novamente o problema da pedra TORRE num jogo de xadrez. Agora ja' podemos usar as 64 posicoes do tabuleiro, ao inves das 25 usadas na simulacao do tabuleiro em capitulo anterior, porque, com o uso do comando EDIT, podemos controlar com mais facilidade as posicoes de impressoes, o que nao acontecia com o comando LIST, a menos que se usassem alguns arti-

13. COMANDO 'EDIT' DE ENTRADA E SAIDA

Page 119

ficios pelo uso da built-in STRING ou CHAR, o que serviria apenas como exercicios didaticos. Vejamos, pois, o programa:

EX1C13: PROC OPTIONS(MAIN); DCL LINHA(8) CHAR(1) INIT((8)(1)'*') ,LINHAI(8) CHAR(1) INIT((8)(1)'.') ,(I,J) FIXED(1) ; GET EDIT(I,J) (COL(1),2 F(5,0)); LINHAI(J) = '*'; LINHA(J) = 'T'; DO K = 1 TO 8; IF K = I THEN PUT SKIP EDIT(LINHA) ((8)A(2)); ELSE PUT SKIP EDIT(LINHAI) ((8)A(2)); END; END EX1C13;

Assim, para os valores de I e J, lidos como 2 e 3, respectivamente, teremos a seguinte saida:

____________________________________ │ │ . . * . . . . . │ * * T * * * * * │ . . * . . . . . │ . . * . . . . . │ . . * . . . . . │ . . * . . . . . │ . . * . . . . . │ . . * . . . . . │ _________ │ / │_________________________/

13. COMANDO 'EDIT' DE ENTRADA E SAIDA

Page 120

14. AREAS COMUNS NA MEMORIA ___________________________

Page 94: Manual de PL1 - Completo

14.1. INTRODUCAO ________________

Neste capitulo sera' abordado o caso de definicao de valores em areas comuns na memoria, como, por exemplo, leitura de valores localizados em areas de memoria pertencentes a variaveis string de caracteres (opcao STRING de E/S) e definicao de variaveis em areas ja' definidas por outras variaveis (atributo DEFINED), abrangendo os tipos de definicao por co- rrespondencia e por sobreposicao.

14.2. OPCAO STRING DE E/S _________________________

Foi visto ate' agora que os comandos GET e PUT eram usados para transmissao de dados de ou para um meio externo e que esses meios exter- nos eram, respectivamente, a leitora de cartoes perfurados padrao do sis- tema operacional (SYSIN) e a impressora de formularios continuos padrao do sistema operacional (SYSPRINT).

Na verdade, apos as palavras-chave GET e PUT dos comandos vistos, sem mais nenhuma modificacao das coisas aprendidas ate' agora, com referencia aos comandos de E/S GET e PUT, podem-se adicionar as palavras FILE(SYSIN) 'a palavra GET ou as palavras FILE(SYSPRINT) 'a palavra PUT, represen- tando que os comandos estao se referindo aos arquivos (FILE) padrao do sistema SYSIN e SYSPRINT. Assim, qualquer um dos exemplos desses comandos visto anteriormente poderia ser escrito dessa maneira, por exemplo:

GET EDIT(A,B) (COL(1),F(4),A(5)); poderia ser escrito como GET FILE(SYSIN) EDIT(A,B) (COL(1),F(4),A(5)); ou ainda PUT FILE(SYSPRINT) DATA(X,Y,Z); ou ainda PUT FILE(SYSPRINT); ou ainda PUT FILE(SYSPRINT) PAGE;etc.

Muito bem, a opcao STRING de entrada e saida e' usada com os comandos GET e PUT, porem, em vez da transmissao de dados ser feita de ou para um meio externo, essa transmissao e' feita internamente de variavel para variavel e a parte dos comandos GET e PUT, referenciada no paragrafo anterior, formada pelas palavras FILE(nome do arquivo-padrao), e' substituida pelas palavras STRING(nome da variavel string de caracteres)

Vejamos um exemplo, para melhor esclarecer o assunto. Um conjunto de cartoes contem informacoes a serem lidas para um determinado processamento. Os cartoes que formam esse conjunto podem ter uma, duas ou tres variaveis, as quais deverao ser lidas com codigos de format diferen- tes para cada caso. A ligacao entre o numero de variaveis existente num tipo de cartao, que esta' perfurado na coluna 80, e o formato de leitura podera' ser feita no programa por meio da opcao de E/S GET STRING, senao vejamos:

14. AREAS COMUNS NA MEMORIA

Page 121

EX1C14: PROC OPTIONS(MAIN); DCL XAV_FIM BIT(1) INIT('1'B) ,(A,B,C) CHAR(5) ,D FIXED(5,2) ,(E,F) FLOAT(6) ; DCL ENTRADA CHAR(80) ,CODIGO CHAR(1) ; ON ENDFILE(SYSIN) XAV_FIM = '0'B; GET FILE(SYSIN) EDIT(ENTRADA) (A(80)); DO WHILE(XAV_FIM); GET STRING(ENTRADA) EDIT(CODIGO) (X(79),A(1));

Page 95: Manual de PL1 - Completo

IF CODIGO = '1' THEN GET STRING(ENTRADA) EDIT(F) (X(1),P'9V.999'); ELSE IF CODIGO = '2' THEN GET STRING(ENTRADA) EDIT(D,E) (F(5,2),E(6,2)); ELSE IF CODIGO = '3' THEN GET STRING(ENTRADA) EDIT(A,B,C) (3 A(25)); ELSE PUT SKIP LIST('ERRO -- CODIGO DIFERENTE DE 1,2 OU 3'); GET FILE(SYSIN) EDIT(ENTRADA) (A(80)); END; END EX1C14;

Conforme o leitor podera' verificar,todo o cartao e' lido do meio ex- terno, que e' o arquivo-padrao do sistema operacional, SYSIN, por meio do comando GET EDIT, para a variavel denominada ENTRADA e declarada CHAR(80). Dai em diante, todas as demais leituras sao feitas em cima dessa variavel. Assim, ao ser lido o valor do codigo, que no cartao estava perfurado na coluna 80 e que agora na variavel ENTRADA esta' exatamente na posicao 80a., pode-se voltar a ler no formato conveniente os valores das variveis A,B,C,D,E e F, operacao essa que, se fosse em cartao, nao poderia ser efetivada, pois, uma vez lido um cartao, este nao podera' mais ser lido em suas posicoes anteriores.

Um detalhe interessante a ser notado e' que, para ler mais de uma vez uma variavel string de caracteres na memoria, nao precisamos ter o cuidado mencionado antes, de posicionar o cursor de leitura no inicio do campo, como se fazia em cartoes perfurados por meio do codigo de format COL(w). Ele se posicionara' automaticamente na primeira posicao sempre que for iniciado um comando GET STRING(ou PUT STRING, para gravacao).

Vejamos, agora, uma aplicacao do comando de saida PUT STRING.

Um conjunto de cartoes tem perfurados nas colunas 60 a 61 numeros que definem a sua ordem numa colecao de 50 valores. Estando os cartoes nao ordenados, o programa a seguir os lera' e os imprimira' ordenadamente, desde o mais baixo ao mais alto (ordem crescente).

14. AREAS COMUNS NA MEMORIA

Page 122

EX2C14: PROC OPTIONS(MAIN); DCL (CONT_CARTAO INIT(0),NUM_LINHA) FIXED ,IMAGEM(50) CHAR(80) INIT((50)(1)'') ,CARTAO CHAR(80) ; ON ENDFILE(SYSIN) GOTO SEGUE; DO I = 1 TO 50; GET FILE(SYSIN) EDIT(CARTAO) (A(80)); GET STRING(CARTAO) EDIT(NUM_LINHA) (X(59),F(2)); PUT STRING(IMAGEM(NUM_LINHA)) EDIT(CARTAO) (A); CONT_CARTAO = CONT_CARTAO + 1; END; SEGUE: PUT SKIP EDIT('IMPRESSAO DOS ',CONT_CARTAO,'LIDOS E', 'ORDENADOS') (A,F(2),2 A); DO I = 1 TO 50; IF IMAGEM(I) = (80)'' THEN PUT SKIP LIST('',IMAGEM(I)); END; END EX2C14;

14.3. DEFINED _____________

Page 96: Manual de PL1 - Completo

O atributo DEFINED e' usado para redefinir areas na memoria, isto e', de- finir uma variavel que ocupara' o mesmo local de memoria que uma outra ja' definida.

E' usado no comando DECLARE e sua forma geral e':

_______________________________________________ │ │ │ variavel DEFINED variavel base POSITION(c) │ │_______________________________________________│

constituindo o tipo de DEFINICAO DE SOBREPOSICAO, ou

____________________________________________________ │ │ │ array DEFINED array base (lista de subscrito) │ │____________________________________________________│

constituindo o tipo de DEFINICAO DE CORRESPONDENCIA.

Veremos a seguir os tipos apresentados.

14. AREAS COMUNS NA MEMORIA

Page 123

14.4. DEFINICAO DE SOBREPOSICAO _______________________________

Nesse tipo, a variavel a ser definida, se for estrutura, devera' ser de nivel 1, e o atributo VARYING nao pode ser especificado nem para a variavel a ser definida nem para a variavel-base.

As palavras-chave DEFINED e POSITION podem ser abreviadas por DEF e POS.

Vejamos uma aplicacao: DCL BB CHAR(100), B CHAR(10) DEF BB; significa que os 10 caracteres do string B ocupam as mesmas posicoes dos 10 primeiros caracteres do string BB, ou seja, os 10 primeiros caracteres d string BB foram redefinidos pelos caracteres de B. E' obvio que se referir ao string B e' o mesmo que se referir 'as 10 primeiras posicoes do string BB, pois, sendo o mesmo local de memoria, so' podera' haver um conteudo (valor da constante string de caracteres).

Conforme se pode notar, foi omitido o parametro POSITION, significando que a sobreposicao se dara' a partir da primeira posicao.

A declaracao, portanto, poderia ser feita usando o atributo POS, da seguinte forma:

DCL B CHAR(10) DEF BB POS(1);

Esse atributo e' obrigatorio quando se deseja que a sobreposicao se de nao a partir da primeira posicao, e sim a partir de uma outra qualquer. Por exemplo, para a mesma variavel BB declarada anteriormente, poderiamos desejar que a sobreposicao se desse a partir da 91a. posicao, ou seja, sobre os 10 ultimos caracteres do string BB e, nesse caso, teriamos:

DCL B CHAR(10) DEF BB POS(91);

Assim, poderiamos formar varios exemplos, como:

Page 97: Manual de PL1 - Completo

14. AREAS COMUNS NA MEMORIA

Page 124

(a) DCL 1 A, (b) DCL 1 A, 2 B CHAR(15), 2 B FIXED, 2 C CHAR(25), 2 C FLOAT, D CHAR(40) DEF A; 1 Y DEF A, 2 Y1 FIXED, 2 Y2 FLOAT;

Nesse tipo de definicao, devemos ter cuidado quando declaramos variaveis de tipos diferentes. Entre as variaveis declaradas como CHAR e como PICTURE, praticamente nao ha' problemas, a menos que nao tenhamos cuidado com a posicao do sinal nas PICTURES numericas, e normalmente o Compilador PL/I nos advertira'. Ja' com variaveis com atributos FIXED e FLOAT, alem da posicao de sinal dos campos, um outro problema se nos apresenta, que e' o de compactacao de ponto fixo e o de ponto flutuante. A essas variaveis podemos fazer definicoes de sobreposicao com variaveis CHAR ou PICTURE de caracteres, quando temos que trata'-las como um todo, isto e', nao havendo necessidade de nos referirmos a cada uma delas em separado. Essa operacao e' muito comum em manipulacoes de registros, quando nao se desejam fazer referencias aos seus campos isoladamente e sim a todos eles, ou sejam a todo o registro de uma so' vez (isso sera' visto com mais detalhes quando tratarmos de arquivos, mais adiante).

Apenas como ilustracao, temos:

DCL LETRAS CHAR(5) INIT('NORMA');

DCL LETRA CHAR(1) DEF LETRAS;

LETRA = 'F';

tem o mesmo significado que:

DCL LETRAS CHAR(5) INIT('NORMA');

SUBSTR(LETRAS,1,1) = 'F';

ambos fazem com que o string de caracteres LETRAS, que inicialmente tinha o valor da constante string de caracteres 'NORMA' passe a ter o string 'FORMA'.

14.5. DEFINICAO DE CORRESPONDENCIA __________________________________

Esse tipo e' usado quando a variavel definida e a variavel a ser definida sao variaveis ARRAYS, nao sendo permitido, no entanto, para variaveis arrays de estruturas.

14. AREAS COMUNS NA MEMORIA

Page 125

Conforme foi visto, podera' ser usado com a lista de subscrito especifi- cada ou nao, respectivamente, entre arrays de dimensoes diferentes e mesmas dimensoes.

Assim, se B e' um array de uma dimensao, com 20 elementos, pode-se decla- rar um outro array C, cujos elementos serao definidos exatamente na mesmas posicoes de memoria que os elementos do array B ocupam. Assim, teremos:

DCL B(20) FIXED INIT((20) 0), C(20) FIXED DEFINED B;

E' o caso do array-base usado sem a lista de subscrito. Notem-se dois

Page 98: Manual de PL1 - Completo

pontos importantes: 1) os arrays devem ter os mesmos atributos; 2) somente o array-base pode usar o atributo INITIAL.

Assim, essas declaracoes indicam que os 20 elementos do array C estarao ocupando as mesmas posicoes de memoria dos elementos do array denominado B, cujos valores iniciais sao todos iguais a zero; por conseguinte, os valores dos elementos de C tambem sao todos iguais a zero.

DCL LISTA(10,30), CODIGO(10,30) DEF LISTA; seria um outro exemplo de definicao de correspondencia, agora entre arrays de duas dimensoes.

Por outro lado, nem sempre se deseja que a definicao cubra todos os ele- mentos de um determinado array; por exemplo, pode-se desejar que a definicao de correspondencia cubra apenas os elementos da diagonal prin- cipal de uma dada matriz. E, para isso, o PL/I exige que seja usada lista de subscrito acoplada ao array-base, indicando quais as posicoes que serao redefinidas nesse array (array basico).

Com isso os arrays nao precisam mais ter as mesmas dimensoes, como no exemplo referido da diagonal principal; um array de 4 elementos e de uma dimensao podera' ocupar as mesmas posicoes que os elementos da diagonal principal de uma matriz de 4 linhas por 4 colunas (4x4).

Vejamos, pois, como e' construida a lista de subscrito do array-base.

Conforme o nome indica, e' uma relacao dos subscritos do array-base re- presentados por um tipo especial de variavel, cuja forma e' iSUB, sendo i uma constante inteira decimal que assumira' valores de acordo com a dimensao do array a definir.

Por exemplo, 1SUB representa subscritos da 1a. dimensao do array a ser definido; 2SUB representa subscritos da 2a. dimensao do array a ser defi- nido; 3SUB representa subscritos da 3a. dimensao do array a ser definido, e assim por diante.

Logo, se 2SUB, por exemplo, que representa subscritos da 2a. dimensao do array a ser definido, e' usado na lista de subscritos acoplada ao array- base, numa determinada posicao de dimensao, ele fara' corresponder os elementos dessa dimensao do array-base aos elementos que ele representa do array a ser definido; assim:

14. AREAS COMUNS NA MEMORIA

Page 126

DCL MATRIZ(4,4), DIAG(4) DEF MATRIZ(1SUB,1SUB);

E' o tipo de declaracao para o exemplo referido, sobre os elementos da diagonal principal de uma matriz ocuparem as mesmas posicoes que os ele- mentos de um vetor.

Ora, pela apresentacao da variavel especial iSUB, que no caso tem a forma 1SUB, pode-se facilmente deduzir que a mesma variara' de 1 a 4 (limites da dimensao do array DIAG a ser definido), indicando os elementos (1,1), (2,2), (3,3) e (4,4) da matriz denominada MATRIZ.

Em resumo, pode-se entao dizer que a variavel especial iSUB e' usada na lista de subscrito do array-base, em que i e' a ordem da dimensao do array a ser definido e que iSUB variara' de acordo com os limites da dimensao i. Para completar, a lista de subscrito podera' ser formada por expressoes cujas variaveis sao as do tipo iSUB.

Por exemplo, no caso da diagonal principal, para uma redefinicao analoga 'a que foi feita, apenas sem aconsiderar o primeiro e o ultimo valores da diagonal teremos:

DCL B(10,10), C(8) DEF B(1+1SUB,1+1SUB);

Page 99: Manual de PL1 - Completo

14.6. EXEMPLOS ______________

1) DCL A(30),Y(5) DEF A(1SUB); redefine as posicoes A(1), A(2),... A(5) com os elementos Y(1), Y(2),... Y(5). Neste caso, a variavel especial 1SUB se refere ao 1o. subscrito (e unico) da variavel Y a ser definida e seu valor varia de 1 a 5, que sao os limites da dimensao do array a ser definido Y.

2) DCL A(30), Y(5) DEF A(25+1SUB); redefine as posicoes A(26), A(27), A(28), A(29), e A(30) com os elementos Y(1), Y(2), ... Y(5) e a variavel 1SUB assumira' os valores 1 a 5, que sao os limites da dimensao de Y.

3) DCL A(50,30), B(50) DEF A(1SUB,15); redefine a 15a. coluna do array A com um array de 1 dimensao B com 50 elementos.

4) DCL A(5,3), B(3,5) DEF A(2SUB,1SUB); seria uma aplicacao da matriz transposta de A, ou vice-versa. A variavel 2SUB variara' de 1 a 5, pois se refere a 2, dimensao do array a ser definido, cujos limites sao 1 e 5 , e a variavel 1SUB variara' de 1 a 3, pois se refere a 1, dimensao do array a ser definido, cujos limites sao 1 e 3.

5) DCL A(10,10), B(5) DEF A(2*1SUB,2*1SUB); redefinicao apenas nos ele- mentos pares da diagonal principal de A.

A(2,2) ---------- B(1)

14. AREAS COMUNS NA MEMORIA

Page 127

A(4,4) ---------- B(2) A(6,6) ---------- B(3) A(8,8) ---------- B(4) A(10,10) -------- B(5)

14. AREAS COMUNS NA MEMORIA

Page 128

15. BLOCOS __________

15.1. BLOCO BEGIN, BLOCO PROCEDURE,GRUPO DO ___________________________________________

Um GRUPO DO e' uma sequencia de comandos encabecada pela palavra DO se- guida de ponto-e-virgula e terminada pelo comando END; Serve apenas para agrupar comandos. Seu uso mais constante e' nas unidades THEN e ELSE do

Page 100: Manual de PL1 - Completo

comando IF, quando nelas e' usado mais de um comando.

O grupo DO nao tem nada a ver com o comando DO ja visto, ou seja, nao identifica laco algum, permitindo, assim, entradas em qualquer dos seus comandos de pontos externos ao grupo.

Ja' um BLOCO e' uma sequencia de comandos que define uma determinada area num programa como tendo caracteristicas proprias. E' usado para delimitar o "scope" de um identificador (variavel, label, etc.).

Pode-se entender como "scope" um trecho do programa em que sao validas as caracteristicas de um identificador. Ver-se-a' isso com mais detalhes um pouco mais adiante, ainda neste topico.

Os blocos se dividem em dois tipos: PROCEDURE e BEGIN, ambos delimitados pelos comandos PROCEDURE (ou PROC) e BEGIN, seguidos por ponto-e-virgula, respectivamente, e pelo comando END;

DO; label: PROC; label: BEGIN;

(comandos) (comandos) (comandos)

END; END label; END label;

GRUPO-DO BLOCO-PROCEDURE BLOCO-BEGIN

Um programa e' composto por blocos PROCEDURE ou blocos PROCEDUREs e BEGIN, nunca somente por blocos BEGIN.

Um programa pode consistir em um ou mais blocos.

Todos os programas vistos ate' agora sao compostos por apenas um bloco, do tipo PROCEDURE. Conforme o leitor podera' verificar, todos esses pro- gramas comecam com o comando label: PROC OPTIONS(MAIN); que e' um tipo especial de PROCEDURE, denominado PROCEDURE PRINCIPAL. Todo programa deve ter pelo menos um Bloco PROCEDURE (que se abrevia por PROC), que e' chamado principal.

Ver-se-a' mais adiante que as PROCEDURES (ou PROCS), quando nao acrescidas das palavras OPTIONS(MAIN), sao denominadas SUBPROGRAMAS, podendo ser SUB-ROTINA ou FUNCAO.

15. BLOCOS

Page 129

A: PROC OPTIONS(MAIN); C: PROC OPTIONS(MAIN);

------- -------

BEGIN; D: PROC;

---- -----

---- -----

B: PROC; BEGIN;

----- ----

----- ----

END B; END;

------ ----

------ ----

END; END D;

Page 101: Manual de PL1 - Completo

---- ------

---- ------

END A; END C;

Nos exemplos mencionados, as PROC de label A e C sao procedures principais, as de label B e D sao blocos PROCEDURES normais e os demais sao blocos BEGIN.

O bloco PROCEDURE principal e' invocado automaticamente pelo sistema ope- racional, os outros blocos PROCEDURE sao invocados por comandos proprios, denominados CALL, que fazem parte de algum outro bloco, e os blocos BEGIN sao invocados pelo uso de um dos comandos de desvio GOTO o ON, ou ainda pela sequencia natural dos comandos do bloco a que ele pertence.

Um bloco BEGIN, depois de executado, retorna ao comando imediatamente seguinte ao seu comando END, no bloco que o ativou.

Um bloco PROC retorna o controle ao comando imediatamente seguinte ao co- mando CALL que o ativou.

Vejamos um exemplo de um programa contendo um bloco BEGIN e um bloco PROCEDURE.

1 EX1C15: 2 PROC OPTIONS(MAIN); 3 DCL A(2,3),B(3,2),C(2,2); 4 CALL PROD;

15. BLOCOS

Page 130

5 DO I=1 TO 2; 6 PUT SKIP EDIT((C(I,J) DO J = 1 TO 2)); 7 END; 8 BEGIN; 9 DCL A(5,4),B(4,2),C(5,2); 10 GET LIST(A,B); 11 PUT SKIP(2) EDIT(A) (F(2)); 12 PUT SKIP(2) EDIT(B) (F(2)); 13 DO I = 1 TO 5; 14 DO K = 1 TO 2; 15 SOMA = 0; 16 DO J = 1 TO 4; 17 SOMA = SOMA + (A(I,J)*B(J,K)); 18 END; 19 C(I,K) = SOMA; 20 END; 21 END; 22 PUT SKIP(2); 23 DO I = 1 TO 5; 24 PUT SKIP EDIT((C(I,J) DO J=1 TO 2)) (F(2)); 25 END; 26 END; 27 PROD: 28 PROC; 29 GET LIST(A,B); 30 PUT SKIP EDIT(A) (F(2)); 31 PUT SKIP EDIT(B) (F(2)); 32 C = 0; 33 DO I = 1 TO 2; 34 DO J = 1 TO 3; 35 DO K = 1 TO 2; 36 C(I,K) = A(I,J) + C(I,K); 37 END; 38 END;

Page 102: Manual de PL1 - Completo

39 END; 40 END PROD; 41 END EX1C15;

Essa aplicacao mostra uma PROCEDURE principal de nome EX1C15, contendo dois blocos, um BEGIN e um PROCEDURE de nome PROD. Nela, o primeiro bloco a ser ativado e' o bloco PROCEDURE, pois, na ordem de apresentacao dos seus comandos, o comando CALL PROD aparece antes do comando identifi- cador do bloco BEGIN. Assim, ao ser ativado o bloco PROC, os comandos desse bloco sao executados, e, ao encontrar o comando END do bloco, o controle do programa e' retornado ao comando imediatamente seguinte ao comando que ativou o bloco, o comando CALL PROD (linha 4), que e' o co- mando DO I = 1 TO 2; (linha 5). Apos executar o laco especificado por esse comando, e' ativado o bloco BEGIN (linha 8), pela simples passagem da logica do programa por aquele ponto. Dai' em diante, os comandos do bloco BEGIN sao executados e, ao chegar no seu comando END, o retorno ao programa que o ativou se dara' no comando imediatamente seguinte ao co- mando END do BEGIN encontrado, que e' o comando END EX1C15 (linha 41). Note o leitor que o trecho do programa compreendido entre as linhas 27 e 40 nao foi executado nessa ultima passagem, pois constituem os comandos do bloco PROCEDURE, de nome PROD. Esses comandos foram executados quando

15. BLOCOS

Page 131

o programa passou pelo comando CALL PROD, que e' justamente o comando que serve para ativar um bloco PROCEDURE, no caso, o bloco PROD.

Pode-se deduzir dessa filosofia que um bloco PROCEDURE pode ser colocado em qualquer parte de um programa, pois o que fara' com que ele seja executado sera' o comando de ativacao CALL, o qual estara', de acordo com a logica do programa, num ou em varios pontos do mesmo.

A presente aplicacao, puramente didatica, se presta a determinar o produto de duas matrizes, por dois processos diferentes, programados um no bloco PROCEDURE e outro no bloco BEGIN.

Um fato interessante acontecido no exemplo apresentado e' o uso de variaveis de mesmos nomes com significados diferentes num mesmo programa, como as variaveis A, B e C, sendo arrays de dimensoes (2,3), (3,2) e C(2,2) e tambem de dimensoes (5,4), (4,2) e (5,2), em trechos do pro- grama.

Isso se deve ao uso de blocos (procedure e/ou begin) no programa e e' exatamente esse fato que define o "scope" de variaveis ou, melhor dizendo, de identificadores num programa.

15.2. "SCOPE" DE IDENTIFICADORES ________________________________

Um identificador declarado dentro de um bloco tem significado somente dentro desse bloco.

Um identificador declarado fora de um bloco tem significado fora do bloco e dentro do bloco, a menos que ele tenha sido redeclarado nesse bloco.

Assim, o trecho do programa no qual um identificador mantem seu signifi- cado e' denominado "SCOPE" do identificador.

Por exemplo:

Page 103: Manual de PL1 - Completo

15. BLOCOS

Page 132

P: PROC; ---------------------- ----------------------- │ │ │ │ DCL A(5), B(10); │ │ │ │ │ │ │ │ Q: PROC; -------------------- ----------------------- │ │ │ │ │ │ DCL B FIXED, C BIN; │ │ │ │ │ │ │ │ │ │ │ │ R: PROC; ------------------ ----------------------- │ │ │ │ │ │ │ DCL C(10) FIXED; │ │ │ │ │ │ │ │ │ │ │ │ │ │ D BIN; │ │ │ │ │ │ │ │ │ │ │ │ │ │ END R; ----------------- ----------------------- │ │ │ │ │ │ END Q; ------------------- ----------------------- │ │ │ │ END P; --------------------- ----------------------- P A B B'C C'D Q R

As letras B e B' se referem a variavel B, assim como C e C' se referem a variavel C, sendo, porem, variaveis distintas.

A variavel A e' o identificador de um array de 5 elementos, todos decimais de ponto flutuante, que mantem esse significado em toda a procedure-P e nas procedures-Q e R. Ja a variavel B identifica um array de 10 elementos, todos decimais de ponto flutuante, que mantem esse sig- nificado somente na procedure-P. Na procedure-Q e na R, ele mantem o significado de variavel decimal de ponto fixo (variavel elementar).

Assim, voltando ao exemplo EX1C15 apresentado, as variaveis arrays A, B e C declaradas tem "scope" no programa principal abrangendo PROCEDURE-PROD e tem "scope" diferente no bloco BEGIN, onde elas foram declaradas com referencia 'as suas dimensoes.

Vejamos agora uma outra classificacao aplicada aos blocos, que e' a de blocos internos e de blocos externos.

15.3. BLOCOS INTERNOS E EXTERNOS ________________________________

Qualquer bloco pode conter um ou mais blocos.

A classificacao de blocos internos e externos e' sempre relativa, ou seja, um bloco que esta contido em um outro e' dito interno a esse outro e um bloco que nao esta contido em um outro e' dito externo a esse outro.

Os blocos BEGIN sao sempre internos a, pelo menos, um outro bloco (PROCEDURE ou BEGIN).

15. BLOCOS

Page 133

No EX1C15, o bloco BEGIN e o PROCEDURE-PROD sao externos, um em relac ao ao outro, e sao internos em relacao ao bloco PROCEDURE principal. Ja no exemplo dado para explicar o "scope" das variaveis A, B, C e D e dos labels P. Q e R, o bloco R e' interno ao bloco Q, que, por sua vez, e' interno ao bloco P.

_A:PROC; │ (comandos da proc-A)

Page 104: Manual de PL1 - Completo

│ _B:BEGIN; │ │ (comandos do begin-B) │ │___END B; │ _C:PROC; │ │ (comandos da proc-C) │ │ _D:BEGIN; │ │ │ (comandos do begin-D) │ │ │ _E:PROC; │ │ │ │ (comandos da proc-E) │ │ │ │___END E; │ │ │ (comandos do begin-D) │ │ │___END D; │ │ (comandos da proc-C) │ │___END C; │ (comandos da proc-A) │___END A;

Esse exemplo serve para mostrar os niveis de relacao dos blocos de acordo com a classificacao de interno e externo vista.

Assim, em relacao ao bloco principal, PROC-A, tem-se dois niveis:

1o. nivel - BEGIN-B e PROCEDURE-C 2o. nivel - BEGIN-D 3o. nivel - PROCEDURE-E

Em relacao ao bloco PROCEDURE-C, tem-se dois niveis:

1o. nivel - BEGIN-D 2o. nivel - PROCEDURE-E

e em relacao ao BEGIN-D, tem-se um nivel:

PROCEDURE-E

15.4. ATIVACAO DE BLOCOS PROCEDURE __________________________________

Ja foi visto que um bloco PROCEDURE e' ativado pelo comando CALL, cuja forma e' (label:) CALL nome-de-entrada; e onde nome-de-entrada e' o label do bloco PROCEDURE a ser ativado.

15. BLOCOS

Page 134

Por exemplo, no exemplo apresentado no EX1C15, no comando de ativacao da procedure PROD, CALL PROD;, na linha 4, PROD e' o nome do bloco procedure, descrito nas linhas 27 a 40 do bloco a que ele pertence, sendo, por conseguinte, um bloco interno. Esse nome indica exatamente o ponto de entrada do bloco PROD e e' chamado de entrada primaria.

Porem, se desejassemos que a entrada se desse nao mais nesse exato ponto, e sim em um outro ponto do bloco, estariamos especificando uma outra en- trada, denominada secundaria, e o nome dessa entrada, alem de aparecer no comando CALL, da mesma forma que foi visto para a entrada primaria, deveria aparecer, identificando o ponto de entrada secundaria, como label de um comando proprio, denominado ENTRY;

Por exemplo:

A:PROC; CALL A; invocando a procedure A pela sua ------ entrada primaria. B:ENTRY; CALL B; invocando a procedure A pela sua ------ entrada secundaria. END A;

Page 105: Manual de PL1 - Completo

Uma ativacao de um bloco pela sua entrada primaria indica que a execucao do bloco se dara' a partir do primeiro comando do bloco; uma ativacao de um bloco pela sua entrada secundaria indica que a execucao do bloco se dara' a partir do primeiro comando apos o comando ENTRY que identifica a entrada secundaria especificada.

Um bloco pode ter mais do que uma entrada secundaria e mais, uma entrada secundaria pode ter mais de um nome, isto e', mais de um label indicativo da mesma entrada. Por exemplo: C: D: E: ENTRY; e o bloco com uma entrada secundaria desse tipo podera' ser ativado por essa entrada de uma das tres maneiras: CALL C; CALL D; ou CALL E;

Vimos que o comando CALL colocado num bloco pode ativar um outro bloco , ou seja, os blocos PROCEDURES, com excecao do principal, que era ativado automaticamente pelo sistema operacional, eram ativados por outros blocos e por meio do comando CALL colocados nesses outros blocos. Porem nao sao todos os blocos que podem ser ativados por qualquer outro bloco. A regra e' muito simples: "Uma procedure pode invocar qualquer procedure, desde que elas sejam externas, uma em relacao a outra. Se a procedure invocada for interna a procedure invocante, ela devera' estar no nivel imediatamente abaixo ao da procedure invocante. E uma procedure que nao seja interna a nenhuma outra pode ser invocada por qualquer procedure."

Apenas como instrucao, um caso especial na linguagem e' o uso do atributo RECURSIVE, que faz com que uma procedure seja invocada por ela mesma. Esse recurso e' muito usado no calculo do fatorial de um numero, por exemplo: .cb

FAT:PROC(N) RECURSIVE RETURNS(FIXED); DCL N FIXED; IF N LE 1 THEN RETURN(1);

15. BLOCOS

Page 135

ELSE RETURN(N*FAT(N-1)); END FAT;

Esse exemplo devera' ser revisto pelo leitor apos o Cap. 16, pois se trata de uma PROC-funcao, com passagem de valores por meio de parametro.

15.5. ATRIBUTOS INTERNAL E EXTERNAL ___________________________________

O modo pelo qual um identificador e' conhecido no bloco em que foi decla- rado e nos blocos internos a esse bloco e' dado pelo atributo INTERNAL automaticamente declarado pelo compilador PL/I.

No entanto, se se desejar que um ou varios identificadores sejam conhecidos em blocos, nao necesariamente internos ao bloco em que eles tenham sido declarados, dever-se-a' usar o atributo EXTERNAL, e, nesse caso, todos os blocos que forem usar o referido identificador deverao conter a declaracao do identificador com a opcao EXTERNAL.

Os atributos INTERNAL e EXTERNAL podem ser abreviados por INT e EXT, res- pectivamente.

O compilador PL/I declara automaticamente o atributo EXTERNAL para os nomes-de-entrada de blocos PROCEDURE (entrada primaria e entrada secunda- ria).

Um importante fato e' que um identificador declarado com o atributo EX- TERNAL nao podera ter mais de 7 (sete) caracteres na composicao de seu nome, dai o fato de um nome de um procedimento (PROCEDURE) nao poder ter

Page 106: Manual de PL1 - Completo

mais de 7 caracteres, conforme foi visto quando foram apresentadas as regras de criacao de nomes para identificadores.

Entao, uma variavel assim declarada: DCL 1 A EXT, 2 B, 2 C; podera' ser usada em qualquer bloco, mantendo os mesmos atributos e valores, se nos blocos for usada a mesma declaracao.

Por exemplo:

A:PROC; B:PROC; DCL XYZ BIT(1) EXT; DCL (PQR,XYZ) BIT(1) EXT; -------- --------- END A; END B;

supondo-se que o identificador PQR seja usado em uma outra PROC.

15. BLOCOS

Page 136

15.6. APLICACOES ________________

1) Programa para determinar e imprimir a data e a hora, em um determinado instante, usanto as built-in functions DATE e TIME.

EX2C15: PROC OPTIONS(MAIN); DCL XDATA CHAR(8), XHORA CHAR(15); CALL DATHOR; PUT EDIT('DATA',XDATA,'HORAS',XHORA) (SKIP(5),COL(10),(2)(A,X(2)),X(3),(2)(A,X(2))); DATHOR: PROC; DCL DATA CHAR(6), HORA CHAR(9); DATA = DATE; HORA = TIME; DO I=1,3,5; IF SUBSTR(DATA,I,1)='0' THEN SUBSTR(DATA,I,1)=' '; IF SUBSTR(HORA,I,1)='0' THEN SUBSTR(HORA,I,1)=' '; END; XDATA = SUBSTR(DATA,5,2) CAT '/' CAT SUBSTR(DATA,3,2) CAT '/' CAT SUBSTR(DATA,1,2); XHORA = SUBSTR(HORA,1,2) CAT 'H' CAT SUBSTR(HORA,3,2) CAT 'M' CAT SUBSTR(HORA,5,2) CAT ',' CAT SUBSTR(HORA,7,3) CAT 'S'; END DATHOR; END EX2C15;

Esse programa apresentaria como saida o seguinte:

DATA 19/ 9/76 HORAS 21H 55M 3,950S

se fosse corrido no dia 19 de setembro de 1976, as 21 horas, 55 minutos e 3 seguntos (os 950 milesimos do segundo nao temos condicao de observar).

2) Programa para classificar uma colecao de valores relativos a nomes e codigo de identidade, em que cada nome esta' subdividido em tres partes: primeiro, meio e ultimo, segundo o codigo de identidade.

Essa colecao devera' ser lida de cartoes perfurados, podendo ou nao estar em ordem crescente, segundo o campo de codigo de identificacao.

Page 107: Manual de PL1 - Completo

A colecao devera' conter no maximo 10 codigos com seus respectivos nomes.

EX3C15: PROC OPTIONS(MAIN); DCL 1 CARTAO(10) ,2 NUMERO FIXED(4) ,2 NOME

15. BLOCOS

Page 137

,3 PRIMEIRO CHAR(10) ,3 MEIO CHAR(20) ,3 ULTIMO CHAR(10) ,XAV_FIM BIT(1) INIT('1'B) ; ON ENDFILE(SYSIN) XAV_FIM = '0'B; DO I = 1 TO 10 WHILE(XAV_FIM); GET LIST(CARTAO(I)) COPY; END; IF XAV_FIM THEN I = 10; ELSE I = I - 1; CALL SORT; PUT SKIP(5); DO J = 1 TO I; PUT EDIT(CARTAO(J)) (COL(1),F(5),X(2),A(11),A(21),A(11)); END; SORT: PROC; DCL IND BIT(1) ,1 TROCA LIKE CARTAO ; DO K = I TO 1 BY -1; IND = '1'B; DO J = 2 TO K; IF CARTAO(J).NUMERO LT CARTAO(J - 1).NUMERO THEN DO; IND = '0'B; TROCA = CARTAO(J); CARTAO(J) = CARTAO(J - 1); CARTAO(J - 1) = TROCA; END; END; IF IND THEN GOTO FIM; END; FIM: END SORT; END EX3C15;

Se tivermos, como dados de entrada, os valores abaixo:

1o. cartao 110 'AAAAAAAAAA' 'AAAAAAAAAA' 'AAAAA' 2o. cartao 1300 'AAAAAAAAAA' 'AAAAAAAAAA' 'AAAAA' 3o. cartao 130 'BBBBBBBBBB' 'BBBBBBBBBB' 'BBBBB' 4o. cartao 105 'CCCCCCCCCCC' 5o. cartao 'CCCCCCCCCC' 'CCCCC' 6o. cartao 101 'DDDDDDDDDD' 'DDDDDDDDDD' 'DDDDD' 7o. cartao 120 'EEEEEEEEEE' 'EEEEEEEEEE' 'EEEEE'

onde os valores sao perfurados da maneira mais livre possivel, mantendo-se apenas a ordem dos itens elementares da estrutura, teremos a seguinte saida impressa:

Page 108: Manual de PL1 - Completo

15. BLOCOS

Page 138

110 'AAAAAAAAAA' 'AAAAAAAAAA' 'AAAAA' 1300 'AAAAAAAAAA' 'AAAAAAAAAA' 'AAAAA' 130 'BBBBBBBBBB' 'BBBBBBBBBB' 'BBBBB' 105 'CCCCCCCCCC' 'CCCCCCCCCC' 'CCCCC' 101 'DDDDDDDDDD' 'DDDDDDDDDD' 'DDDDD' 120 'EEEEEEEEEE' 'EEEEEEEEEE' 'EEEEE' (puladas 5 linhas) 101 DDDDDDDDDD DDDDDDDDDD DDDDD 105 CCCCCCCCCC CCCCCCCCCC CCCCC 110 AAAAAAAAAA AAAAAAAAAA AAAAA 120 EEEEEEEEEE EEEEEEEEEE EEEEE 130 BBBBBBBBBB BBBBBBBBBB BBBBB 1300 AAAAAAAAAA AAAAAAAAAA AAAAA

3) Essa aplicacao evidencia o uso de um bloco BEGIN como tecnica de con- trole no dimensionamento variavel de Arrays.

Outras tecnicas de dimensionamento variaveis sao encontradas no topico 6, do Cap.17.

O programa a seguir se propoe a,lendo e imprimindo uma colecao de valo- res, calcular e imprimir a soma e a media desses valores. Como ponto de partida e' lido a quantidade de valores a serem usados no programa (variavel N).

EX3C15: PROC OPTIONS(MAIN); GET LIST(N); BEGIN; DCL VALORES(N); GET LIST(VALORES); PUT LIST(VALORES); PUT SKIP(2) LIST('TOTAL=',SUM(VALORES)); PUT SKIP(2) LIST('MEDIA=',SUM(VALORES/N)); END;

15. BLOCOS

Page 139

END EX3C15;

Page 109: Manual de PL1 - Completo

15. BLOCOS

Page 140

16. SUBPROGRAMAS ________________

16.1. SUB-ROTINAS E FUNCOES ___________________________

Sub-rotinas e funcoes nada mais sao que os blocos vistos no capitulo anterior (apenas os blocos PROCEDURE).

Na verdade, quando criamos um bloco num programa, estamos criando uma rotina que, dentro da logica do problema, sera' executada varias vezes, evitando-se, assim, que esse trecho que compreende a rotina seja repro- gramado nos varios pontos do programa onde ele seria exigido.

Por exemplo, dada uma colecao de valores, se desejassemos calcular a soma desses valores e a media dos mesmos, imprimindo os valores, a soma e a media; em seguida calcular a soma dos desvios desses valores em relacao 'a media e a media desses novos valores (desvios), imprimindo os desvios, a soma e a media; em seguida calcular a soma dos desvios determinados, ao quadrado, e a media desses novos valores, imprimindo esses valores (des- vios ao quadrado), a soma e a media e, finalmente, repetir os calculos para os desvios elevados 'a terceira potencia, tambem imprimindo esses ultimos valores, sua soma e sua media, teriamos que repetir a programacao que calcularia a soma de uma serie de valores e a media desses valores 4 vezes, certo? Pois bem, e' exatamente para se evitar esse tipo de coisa que se usa o recurso de programar esses calculos em forma de bloco PROCEDURE, e, no momento necessario, ativa-lo segundo o comando CALL. Dai a denominacao de sub-rotina, devido ao fato de estarmos, dentro de uma rotina (procedure principal ou uma outra procedure), usando uma sub- rotina para se fazer um determinado processamento, que normalmente e' re- petido varias vezes.

Agora, nem sempre uma sub-rotina e' feita por ela representar um processamento que se repetira' varias vezes no programa. 'As vezes ela sera' processada apenas uma vez e, tambem, pode nem ser processada. Tal procedimento e' explicado quando estamos trabalhando com modulos de pro- gramas, utilizando os recursos de alocacoes dinamicas ou de tecnicas de "overlay", em que cada modulo e' representado por uma ou mais sub- rotinas.

E' a chamada programacao modular e que nao faz parte desta apresentacao. Mais adiante veremos exemplos desses casos abordados nesses primeiros paragrafos, ou seja: a) programa com varios processamentos repetidos; b) programa com blocos sendo executados varias vezes; e c) programas com blocos que nao sao executadas nem uma vez numa determinada rodada.

Quando vimos o atributo EXTERNAL, aprendemos que as variaveis, quando de- claradas com esse atributo, representavam valores que, armazenados em uma area 'a parte, podiam ser usados em varios blocos, bastando, para isso, que cada bloco que fosse usa-las contivesse a declaracao das mesmas com o

Page 110: Manual de PL1 - Completo

atributo.

Assim, uma variavel manipulada num bloco era passada para outro bloco por meio dessa area comum usada pelo atributo EXTERNAL. Esse mecanismo

16. SUBPROGRAMAS

Page 141

constitui o primeiro modo de passar valores de um bloco para outro, quando esses blocos sao externos, e e' com base exatamente nesse meca- nismo que temos o conceito de SUB-ROTINA e FUNCAO para um bloco PROCEDURE:

® Diz-se que um bloco PROCEDURE e' uma SUB-ROTINA quando, ao ser passado um ou varios valores, ele retorna um ou varios valores, independentemente.

® Diz-se que um bloco PROCEDURE e' uma funcao quando, ao ser passado um ou varios valores, ele retorna apenas um valor.

Os valores passados e retornados para uma sub-rotina sao obtidos por meio de variaveis com atributo EXTERNAL, servindo assim, esse atributo, nao so' para uso de variaveis comuns em blocos externos, como tambem para passagem de valores de ou para sub-rotinas.

No caso das FUNCOES, repete-se todo esse mecanismo, porem somente em relacao aos valores (ou valor) passados para a FUNCAO, uma vez que o va- lor, e somente um valor, e' retornado da FUNCAO para o bloco de ativamento da funcao, pelo proprio nome da funcao.

Temos, pois, nesse momento, mais uma diferenca entre SUB-ROTINA e FUNCAO, que e' a maneira de ativacao dos referidos blocos:

® Uma sub-rotina e' ativada pelo comando CALL nome-de-entrada;

® Uma funcao e' ativada pelo uso do seu proprio nome em um comando.

Como exemplo de ativacao de um bloco sub-rotina, podemos reportar-nos a qualquer um dos exemplos vistos sobre bloco, internos ou externos, no ca- pitulo anterior. E, como exemplo de ativacao de um bloco funcao, podemos reportar-nos a qualquer um dos exemplos vistos sobre Built-in Function, no Cap.9, mas especificamente 'as built-in sem argumentos, enquadrando-se perfeitamente na teoria apresentada ate' aqui.

As built-in com argumentos, porem, tambem sao exemplos de ativacao de FUNCOES, e, por apresentarem lista de argumentos, introduzem um novo conceito no nosso estudo de sub-rotinas e funcoes, que e' o uso de parametros e de argumentos.

16.2. PARAMETROS E ARGUMENTOS _____________________________

Convencionando-se que a lista de parametros sao as variaveis que aparecem entre parenteses apos a palavra PROCEDURE, em uma sub-rotina ou funcao, e que a lista de argumentos sao as variaveis que aparecem entre parenteses apos o nome da PROCEDURE, no comando CALL (para sub-rotina) ou apos o nome da PROCEDURE num comando executavel (para funcao), pode-se entender como argumentos as variaveis do programa invocante que passarao e/ou receberao valores para a sub-rotina ou que apenas passarao valores para a funcao; e como parametros as variaveis da rotina (sub-rotina ou funcao)

16. SUBPROGRAMAS

Page 142

que receberao e/ou passarao valores para o programa invocante (sub- rotina), ou que apenas receberao valores do programa invocante (funcao).

Page 111: Manual de PL1 - Completo

As listas de argumentos e de parametros estao univocamente relacionadas, isto e', as variaveis da lista de argumentos correspondem uma a uma 'as variaveis da lista de parametros, na exata ordem de aparecimento das mesmas.

As variaveis que entrarem na lista de argumentos ou de parametros nao poderao conter o atributo EXTERNAL. O uso do atributo EXT e' mutuamente exclusivo com o uso de listas de argumentos e parametros, naquelas variaveis.

E, como ultima diferenca entre SUB-ROTINA e FUNCAO, temos o uso do co- mando RETURN (expressao), de uso obrigatorio nas funcoes, e o comando RETURN, de uso opcional nas sub-rotinas.

16.3. PARAMETROS/ARGUMENTOS E ATRIBUTO "EXTERNAL" _________________________________________________

Veremos, a seguir, dois exemplos de uso de sub-rotina e funcao, puramente didaticos apenas para melhor esclarecimento a respeito de passagem de va- lores atraves de variaveis com atributo EXTERNAL e atraves de variaveis pertencentes 'as listas de argumentos e de parametros, como tambem a respeito de ativacao dos blocos e uso do comando RETURN na sub-rotina e do comando RETURN (expressao) na funcao.

COM PARAMETROS E COM ATRIBUTO ARGUMENTOS (I) EXTERNAL (II) SUBFUN: SUBFUN: PROC OPTIONS(MAIN); PROC OPTIONS(MAIN); DCL (VAL1,VAL2,VAL3) DCL (VAL1,VAL2,VAL3) FLOAT(5); FLOAT(5) EXTERNAL; GET DATA(VAL1,VAL2,VAL3); GET DATA(VAL1,VAL2,VAL3); CALL SOMAPRD(VAL1,VAL2, CALL SOMAPRD(SOMA,PROD); VAL3,SOMA,PROD); PUT LIST(SOMA,PROD); PUT LIST(SOMA,PROD); SOM = SOMAR; SOM = SOMAR(VAL1,VAL2, PUT SKIP(2); VAL3); PUT LIST('SOMA =',SOM); PUT SKIP(2); END SUBFUN; PUT LIST('SOMA =',SOM); END SUBFUN;

SOMAPRD: SOMAPRD: PROC(X,Y,Z,A,B); PROC(A,B); DCL (X,Y,Z) FLOATS(5); DCL (VAL1,VAL2,VAL3) A = X + Y + Z; FLOAT(5) EXTERNAL; B = X * Y * Z; A = VAL1 + VAL2 + VAL3; RETURN; B = VAL1 * VAL2 * VAL3; END SOMAPRD; END SOMAPRD;

SOMAR: SOMAR: PROC(A,B,C); PROC;

16. SUBPROGRAMAS

Page 143

DCL (A,B,C) FLOAT(5); DCL (VAL1,VAL2,VAL3) RETURN(A+B+C); FLOAT(5) EXTERNAL; END SOMAR; RETURN(VAL1+VAL2+VAL3); END SOMAR;

O leitor podera', revendo todo o material teorico sobre o assunto apresentado, seguir passo a passo esses dois exemplos e conferir todo o exposto, como parte de um excelente exercicio sobre o assunto, observando as variaveis parametros, as variaveis argumentos, os comandos RETURN e RETURN (expressao), as variaveis com atributo EXT etc.

Apenas um detalhe tera' que ser explicado: o fato da funcao ser usada sem

Page 112: Manual de PL1 - Completo

lista de parametros. Quando isso tiver de acontecer, como no caso apresentado, sera' preciso declarar o nome da funcao (SOMAR) no bloco in- vocante com o atributo ENTRY, ou seja, DCL SOMAR ENTRY (e' a declaracao que esta' faltando na procedure SUBFUN, no EX.II).

Note-se que tal fato so' acontece em caso de FUNCAO, devido ao seu uso, ou, melhor dizendo, devido 'a sua ativacao no bloco invocante, que e' apenas usando seu nome em um comando executavel. O compilador PL/I, ao encontrar um comando, como no EX.II, SOM = SOMAR; se nao tiver sido de- clarado que o identificador SOMAR e' uma entrada externa (atributo ENTRY), interpretara' o comando como um simples comando de atribuicao, no qual o valor da variavel denominada SOMAR estara' sendo atribuido 'a variavel denominada SOM.

Ja' no caso de SUB-ROTINA, tal fato nao acontece, pois seu uso se da' atraves do comando CALL, nao havendo condicao de duvidas para o compi- lador, uma vez que o nome que aparece apos a palavra-chave CALL, nu co- mando de ativacao de blocos PROCEDURE, tendo ou nao lista de argumento ,so' podera' indicar um nome-de-entrada.

Voltando ao caso dos argumentos e parametros, os identificadores correspondentes das listas de argumentos e de parametros tem que ter os mesmos atributos, a ponto de ser preciso usar ate' constantes de mesmo tipo, nao so' em base, escala, como tambem em precisao, ao se passar com argumento para uma sub-rotina ou funcao; por exemplo:

16. SUBPROGRAMAS

Page 144

CONST:PROC(X,Y,L); DCL (A,B) FIXED(4);

DCL (X,Y,L) FIXED(4); _________

__________ CALL CONST(A,B,0004);

END CONST; _________

um comando do tipo CALL(A,B,4); daria erro, pois a constante 4, colocada na lista de argumentos, tem atributos DEC FIXED(1), nao sendo coerente com o atributo do elemento correspondente na lista de parametros,que e' o identificador L, cujos atributos sao DEC FIXED(4).

16.4. TIPOS DE ELEMENTOS NAS LISTAS DE ARGUMENTOS E DE PARAMETROS _________________________________________________________________

Com esse ultimo exemplo, vimos que os elementos na lista de argumentos nem sempre deverao ser identificadores, podendo ser constante , como nesse caso, a constante 4 sendo passada para o identificador L, variavel simples.

Na verdade, o que acontece e' o seguinte: na lista de parametros, todos os elementos sempre terao que ser identificadores (variaveis simples, arrays ou estruturas, ou ainda labels); na lista de argumentos, os ele- mentos poderao ser identificadores ( como os mencionados), constantes (como o caso anteriormente visto), nomes de funcoes e expressoes.

Vejamos um exemplo:

_______

CALL SUB(A+B,NOME1,NOME2,SIN(A-B));

Page 113: Manual de PL1 - Completo

_______

no bloco procedure, denominado SUB, teriamos:

SUB:PROC(X,Y,Z,V) ________

END SUB;

onde os parametros que correspondem aos argumentos do tipo expressoes ou nomes de funcoes sao denominados parametros mudos, e tem que manter a mesma coerencia com os atributos dos seus correspondentes. No caso apresentado, os parametros mudos sao as variaveis X e V que sao coerente com os seus elementos correspondentes: a expressao A+B (retornando um va- lor DEC FLOAT(6)) e a funcao seno (retornando um valor, tambem em ponto flutuante de precisao 6).

16. SUBPROGRAMAS

Page 145

16.5. ATRIBUTOS ENTRY E RETURNS _______________________________

O comando ENTRY, ja' visto anteriormente no caso de FUNCAO sem lista de argumentos, e' tambem usado para se manter a coerencia entre os elementos das listas de argumentos e parametros. Vejamos como. Nem sempr podemos manter essa coerencia apenas pelos atributos declarados automaticamente, como no caso dos resultados da expressao e da funcao seno serem os mesmos que os das variaveis X e Y (parametros mudos) automaticamente.

Por exemplo:

S:PROC(X,Y); DCL S ENTRY(FIXED,FIXED(7)); DCL X FIXED, Y FIXED(7); A = 5; B = 10; Y = Y + X; CALL S(A,B); END S;

Conforme podemos verificar, foi mantida a ordem exata dos parametros, dos argumentos e dos atributos usados no comando ENTRY.

A lista de atributos do comando ENTRY, quando usada, nao precisa ser do mesmo tamanho que a de parametros (ou de argumentos). Como ela tem que corresponder exatamente aos elementos das listas de parametros (ou de ar- gumentos), usa-se uma virgula na posicao referente ao elemento que nao for referenciado, ou entao, se os elementos nao referenciados forem depois da ultima posicao da lista de atributos, esta terminara' exatamente nesse ponto, isto e', nao precisando fazer referencia com "virgulas" a todos os elementos seguintes ao ultimo especificado. Por exemplo:

DCL SS ENTRY(FIXED,,,FLOAT); SS:PROC(A,B,C,J,X,Y,Z); DCL A FIXED, B FLOAT, C FLOAT, J FLOAT;

sendo que as variaveis B, C, X, Y e Z sao declaradas FLOAT(6), ou pelo comando DECLARE ou automaticamente pelo sistema.

Se o elemento for um array, a especificacao sera' feita por meio da indicacao de asteriscos nas dimensoes do array; por exemplo:

DCL SSS ENTRY((*) FIXED,,FLOAT,(*,*) FLOAT); indicando que o 1o. elemento das listas (de argumentos ou de parametros) e' um array de uma dimensao; o 2o. nao tem referencia de atributos; o 3o. e' uma expressao ou uma variavel simples FLOAT(6) DEC; o 4o. e' um array de duas dimensoes cujos elementos sao DEC FLOAT(6); e do 5o. em diante, se existirem, nao ha' re- ferencias de atributos.

Page 114: Manual de PL1 - Completo

Se o elemento for um label, devera' ser feita referencia ao atributo LABEL, na posicao correspondente.

E, finalmente, se o elemento for um nome-de-entrada (nome de uma sub- rotina), devera' ser feita referencia ao atributo ENTRY, na posicao correspondente. Por exemplo:

16. SUBPROGRAMAS

Page 146

DCL A ENTRY; CALL XYZ(X,Y,A);

ou, se quisessemos mudar os atributos:

DCL A ENTRY, XYZ ENTRY(FIXED,BINARY,ENTRY); CALL XYZ(X,Y,A);

Com relacao ao atributo RETURNS, ele e' usado somente em caso de funcoes, quando se deseja mudar o atributo da variavel nome da funcao.

Sabemos que, em uma FUNCAO, a expressao colocada no comando RETURN, co- mando obrigatorio, e' avaliada e seu resultado e' colocado na variavel especificada como nome da funcao, por exemplo: uma funcao que calculasse a soma de tres valores, todos reais, decimais e de ponto flutuante; espera-se que o nome dessa funcao comece por uma letra que nao seja I, J K, L, M ou N, para justamente especificar uma variavel real, decimal e de ponto flutuante com precisao 6, mantendo toda a coerencia possivel. Por exemplo:

OPER:PROC; SOMAR:PROC(A,B,C); GET LIST(X,Y,Z); D=A+B+C; │ ou RETURN SOMA = SOMAR(Z,Y,X); RETURN(D); │ (A+B+C); PUT DATA(SOMA); END SOMAR; END OPER;

a expressao A+B+C sera' avaliada e seu resultado sera' passado para a variavel SOMAR, que e' justamente o nome da FUNCAO. No programa que invocou essa FUNCAO, esse valor sera' atribuido 'a variavel SOMA, mantendo, assim, toda a coerencia possivel entre os atributos das variaveis usadas, ate' mesmo com a que define o nome da funcao, variavel SOMAR.

Mas vamos supor que no programa invocante tivessemos que receber essa soma, nao como um valor decimal de ponto flutuante e sim como um valor binario de ponto fixo, por exemplo; assim, deveriamos usar o atributo RETURNS para fazer essa transformacao, ou seja:

DCL SOMAR RETURNS(BINARY FIXED(4)); no programa invocante SOMAR:PROC(A,B,C) RETURNS(BINARY FIXED(4)); na funcao

Os atributos ENTRY e RETURNS podem ser usados em conjunto:

DCL nome da funcao ENTRY(....) RETURNS(atributo);

16. SUBPROGRAMAS

Page 147

16.6. ATRIBUTO INITIAL CALL ___________________________

E' usado para invocar uma sub-rotina por meio do atributo INITIAL e sua

Page 115: Manual de PL1 - Completo

forma e': INITIAL CALL nome-de-entrada(lista de argumentos).

Vejamos um exemplo: se num programa tivermos a declaracao de um array, por exemplo, e quisermos inicializa-lo, poderemos fazer:

DCL ARRAY(3,4) FIXED INIT CALL INICIAR;

onde INICIAR sera' a seguinte sub-rotina:

INICIAR:PROC; ARRAY(1,1) = 1; ARRAY(1,2) = 2; ARRAY(1,3) = 3; ARRAY(1,4) = 4; ARRAY(2,1) = 1; ARRAY(3,1) = 1; ARRAY(2,2) = 2; ARRAY(3,2) = 2; ARRAY(2,3) = 3; ARRAY(2,4) = 4; ARRAY(3,4) = 4; ARRAY(3,3) = 3; END INICIAR;

O leitor podera' observar que nao ha' necessidade de se construir a sub- rotina mantendo a ordem dos elementos do array.

Essa tecnica e' usada quando se tem uma grande quantidade de valores de inicializacao e se tem, eventualmente, que mudar esses valores ou alguns deles. Para nao ficar alterando o programa, que normalmente ja' esta' pronto e testado, usa-se esse recurso, criando-se uma PROCEDURE (sub- rotina) e fazendo nela as alteracoes necessarias.

16.7. APLICACOES ________________

1. Esta primeira aplicacao e' para exemplificar o caso de um programa com varios processamentos repetidos varias vezes, como os descritos nas linhas nros.: 6 a 12, 16 a 22, 26 a 32 e 36 a 42.

1 EX1C16: 2 PROC OPTIONS(MAIN); 3 DCL VAL(10) 4 ; 5 GET EDIT(VAL) ((10)F(5)); 6 SOMA = 0; 7 DO I = 1 TO 10; 8 SOMA = SOMA + VAL(1); 9 END; 10 XMEDIA = SOMA/10; 11 PUT SKIP EDIT(VAL) ((10)F(5)); 12 PUT SKIP EDIT(SOMA,XMEDIA) (F(10),F(10,3)); 13 DO I = 1 TO 10; 14 VAL(I) = VAL(I) - XMEDIA; 15 END; 16 SOMA = 0;

16. SUBPROGRAMAS

Page 148

17 DO I = 1 TO 10; 18 SOMA = SOMA + VAL(I); 19 END; 20 XMEDIA = SOMA/10; 21 PUT SKIP EDIT(VAL) ((10)F(10,3)); 22 PUT SKIP EDIT(SOMA,XMEDIA) (F(10,3)); 23 DO I = 1 TO 10; 24 VAL(I) = VAL(I) ** 2; 25 END; 26 SOMA = 0; 27 DO I = 1 TO 10; 28 SOMA = SOMA + VAL(I); 29 END; 30 XMEDIA = SOMA/10; 31 PUT SKIP EDIT(VAL) ((10)F(10,3));

Page 116: Manual de PL1 - Completo

32 PUT SKIP EDIT(SOMA,XMEDIA) (F(10,3)); 33 DO I = 1 TO 10; 34 VAL(I) = VAL(I) ** 3; 35 END; 36 SOMA = 0; 37 DO I = 1 TO 10; 38 SOMA = SOMA + VAL(I); 39 END; 40 XMEDIA = SOMA/10; 41 PUT SKIP EDIT(VAL) ((10)F(10,3)); 42 PUT SKIP EDIT(SOMA,XMEDIA) (F(10,3)); 43 END EX1C16;

2. Esta segunda aplicacao e' a transformacao dos processamentos repe- tidos varias vezes, na primeira aplicacao apresentada, por um bloco PROCEDURE, que e' executado varias vezes.

1 EX2C16: 2 PROC OPTIONS(MAIN); 3 DCL VAL(10), XMEDIA FIXED(10,3) 4 ; 5 GET EDIT(VAL) ((10)F(5)); 6 CALL CALCULO; 7 DO I = 1 TO 10; 8 VAL(I) = VAL(I) - XMEDIA; 9 END; 10 CALL CALCULO; 11 DO I = 1 TO 10; 12 VAL(I) = VAL(I) ** 2; 13 END; 14 CALL CALCULO; 15 DO I = 1 TO 10; 16 VAL(I) = VAL(I) ** 3; 17 END; 18 CALL CALCULO; 19 CALCULO: 20 PROC; 21 SOMA = 0; 22 DO I = 1 TO 10;

16. SUBPROGRAMAS

Page 149

23 SOMA = SOMA + VAL(I); 24 END; 25 XMEDIA = SOMA/10; 26 PUT SKIP EDIT(VAL) ((10)F(10,3)); 27 PUT SKIP EDIT(SOMA,XMEDIA) (F(10,3)); 28 END CALCULO; 29 END EX2C16;

O Bloco PROCEDURE descrito nas linhas 19 a 28 e' ativado 4 vezes, por meio do comando CALL (linhas 6, 10, 14 e 18).

3. O programa que se segue se propoe a apresentar um caso em que varios blocos PROCEDURES sao programados e nem sempre sao executados, podendo ate' mesmo nao ser executado nem uma vez. E' o caso de se ter um codigo para indicar o processamento de um deles, ou, se houver um erro nesse codigo, nao processar nenhum.

Assim, baseado no valor do codigo, o programa executara' uma determi- nada rotina. O programa e' puramente didatico.

EX3C16: PROC OPTIONS(MAIN); GET DATA(CODIGO); IF CODIGO = 1 THEN CALL ROTINA1;

Page 117: Manual de PL1 - Completo

ELSE IF CODIGO = 2 THEN CALL ROTINA2; ELSE IF CODIGO = 3 THEN CALL ROTINA3; ELSE IF CODIGO = 4 THEN CALL ROTINA4; ELSE PUT SKIP LIST('ERRO NO CODIGO'); ROTINA1: PROC; (comandos); END ROTINA1; ROTINA2: PROC; (comandos); END ROTINA2; ROTINA3: PROC; (comandos); END ROTINA3; ROTINA4: PROC; (comandos); END ROTINA4; END EX3C16;

4. O problema que se segue constitui uma aplicacao de uma Procedure tipo FUNCAO, externa 'a procedure invocante.

16. SUBPROGRAMAS

Page 150

EX4C16: PROC OPTIONS(MAIN); DCL (X,Y,Z) FLOAT ; GET LIST(X,Y,Z); Z = Z + 3 * CONT(X,X+Y+10); PUT SKIP(5) DATA(Z); END EX4C16; CONT: PROC(A,B); DCL (A,B) FLOAT ; IF A LE B THEN RETURN(B-A); ELSE RETURN(A-B); END CONT;

________________ Para uma entrada formada pelos valores / 10 20 30 │ │________________│

_________________ │ │ obteremos a seguinte saida: │ Z= 1.200000E+02;│ │________________/

5. Uso de "procedures" externas (sub-rotina e funcao) e dos atributos ENTRY e RETURNS.

EX5C16: PROC OPTIONS(MAIN); DCL SUB ENTRY(FIXED,,BINARY,BINARY) ,SS ENTRY RETURNS(BINARY) ; GET LIST(A,B); CALL SUB(A,B,C,SS);

Page 118: Manual de PL1 - Completo

PUT SKIP EDIT(A,B,C)(F(6,2)); END EX5C16; SUB: PROC(X,Y,Z,W) DCL X FIXED,(W,Z) BINARY ; Z=X+Y+W; END SUB; SS: PROC RETURNS(BINARY); GET LIST(A,B); RETURN(A+B); END SS; Sendo os dados de entrada constituidos pelos valores: ____________________________

16. SUBPROGRAMAS

Page 151

/ │ │10.0 10.0 5.5 4.5 │ │_____________________________│ obtem-se a seguinte saida impressa: ____________________________ │ │ │ b10.00b20.00b30.00 │ │ / │__________________________/

16. SUBPROGRAMAS

Page 152

17. ALOCACAO DE MEMORIA _______________________

17.1. INTRODUCAO ________________

Existem quatro diferentas modalidades para se alocar memoria para identificadores em programas PL/1.

Essas alocacoes podem ocorrer "estaticamente", ou seja,antes da execucao do bloco,ou "dinamicamente", durante a execucao do bloco a que os iden- tificadores pertencem.

As quatro modalidades sao definidas por meio dos atributos: STATIC , AUTOMATIC , CONTROLLED E BASED na declaracao dos identificadores no co- mando DECLARE.

O atributo STATIC constitui o tipo de alocacao "estatica" e os outros

Page 119: Manual de PL1 - Completo

tres, AUTOMATIC , CONTROLLED e BASED, constituem o tipo de alocacao "dinamica".

A declaracao automatica do sistema e' para a alocacao dinamica, no atributo AUTOMATIC, com excecao dos identificadores que tiverem atributo EXTERNAL e que forem label de PROCEDURE, que serao STATIC.

Veremos, a seguir, cada um desses atributos.

17.2. STATIC ____________

Os identificadores designados com esse atributo mantem suas alocacoes permanentemente durante toda a execucao do bloco do qual eles fazem parte.

Vejamos um exemplo do uso desse atributo:

ESTATIC: PROC; ----- ----- DCL CONT FIXED STATIC INIT(0); ----- ----- PUT LIST(CONT); ----- CONT = CONT + 10; ----- END ESTATIC;

Na primeira vez que essa "procedure",denominada ESTATIC, for invocada a variavel CONT sera' inicializada com o valor zero e, apos retornar ao

17. ALOCACAO DE MEMORIA

Page 153

bloco qua a ativou, a variavel CONT contera' o valor 10, por forca do co- mando CONT=CONT+10. Apos uma segunda chamada dessa PROC, essa variavel saira' com o valor 20 e assim sucessivamente, de 10 em 10, para cada cha- mada da PROC.

Conforme o leitor pode verificar, o atributo INITIAL so' tem efeito na primeira chamada da PROC e a partir dai' a variavel CONT contera' sempre seu ultimo valor. Essa variavel ficara' sempre alocada na memoriA enquanto o bloco principal estiver ativado. E' o efeito do atributo STATIC ( alocacao estatica ).

17.3. AUTOMATIC _______________

As variaveis possuidoras desse atributo somente mantem suas alocacoes enquanto o bloco a que elas pertencem permanece ativo.

No exemplo dado no caso anterior, da procedure ESTATIC, se tirassemos o atributo STATIC da variavel CONT, a essa variavel seria dado, automatica- mente, o atributo AUTOMATIC e ela seria inicializada com o valor zero sempre que a procedure fosse ativada (uso do comando CALL).

17.4. CONTROLLED ________________

As variaveis possuidoras desse atributo tem suas alocacoes controladas por dois comandos: o comando ALLOCATE e o comando FREE,o primeiro para alocar a variavel e o segundo para liberar a variavel.

Page 120: Manual de PL1 - Completo

ALLOCATE variavel, variavel, ....,variavel; FORMAS FREE variavel,variavel, .....,variavel;

O atributo CONTROLLED, que se abrevia por CTL, e' sempre usado em combinacao com os comandos ALLOCATE e FREE, principalmente com o primeiro. Quando se usa o comando ALLOCATE (para uma variavel com atri- buto CTL) a alocacao permanece ativa durante todo o tempo que o bloco a que a variavel pertence tambem ficar ativo.

Uma vez desativado o bloco, essa alocacao sera' liberada, nao precisando, pois, do uso do comando FREE, o qual e' usado somente quando se desejam fazer varias alocacoes para a mesma variavel, onde o acesso 'as alocacoes anteriores so' sera' permitido com o uso do comando FREE, para liberar a ultima alocacao feita.

Vejamos alguns exemplos:

17. ALOCACAO DE MEMORIA

Page 154

CONTROL:PROC; ALLOC:PROC; ----- DCL A CTL; ----- ----- DCL A(10) CTL, B CTL; ALLOCATE A; ----- A = B + C; ALLOCATE A; ----- ----- ALLOCATE A; ALLOCATE B; A = C + D; ----- PUT DATA(A); FREE A; FREE A; ----- PUT DATA(A); ALLOCATE A; ----- ----- FREE A; END CONTROL; PUT DATA(A); = = = =

No segundo exemplo, o primeiro comando PUT DATA(A); imprimira' o valor de C + D para a variavel A. No segundo comando PUT DATA(A); imprimira' o valor de B + C para a variavel A, pois o comando anterior FREE A; liberou a ultima alocacao feita. E no terceiro comando PUT DATA (A); nao havera' mais alocacao para a variavel A, podendo ser impresso um valor qualquer existente na memoria, se for numerico, ou entao, se for um valor alfabetico, dara' mensagem de erro, porque o segundo comando FREE A; liberou a primeira alocacao feita para a variavel A.

Esse atributo e' muito usado para se controlar comprimento de variavel 'string' como tambem para se controlar dimensionamento de array

Vejamos alguns exemplos desses casos.

17.5. CONTROLE NO COMPRIMENTO DE "STRINGS" __________________________________________

Podemos especificar um comprimento constante ou variavel para um string e por meio do comando ALLOCATE alocar essa variavel na memoria de acordo com as nossas necessidades, por exemplo:

----- ----- DCL A CHAR(10) CTL; DCL A CHAR(10) VAR CTL; ----- ----- ALLOCATE A; ALLOCATE A CHAR(5); ----- -----

Ou ainda usando uma variavel como indicativa do comprimento do string ou usando um asterisco:

Page 121: Manual de PL1 - Completo

----- ----- DCL C CHAR(M) CTL; DCL C CHAR(*) CTL; ----- -----

17. ALOCACAO DE MEMORIA

Page 155

M = 10; ALLOCATE C CHAR(10); ALLOCATE C; ----- -----

17.6. CONTROLE NO DIMENSIONAMENTO DE ARRAYS ___________________________________________

E' o uso, semelhante ao visto, para o caso de comprimento de strings ape- nas, com as alternativas feitas nas dimensoes do array, isto e', o uso de variavel, o uso do asterisco ou o uso da constante no array com atributo CONTROLLED.

Vejamos alguns exemplos:

----- ----- DCL B(N) CTL; DCL B(*,*) CTL; ----- ----- N = 10; J = 15; ALLOCATE B; ALLOCATE B(J,5); ----- -----

O programa apresentado a seguir se propoe a determinar o produto matricial para quaisquer matrizes dadas, mantendo, e' claro, as exigen- cias teoricas sobre produto matricial (o numero de elementos da segunda dimensao da primeira matriz e' igual ao numero de elementos da primeira dimensao da segunda matriz, dando uma matriz com o mesmo numero de linhas que a primeira e o mesmo numero de colunas que a segunda).

E' um exemplo classico do uso do atributo CONTROLLED usado em variaveis ARRAYS.

17. ALOCACAO DE MEMORIA

Page 156

EX1C17: PROC OPTIONS(MAIN); DCL (A(*,*), B(*,*), C(*,*)) FIXED(2) CTL ; GET DATA(N,M,L); ALLOCATE A(N,M), B(M,L), C(N,L); GET LIST(A,B); PUT EDIT(N,M,M,L,N,L)(SKIP,6 f(2)); DO I = 1 TO N; DO K = 1 TO L; C(I,K) = SUM(A(I,*)*B(*,K)); END; END; PUT SKIP(2) EDIT(A)(F(2)); PUT SKIP(2) EDIT(B)(F(2)); PUT SKIP(2) EDIT(C)(F(3)); END EX1C17;

Page 122: Manual de PL1 - Completo

ENTRADA: __________________________________________ / / N=2, M=3, L=2; 1 1 1 1 1 1 2 2 2 2 2 2 │ │

SAIDA: ________________________________________ │ 2 3 3 2 2 2 │ 1 1 1 1 1 1 │ 2 2 2 2 2 2 │ 6 6 6 6 6 6 │

O leitor podera' relembrar nesse programa o uso da BUILT-in SUM e o uso do Cross-section em array (asterisco).

17.7. BUILT-IN ALLOCATION _________________________

E' usada para se saber se foi alocada memoria para a variavel de atributo CTL ou nao.

Sua forma e' ALLOCATION(x), onde x e' o nome da variavel CONTROLLED.

Essa funcao apresenta como resultado um "string" de bits de comprimento 1, de valor '1'B, se a variavel x esta' alocada, e de valor '0'B, se a variavel x nao esta' alocada.

17. ALOCACAO DE MEMORIA

Page 157

17.8. BASED ___________

As variaveis possuidoras desse atributo sao regidas por mecanismo do tipo das variaveis com o atributo CTL, ou seja, elas dependem do uso de uma variavel denominada POINTER, variavel essa que tera' o endereco de memo- ria da variavel BASED associada a ela. Isto e', enquanto nao colocarmos o endereco em seu conteudo, nao poderemos trabalhar com essas variaveis BASED, a exemplo das variaveis CONTROLLED, com as quais poderiamos trabalhar enquanto nao usassemos o comando ALLOCATE.

Uma variavel BASED e' sempre declarada com uma variavel POINTER, por exemplo: DCL C BASED(D); onde C e' a variavel que tera' o atributo BASED e D e' o POINTER associado a ela.

Pode-se tambem declarar uma variavel como sendo POINTER, simplesmente co- locando essa palavra adiante do nome da variavel; por exemplo: DCL D POINTER;

Agora um detalhe: o fato de se declarar uma variavel POINTER, como foi visto, nao elimina o uso dessa variavel entre parenteses, na declaracao da variavel BASED que sera' associada. Veremos que uma declaracao de variavel POINTER e' para ela ser associada a outras variaveis, durante o programa, sem ser necessariamente aquela que foi declarada como BASED. O que acontece na realidade e' que, quando declaramos uma variavel BASED, a variavel POINTER especificada nao precisa ser declarada a parte, pois ela e' automaticamente declarada, pelo simples aparecimento no comando DECLARE (diz-se que foi declarada implicitamente).

17.8.1. VARIAVEIS POINTER

Seja um array denominado C cuja declaracao e' dada pelo seguinte comando:

Page 123: Manual de PL1 - Completo

DCL C(10) CHAR(40);

Cada elemento desse array e' identificado pelo nome do array e seu correspondente subscrito, por exemplo: C(1), C(2), ... C(10), represen- tando o primeiro, segundo, ..., decimo elemento, respectivamente Pois bem, como cada elemento ocupa 40 bytes de memoria, se o primeiro elemento ocupar a posicao 1000 de memoria, poderemos referir-nos aos demais ele- mentos pelos enderecos: 1040 para o segundo, 1080 para o terceiro, 1120 para o quarto e assim por diante, ate' o decimo elemento. Esses enderecos, chamados enderecos absolutos, especificam, entao, as alocacoe atuais de memoria do array denominado C.

PL/1 permite que esses enderecos absolutos possam ser atribuidos a um tipo especial de variaveis, que sao as variaveis POINTER. Assim uma variavel POINTER tem como valor um endereco absoluto de alguma variavel.

DCL P POINTER; DCL (Q,R,S) POINTER EXTERNAL; DCL 1 EST, 2 X CHAR(10), 2 H POINTER, 2 Z(-6:6) POINTER;

17. ALOCACAO DE MEMORIA

Page 158

17.8.2. BUILT-IN "ADDR" E "NULL"

Antes que uma variavel declarada como sendo POINTER (exemplos apresentados) possa ser manipulada, e' preciso atribuir-lhe um valor de um endereco absoluto, o que e' feito pelo uso de uma das built-in function ADDR ou NULL.

O valor retornado pela funcao ADDR(x) e' o endereco absoluto da variavel especificada em seu argumento. Por exemplo:

DCL P POINTER, A FIXED(7); P = ADDR(A);

Apos a execucao desses comandos, em P havera' o valor do endereco abso- luto da variavel A.

A referencia pela funcao NULL (essa nao tem argumento) faz com que a variavel POINTER contenha um valor que nao identifique alocacao alguma de memoria. E' como se fosse um endereco nulo. E' usada para limpar variaveis pointers e para testar memoria nao alocada.

Como argumento de uma funcao ADDR pode-se ter uma variavel de elemento, um array, um elemento de array, uma estrutura ou subestrutura e um ele- mento de estrutura.

17.8.3. COMANDOS DE ATRIBUICAO PARA POINTERS

Podemos ter comandos de atribuicao usando variaveis pointer onde so' sao permitidos os seguintes casos:

1) variavel pointer = variavel pointer 2) variavel pointer = funcao ADDR(x) ou NULL 3) array pointer = array pointer 4) elemento de array pointer = elemento de array pointer 5) elemento de array pointer = variavel pointer 6) elemento de array pointer = funcao ADDR ou NULL 7) variavel pointer = elemento de array pointer

Podemos ter do lado esquerdo mais de uma variavel pointer, sendo que, nesse caso, deverao estar separadas por virgulas.

17. ALOCACAO DE MEMORIA

Page 124: Manual de PL1 - Completo

Page 159

Exemplos: P= ADDR(B); P= T(2); A.X=P; T.Q,A.X=P; Q,R=NULL; R=T.Q;onde to- das as variaveis usadas sao variaves pointers, com excecao da variavel B, argumento da funcao ADDR que pode nao ser pointer.

17.8.4. EXPRESSOES COM POINTERS

Podemos usar somente dois operandos em expressoes com variaveis pointers, que sao: o igual e o nao igual.

Por exemplo:

IF (P=NULL) OR (Q NE ADDR (C)) THEN GOTO L; B = (P NE Q); IF R = NULL THEN C = A;

onde A,B e C sao variaveis aritmeticas e P,Q e R sao variaveis pointer.

17.8.5. VARIAVEIS BASED

Por meio de uma variavel pointer pode-se, por exemplo, especificar o endereco absoluto de um array A, mas nao se tem condicao de se saber algo a respeito de sua dimensao nem tampouco de seus atributos.

Para isso a linguagem PL/1 prove um tipo especial de variavel, denominado variavel BASED, cuja forma de declaracao e':

___________________________________ │ │ │ variavel atributos BASED(pointer) │ │___________________________________│

Por exemplo: DCL C CHAR(10) BASED(Q); declara a variavel C, com 10 posicoes de string de caracteres, associada 'a variavel pointer Q.

A simples declaracao de uma variavel BASED nao atribui endereco 'a variavel pointer associada a ela, isto e', no exemplo dado anteriormente a variavel pointer Q nao tem ainda o endereco da variavel string de ca- racteres C.

O comando C = 'AULA'; faz com que o string de caracteres 'AULA' seja atribuido 'as 10 posicoes de area de memoria cujo endereco, agora, passa a ser o conteudo da variavel pointer Q.

Quando se declara uma variavel BASED, nao se precisa declarar a variavel pointer a ela associada; a propria declaracao da variavel BASED faz com que o POINTER seja declarado implicitamente.

17. ALOCACAO DE MEMORIA

Page 160

O exemplo pratico que se segue mostra o uso de variavel BASED e variavel POINTER em uma FUNCTION PROCEDURE onde um array de pointer e' passado como argumento na operacao de simulacao de uma lista, de numero de ele- mentos variavel, para se calcular a soma desses elementos e sua media aritmetica.

O termo simulacao de uma lista se deve ao fato de que ela representar a lista real de elementos, no caso de 10 elementos, apenas pelos enderecos desses 10 elementos e nao pelos seus valores, como normalmente se faz, ao nao se usar o recurso da alocacao BASED.

A frase de numeros de elementos variavel se deve ao fato de que o array (lista) de enderecos usado e' de dimensao indefinida, ou seja, assumira a

Page 125: Manual de PL1 - Completo

dimensao do array a ser passado como argumento da procedure invocante. O leitor podera' reparar que esse recurso nao e' o uso do atributo CONTROLLED (nem existe esse atributo na declaracao do array, que no caso se denomina PP), e sim um recurso de passagem de arrays para PROCEDURE, onde, nao se declarando a dimensao do array, este passa a assumir a dimensao do array argumento.

Vejamos o programa:

EX2C17: PROC OPTIONS(MAIN); DCL MEDIA RETURNS(FIXED) ,T(10) FIXED(5) ,P(10) POINTER ; DO I = 1 TO 10; GET EDIT(T(I)) (F(5)); P(I) = ADDR(T(I)); END; PUT EDIT(T)(F(2)); PUT LIST('RESULTADO RETORNADO PELA FUNCAO "MEDIA" =',MEDIA(P)) ; MEDIA: PROC(PP) RETURNS(FIXED(5)); DCL PP(*) POINTER ,VALOR BASED(S) FIXED(5) (M,N) FIXED(5) INIT(0) ; DO I = 1 TO HBOUND(PP,1); IF PP(I) NE NULL THEN DO; S = PP(I); M = M + VALOR; N = N + 1; END; END; IF N = 0 THEN RETURN(0) ELSE RETURN(M/N); END MEDIA; END EX2C17;

17. ALOCACAO DE MEMORIA

Page 161

Podemos ter arrays e estruturas de variaveis based e pointer.

Por exemplo, os casos apresentados a seguir poderiam ser considerados como o uso do atributo DEFINED, ja' visto, uma vez que o resultado das operacoes e' analogo, senao vejamos:

DCL 1 A BASED(P), 2 A1 CHAR(10), 2 A2 CHAR(20); DCL 1 C, 2 C1 CHAR(10), 2 C2 CHAR(20); GET LIST(C); P = ADDR(C); PUT LIST(A2);

Apos a execucao desses comandos o valor de A2 que sera' impresso e' o mesmo que C2, lido no comando GET.

17.8.6. QUALIFICACAO DE VARIAVEIS COM POINTER

PL/1 permite que uma variavel BASED seja associada com mais de uma area de memoria ao mesmo tempo.

Essa multipla associacao e' possivel porque uma variavel BASED por si

Page 126: Manual de PL1 - Completo

so' nao especifica uma constante, mas somente uma descricao de memoria. Uma variavel BASED especifica os atributos e a extensao de uma area de memoria com a qual ela esta' associada (por meio da variavel POINTER).

Nao obstante, a mudanca em um valor de uma variavel POINTER especificada na declaracao de uma variavel BASED causa a associacao da variavel BASED com uma diferente area de memoria e, consequentemente, com um novo dado. E' a combinacao de variaveis POINTER e BASED, entretanto, que determina a alocacao e a descricao de um dado.

Mesmo que somente um POINTER possa ser associado a uma variavel BASED (na declaracao da variavel based), podemos associar simultaneamente dois ou mais POINTERs a uma mesma variavel BASED. Essa multipla associacao e' chamada "POINTER QUALIFICATION" (qualificacao por POINTER) e e' usada para distinguir duas ou mais areas de memoria associada com uma mesma variavel BASED, permitindo que outros POINTERS desfacam o POINTER especi- ficado na declaracao da variavel BASED (no Declare).

O simbolo da qualificacao pointer e' uma combinacao do sinal menos com o sinal de maior(>) ou as letras PT, por exemplo: A->B ou A PT B.

Esse simbolo nao significa uma operacao. Tem uma funcao semelhante a do ponto usado na referencia qualificada de um elemento de uma estrutura , ou seja, DCL 1 EST, 2 A, 2 B; onde poderiamos ter EST.B significando a referencia ao elemento B da estrutura EST.

17. ALOCACAO DE MEMORIA

Page 162

A qualificacao POINTER se aplica 'a descricao de memoria de uma variavel BASED do lado direito do simbolo, para alocacao de memoria especificada pelo valor do POINTER no lado esquerdo do simbolo.

A parte esquerda do simbolo de qualificacao (PT) deve ser ou um POINTER ou uma referencia 'a built-in ADDR e a parte direita deve ser uma variavel BASED.

Por exemplo, P PT Q, onde P e' um pointer e Q uma variavel BASED.

Essa expressao indica a referencia para um dado que tem atributos decla- rados em Q e alocacao de memoria especificada em P.

Se tivermos um outro pointer S e fizermos S PT Q = P PT Q; estaremos es- pecificando duas areas de memoria distintas enderecadas pelos POINTERS S e P 'as quais estao associados os atributos declarados para a variavel BASED denominada Q.

Vejamos um exemplo do uso de um qualificador POINTER no caso de querermos passar os valores impares para os valores pares e os pares para os impa- res em uma ordenacao dada, isto e', trocar os elementos da ordenacao de ordem impar pelos de ordem par e vice-versa; por exemplo , para uma ordenacao chamada P, os elementos P(1), P(3), P(5), P(7) ... serao tro- cados com os elementos P(2), P(4), P(6), P(8)... respectivamente.

EX3C17: PROC OPTIONS(MAIN); DCL P(100) POINTER, T(100) FIXED ; DO I = 1 TO 100; GET EDIT(T(I))(F(5)); PUT SKIP LIST(T(I)); P(I) = ADDR(T(I)); END; CALL TROCA(P) DO I = 1 TO 100; PUT SKIP LIST(' ',' ',T(I)); END; END EX3C17;

Page 127: Manual de PL1 - Completo

TROCA: PROC(P); DCL (P(*),R,S) POINTER, VALOR BASED(S), SALVA FIXED ; DO I = 1 TO HBOUND(P,1) - 1 BY 2; S = P(I); R = P(I+1); SALVA = S PT VALOR; S PT VALOR = R PT VALOR; R PT VALOR = SALVA; END; END TROCA;

17. ALOCACAO DE MEMORIA

Page 163

17.8.7. RESTRICOES PARA VARIAVEIS BASED

® O atributo EXTERNAL nao pode aparecer na declaracao se uma variavel BASED , mas uma variavel BASED pode ser qualificada por uma variavel POINTER externa.

® Nao se podem aplicar os atributos INITIAL e VARYING 'a variavel BASED nem a "ON-Condition" CHECK.

® Nao se podem transmitir valores de uma variavel BASED por meio do co- mando DATA de entrada e saida.

® Nao se pode especificar o atributo BASED a parametros de sub-rotinas ou funcoes.

Para terminar esta apresentacao , veremos um programa classico de variaveis BASED e POINTER. E' o problema de lista encadeada na memoria. Em vez de termos os elementos de uma lista , em locais sucessivos de me- moria , como acontece com os elementos de um array , teremos uma lista de elementos em quaisquer lugares ; apenas ligados por uma variavel POINTER , sendo portanto , necessario que tenhamos , como parte integrante do elemento , uma variavel POINTER , que contera' o endereco do elemento seguinte.

No programa sobre esse problema , apresentado a seguir , os elementos sao definidos por meio de uma estrutura de nome REGISTRO , da qual um item e' justamante a variavel POINTER referida . Uma nota: a posicao, na estrutura, dessa variavel POINTER, como ultimo elemento e' apenas por comodidade, nao sendo obrigatoria .

O programa se propoe, lendo uma "acao" a ser tomada, que pode ser INCLUIR,EXCLUIR,ALTERAR ou LISTAR, a ativar a sub-rotina correspondente incluindo, excluindo ou alterando um elemento ou listando todos os ele- mentos da lista .

As sub-rotinas sao todas internas e o leitor podera', a guisa de exercicio, transformar essas sub-rotinas em externas, fazendo as devidas modificacoes .

EX4C17: PROC OPTIONS(MAIN); DCL NULL BUILTIN,XAV_FIM_SYSIN BIT(1) INIT('1'B) ,1 REGISTRO BASED(P) ,2 XAVEG CHAR(5) ,2 REG CHAR(3) ,2 SEGUINTE POINTER ,ACAO CHAR(7) VAR ,(PRIMEIRO,ULTIMO,ATUAL) POINTER ;

Page 128: Manual de PL1 - Completo

ON ENDFILE(SYSIN) XAV_FIM_SYSIN= '0'B; PRIMEIRO = NULL; GET FILE(SYSIN) EDIT(ACAO)(COL(1),A(7)); DO WHILE(XAV_FIM_SYSIN); PUT FILE(SYSPRINT) SKIP EDIT(ACAO);

17. ALOCACAO DE MEMORIA

Page 164

IF ACAO = 'INCLUIR' THEN CALL INCLUIR; ELSE IF ACAO = 'EXCLUIR' THEN CALL EXCLUIR; ELSE IF ACAO = 'ALTERAR' THEN CALL ALTERAR; ELSE IF ACAO = 'LISTAR' THEN CALL LISTAR; ELSE PUT FILE(SYSPRINT) SKIP LIST ('ERRO NA ACAO ESPECIFICADA'); GET FILE(SYSIN) EDIT(ACAO)(COL(1),A(7)); END; PUT SKIP(2) FILE(SYSPRINT) LIST(' ','FIM DO TRABALHO'); INCLUIR: PROC; ALLOCATE REGISTRO; GET FILE(SYSIN) EDIT(XAVREG,REG)(COL(1),A,A); IF PRIMEIRO = NULL THEN PRIMEIRO = P ELSE ULTIMO PT SEGUINTE = P P PT SEGUINTE = NULL; ULTIMO = P; END INCLUIR; LISTAR: PROC; IF PRIMEIRO = NULL THEN PUT FILE(SYSPRINT) SKIP LIST('NAO HA REGISTROS'); ELSE DO; ATUAL = PRIMEIRO; DO WHILE(ATUAL NE NULL); PUT FILE(SYSPRINT) SKIP EDIT (ATUAL PT XAVREG,ATUAL PT REG)(A); ATUAL = ATUAL PT SEGUINTE; END; END; END LISTAR; ALTERAR: PROC; DCL ALTEREG CHAR(3), CHAVE CHAR(5) ; GET FILE(SYSIN) EDIT(CHAVE,ALTERG)(COL(1),A(5),A(3)); PUT FILE(SYSPRINT) EDIT('ALTERACAO A SER FEITA') (SKIP,A)(CHAVE,ALTREG) (SKIP,A(5),A(3)); IF PRIMEIRO = NULL THEN PUT FILE(SYSPRINT) SKIP LIST('NAO HA REGISTRO'); ELSE DO; ATUAL = PRIMEIRO; DO WHILE(ATUAL NE NULL); IF ATUAL PT XAVREG NE CHAVE THEN ATUAL = ATUAL PT SEGUINTE; ELSE

17. ALOCACAO DE MEMORIA

Page 165

Page 129: Manual de PL1 - Completo

DO; PUT FILE(SYSPRINT) EDIT ('REGISTRO A SER ALTERADO') (SKIP,A) (ATUAL PT XAVREG,ATUAL PT REG) (SKIP,A,A); ATUAL PT REG = ALTEG; ATUAL = NULL; END; END; END ALTERAR; EXCLUIR: PROC; DCL CHAVE CHAR(5), ANTERIOR POINTER; ; GET FILE(SYSIN) EDIT(CHAVE) (COL(1),A(5)); PUT FILE(SYSPRINT) SKIP EDIT(CHAVE) (A); IF PRIMEIRO = NULL THEN PUT FILE(SYSPRINT) SKIP LIST('NAO HA REGISTROS'); ANTERIOR, ATUAL = PRIMEIRO; DO WHILE(ATUAL NE NULL); IF ATUAL PT XAVREG NE CHAVE THEN DO; ANTERIOR = ATUAL; ATUAL = ATUAL PT SEGUINTE; END; ELSE DO; IF ATUAL =PRIMEIRO THEN PRIMEIRO = ATUAL PT SEGUINTE; ELSE ANTERIOR PT SEGUINTE = ATUAL PT SEGUINTE; IF ATUAL = ULTIMO THEN ULTIMO = ANTERIOR; FREE ATUAL PT REGISTRO; PUT FILE(SYSPRINT) SKIP EDIT ('REGISTRO ',CHAVE,'EXCLUIDO DA LISTA') (A); ATUAL = NULL; END; END; END EXCLUIR; END EX4C17;

A seguir apresentamos uma saida desse programa, onde o leitor podera' , analisando-a, identificar os passos seguidos e as acoes tomadas, para esse determinado exemplo:

INCLUIR

AAAA111

INCLUIR

BBBBB222

INCLUIR

17. ALOCACAO DE MEMORIA

Page 166

CCCCC333

INCLUIR

DDDDD444

LISTAR

AAAAA111

Page 130: Manual de PL1 - Completo

BBBBB222

CCCCC333

DDDDD444

EXCLUIR

AAAAA

REGISTRO AAAAA EXCLUIDO DA LISTA

LISTAR

BBBBB222

CCCCC333

DDDDD444

INCLUIR

EEEEE555

ALTERAR

ALTERACAO A SER FEITA

CCCCC777

REGISTRO A SER ALTERADO

CCCCC333

LISTAR

BBBBB222

CCCCC777

DDDDD444

EEEEE555

EXCLUIR

17. ALOCACAO DE MEMORIA

Page 167

EEEEE

REGISTRO EEEEE EXCLUIDO DA LISTA

FIM DO TRABALHO

17.9. ESPACOS OCUPADOS NA MEMORIA _________________________________

Este topico trata dos espacos ocupados na memoria pelos diversos tipos de variaveis existentes na linguagem e seus respecticos alinhamentos com re- ferencia aos enderecamentos permitidos:

Page 131: Manual de PL1 - Completo

17. ALOCACAO DE MEMORIA

Page 168

BYTE , HALFWORD , FULLWORD e DOUBLEWORD. ________________________________________________________________ │ │ │ │ │ │ TIPO DE │ ARMAZENADA │ MEMORIA │ ALINHAMENTO │ │ VARIAVEL │ INTERNAMENTE │ REQUERIDA │ REQUERIDO │ │ │ COMO │ (EM BYTE) │ │ │___________│____________________│______________│________________│ │ BIT(n) │ Um byte para cada │ CEIL(n/8) │ │ │ │ grupo de 8 bits ou │ │ │ │ │ parte de 8 bits │ │ │ │___________│____________________│______________│ │ │ CHAR(n) │ Um byte para cada │ n │ │ │ │ carater │ │ │ │___________│____________________│______________│ BYTE │ │ Picture │ Um byte para cada │ numero de │ │ │ │ carater picture │ caracteres │ │ │ │ (exceto para M,V, │ picture │ │ │ │ k,G) │ │ │ │___________│____________________│______________│ │ │ DEC FIXED │ 1/2 byte por digi- │ CEIL │ │ │ (p,q) │ to mais 1/2 byte │ ((p+1)/2) │ │ │ │ para sinal │ │ │ │___________│____________________│______________│________________│ │ BIN FIXED │ Inteiro binario │ 2 │ │ │ (p,q) │ │ │ HALFWORD │ │ p menor 16│ │ │ │ │___________│____________________│______________│________________│ │ BIN FIXED │ Inteiro binario │ │ │ │ (p,q) │ │ │ │ │ p >= 16 │ │ │ │ │___________│____________________│ │ │ │ BIN FLOAT │ │ │ │ │ (p) │ │ 4 │ FULLWORD │ │ p menor 22│ │ │ │ │___________│ │ │ │ │ DEC FLOAT │ │ │ │ │ (p) │ │ │ │ │ p menor 7 │ │ │ │ │___________│____________________│ │ │ │ POINTER │ │ │ │ │___________│____________________│______________│________________│ │ LABEL │ │ │ │ │___________│____________________│ 8 │ DOUBLEWORD │ │ BIN FLOAT e DEC FLOAT │ │ │ │________________________________│______________│________________│

17. ALOCACAO DE MEMORIA

Page 169

17.10. APLICACOES _________________

Page 132: Manual de PL1 - Completo

1)Este programa e' para resolver sistemas lineares de M equacoes a N incognitas, onde o valor de M e' lido, tornando o programa com caracteristicas gerais.

EX5C17: PROC OPTIONS(MAIN); DCL (A(*,*),AUX(*),TETA(*)) FLOAT(10) CONTROLLED ,MULT FLOAT(10),(M,N,M1,I,J,K,II) FIXED(2) ,FRMAT LABEL ; GET LIST(M) COPY; N = M + 1; M1 = M - 1; ALLOCATE A(M,N), AUX(N), TETA(M); FRMAT2: FORMAT((N)E(120/N,8)); GET LIST(A) COPY; FRMAT = FRMAT2; PUT SKIP(3) EDIT (((A(I,J) DO J = 1 TO N) DO I = 1 TO M)) (R(FRMAT)); METODO: DO K = 1 TO M1; DO WHILE(A(K,K) = 0); AUX = A(K,*); A(K,*) = A(K + 1,*); A(K + 1,*) = AUX; END; DO I = K + 1 TO M; MULT = FLOAT(A(I,J))/A(K,K); DO II = I TO M; DO J = K TO N; (II,J) = A(K,J) * MULT - A(II,J); END METODO; DO J = M TO │ BY -1; TETA(J) = A(J,N)/A(J,J); DO I = J + 1 TO M; TETA(J) = TETA(J) - TETA(I)*A(J,I)/A(J,I); END; END; PUT PAGE; PUT SKIPE(5) EDIT(TETA)(R(FRMAT2)); END EX5C17; A seguir , um lay-out da saida desse programa , para M = 5:

IMPRESSAO DEVIDO AO COMANDO GET LIST(M) COPY

5 2.5 0.87153 -1.35355 -0.95079 0.5

17. ALOCACAO DE MEMORIA

Page 170

1.0 2.625 0.99653 -1.22855 -0.82579 0.625 1.0 3.0 1.35253 -0.92667 -0.80512

Page 133: Manual de PL1 - Completo

0.750 1.0 3.625 1.75008 -0.97855 -1.08797 0.625 1.0 4.5 3.01367 0.5 -0.24831 0.5 1.0

IMPRESSAO DA MATRIZ 'A'

2.50000000E+00 8.71530000E-01 -1.35355000E+00 -9.50790000E-01 ... 2.62500000E+00 9.96530000E-01 -1.22855000E+00 -8.25790000E-01 ... 3.00000000E+00 1.35253000E+00 -9.26670000E-01 -8.05120000E-01 ... 3.62500000E+00 1.75008000E+00 -9.78550000E-01 -1.08797000E-01 ... 4.50000000E+00 3.01367000E+00 5.00000000E-01 -2.48310000E-01 ...

considere as linhas seguintes como continuacao das anteriores

... 5.00000000E-01 1.00000000E+00 ... 6.25000000E-01 1.00000000E+00 ... 7.50000000E-01 1.00000000E+00 ... 6.25000000E-01 1.00000000E+00 ... 5.00000000E-01 1.00000000E+00

SOLUCAO 5.39435870E+00 -8.00143544E+00 3.19141891E+00 6.20689110E-01 ...

considere como continuacao

... -1.20503128E+00

2)Programa para classificar um array ora em ordem crescente, ora em ordem decrescente, dependendo, para tanto, da leitura do parametro correspondente, que no caso e' um string de caracteres de comprimento igual a 1, contendo o carater 'C' para indicar ordenacao crescente, ou um

17. ALOCACAO DE MEMORIA

Page 171

outro qualquer para indicar ordenacao decrescente. Juntamente com esse valor e' lido tambem o limite da dimensao do array .

EX6C17: PROC OPTIONS(MAIN); DCL NUM(*) DEC FIXED(6) CONTROLLED EXTERNAL ,ORD CHAR(1), N DEC FIXED(6) ; ON ENDFILE(SYSIN) GOTO FINAL; DO WHILE(1); GET LIST(N,ORD); ALLOCATE NUM(N); CALL ORDENA(ORD,N); IF ORD = 'C' THEN PUT EDIT('ORDEM CRESCENTE') (SKIP(3),A); ELSE PUT EDIT('ORDEM DECRESCENTE') (SKIP(3),A); PUT EDIT(NUM) (20 F(6)); END; FINAL: END EX6C17;

Page 134: Manual de PL1 - Completo

ORDENA: PROC(ORD,N) OPTIONS(MAIN); DCL NUM(*) FIXED(6) CONTROLLED EXTERNAL ,ORD CHAR(1), IND BIT(1); ,(J,N) FIXED(6), TROCA FIXED(6) ; IF ORD = 'C' THEN CALL CRESC; ELSE CALL DECRESC; CRESC: PROC; CT = -1; VOLTA: IND ='0'B; CT = CT + 1; DO J = 2 TO N - CT; IF NUM(J) LT NUM(J-1) THEN CALL TROC; END; IF IND THEN GOTO VOLTA; END CRESC; DECRESC: PROC; CT = -1; VOLTA; IND = '0'B; CT = CT + 1; DO J = 2 TO N - CT; IF NUM(J) GT NUM(J - 1) THEN CALL TROC; END;

17. ALOCACAO DE MEMORIA

Page 172

IF IND THEN GOTO VOLTA; END DECRESC; TROC: PROC; IND = '1'B; TROCA = NUM(J); NUM(J) = NUM(J - 1); NUM(J - 1) = TROCA; RETURN; END TROC; END ORDENA;

e, para os dados que se seguem como entrada : _____________________________ / │ / 10 'C' 3 4 2 1 5 6 7 10 9 8 │ │ │ │______________________________│

_____________________________ / │ / 10 'D' 3 4 2 1 5 6 7 10 9 8 │ │ │ │______________________________│

teremos para saida:

ORDEM CRESCENTE 1 2 3 4 5 6 7 8 9 10

ORDEM DECRESCENTE 10 9 8 7 6 5 4 3 2 1

Page 135: Manual de PL1 - Completo

3)Programa para classificar um array de estruturas usando variaveis POINTER e BASED.

EX7C17: PROC OPTIONS(MAIN); DCL P(5) POINTER ,1 IMAGEM BASED(S) ,2 CHAVE CHAR(3) ,2 RESTO CHAR(77) ,1 CARTAO(5) ,2 CHAVE CHAR(3) ,2 RESTO CHAR(77) ; GET EDIT(CARTAO) (A(3),A(77)); DO I = 1 TO 5; P(I) = ADDR(CARTAO(I)); END; CALL SORT(P); DO I = 1 TO 5; S = P(I); PUT EDIT(S PT IMAGEM) (SKIP,2 A); END;

17. ALOCACAO DE MEMORIA

Page 173

SORT: PROC(PP); DCL (PP(*),T POINTER ,IND BIT(1) INIT('1'B) ,1 IMAGEM BASED(S) ,2 CHAVE CHAR(3) ,2 RESTO CHAR(77) ; DO WHILE(IND); IND = '0'B; DO I = 1 TO (DIM(PP,1) - 1); S = PP(I); T = PP(I + 1); IF (S PT IMAGEM.CHAVE) GT (T PT IMAGEM.CHAVE) THEN DO; IND = '1'B; PP(I) = T; PP(I + 1) = S; END; END; END; RETURN; END SORT; END EX7C17;

4)Este programa e' identico ao anterior(EX7C17), porem, nao usa array de estrutura. A classificacao e' feita apenas usando enderecos de alocacao da estrutura por meio das variaveis POINTER e BASED.

EX8C17: PROC OPTIONS(MAIN); DCL P(5) POINTER ,1 IMAGEM BASED(S) ,2 CHAVE CHAR(3) ,2 RESTO CHAR(77) ,1 CARTAO CTL ,2 CHAVE CHAR(3) ,2 RESTO CHAR(77) ; DO I = 1 TO 5;

Page 136: Manual de PL1 - Completo

ALLOCATE CARTAO; GET EDIT(CARTAO) (A(3),A(77)); P(i) = ADDR(CARTAO); END; CALL SORT(P); DO I = 1 TO 5; S = P(I); PUT EDIT(S PT IMAGEM) (SKIP,2 A); END; END EX8C17;

A sub-rotina SORT e' a mesma usada no programa anterior.

17. ALOCACAO DE MEMORIA

Page 174

18. ARQUIVOS ____________

18.1. INTRODUCAO ________________

A funcao de apanhar dados de dispositivos externos para serem processados e devolver resultados de operacoes com esses dados chama-se "transmissao de dados".

Os dispositivos externos podem ser a leitora de cartoes,a perfuradora de cartoes,a leitora e/ou perfuradora de fita de papel, a impressora, as unidades de discos e as unidades de fitas magneticas, constituindo os ti- pos de arquivos existentes,cujos meios de transmissao de dados sao os cartoes, as fitas de papel, o formulario, os discos e as fitas magnetica , respectivamente.

Existem dois metodos de transmissao de dados:

1)- o metodo que usa os comandos de entrada e saida, GET e PUT quando os dados sao tratados como uma corrente continua de caracteres.

Foi o metodo utilizado ate' agora em nossa apresentacao, quando usamos para entrada e saida os arquivos-padrao do sistema operacional SYSIN (cartoes) e SYSPRINT (impressora).

2)- o metodo que usa os comandos READ e WRITE - quando os dados sao tra- tados como grupos separados, nao mais em fileiras continuas. E' o aparecimento da nocao de "registros" (que sera' vista mais adiante).

Os dados em um meio externo a ser processado por computador sao chamados ARQUIVOS, por exemplo, um conjunto de cartoes perfurados, um disco,etc.

Os arquivos possuem nomes, que sao identificadores, e devem ter seus atributos declarados explicitamente no comando DECLARE, pelo menos no inicio, quando o programador deve familiarizar-se com os novos atributos ,uma vez que, mais tarde, veremos que os arquivos podem tambem ser decla- rados implicitamente e, assim, um primeiro comando de entrada ou de saida referido ao arquivo fara' com que os atributos sejam assumidos automati- camente.

Um nome de arquivo e', entao, uma representacao simbolica de um determi- nado conjunto de dados armazenados em um meio externo.

Os nomes de arquivos so' podem ter no maximo 7 caracteres, constituindo mais uma excessao 'a regra dos identificadores, de permitir no maximo 31 caracteres. A outra excessao, ja' vista, e' para os rotulos de PROCEDURES.

Page 137: Manual de PL1 - Completo

A forma de se declarar um identificador como sendo um arquivo e': "DE- CLARE nome FILE atributos".

18. ARQUIVOS

Page 175

18.2. ATRIBUTOS PARA ARQUIVOS _____________________________

Quanto aos atributos usados na declaracao de arquivos, vejamos alguns deles:

STREAM - Se os dados do arquivo devem ser considerados como uma corrente continua de caracteres.

RECORD - Se os dados do arquivo devem ser tratados como blocos de carac- teres separados (registros).

INPUT - Se os dados vao ser processados (arquivo de entrada).

OUTPUT - Se os dados sao resultados de processamento e vao ser arquiva - dos (arquivo de saida).

UPDATE - Se os dados vao ser processados e vao ser arquivados apos o processamento (arquivo de entrada-e-saida).

SEQUENTIAL - Se os dados devem ser pesquisados ou guardados sequencial- mente.

DIRECT - Se os dados podem ser pesquisados ou guardados diretamente em sua posicao.

TRANSIENT - Usado somente para aplicacoes de teleprocessamento.

EXTERNAL/INTERNAL - Usado para indicar se o arquivo deve ser reconhecido externamente ou internamente no bloco em que ele foi declarado.

KEYED - Usado para arquivos RECORD com chaves nos registros.

ENVIRONMENT - Usado para especificar o metodo de acesso a ser usado e informacoes sobre o tipo de registro (DCB do arquivo).

PRINT - Usado somente para arquivos STREAM e OUTPUT.

A Fig. 18.1 mostra as relacoes existentes entre os atributos apre- sentados, com referencia a conflitos de declaracao:

_________________________________________ │ STREAM/RECORD │ │ INPUT/OUTPUT/UPDATE │ │ PRINT/RECORD │ │ SEQUENTIAL/DIRECT/TRANSIENT/STREAM │ │ ENVIRONMENT/'DCB' do arquivo │ │ EXTERNAL/INTERNAL │ │ KEYED/STREAM │ │ PRINT/RECORD │ │_________________________________________│ fig. 18.1

18. ARQUIVOS

Page 176

Os atributos STREAM e RECORD especificam o tipo de transmissao de dados

Page 138: Manual de PL1 - Completo

do arquivo e o atributo ENVIRONMENT especifica o metodo de acesso do arquivo, isto e', se CONSECUTIVE, INDEXED ou REGIONAL.

Se o atributo ENVIRONMENT, que se abrevia por ENV, nao for especificado, sera' assumido o metodo CONSECUTIVE automaticamente.

Esse atributo tem a forma ENV(especificacoes), em que "especificacoes " podem ser os tipos de registros (que veremos mais adiante) e/ou um nome de um dos metodos apresentados.

Vejamos alguns exemplos de declaracao de arquivos:

1) DCL ARQ FILE INPUT STREAM: onde ARQ e' um arquivo (FILE) de entrada a ser usado na modalidade STREAM.

2) DCL ARQUIVO FILE OUTPUT RECORD SEQUENTIAL; onde ARQUIVO e' o nome de um arquivo de saida (OUTPUT), a ser acessado na modalidade de registros (RECORD) sequenciais.

3) DCL A FILE INPUT RECORD ENV(F(80)); onde A e' um arquivo de entrada cujos registros terao comprimento fixo igual a 80 bytes. O uso do atri- buto ENV sera' visto quando se tratar de "registros".

Os atributos, em uma declaracao de arquivos, podem vir em qualquer ordem e separados por um branco, pelo menos, podendo ate' mesmo nao conter a palavra-chave FILE, pois os atributos caracterizam o arquivo.

18.3. COMANDOS OPEN E CLOSE ___________________________

Esses comandos sao usados para abrir e fechar um arquivo, significando deixar um arquivo disponivel para o programa e libera'-lo, respecti- vamente.

Asim como um arquivo era declarado automaticamente pelo primeiro comando de entrada ou saida encontrado no programa, ele tambem e' aberto, auto- maticamente, por um dos comandos de E/S.

No comando OPEN podemos tambem definir os atributos do arquivo, exceto para os atributos INTERNAL, EXTERNAL e ENVIRONMENT, que so' poderao cons- tar do comando DECLARE.

A opcao de declaracao de atributos por meio do comando OPEN serve para mudarmos a modalidade do arquivo, ou seja, por exemplo, um arquivo INPUT passar para OUTPUT, ou um arquivo STREAM passar para RECORD e, para tanto, devemos, entre uma modalidade e outra, fechar o arquivo com o uso do comando CLOSE.

As formas dos comandos OPEN e CLOSE sao as seguintes:

OPEN FILE(nome do arquivo) atributos, FILE(nome do arquivo) atributos,

18. ARQUIVOS

Page 177

..... FILE(nome do arquivo) atributos; CLOSE FILE(nome do arquivo), FILE(nome do arquivo), .... FILE(nome do arquivo);

Um arquivo pode ter seus atributos declarados parcialmente no comando DE- CLARE e completado no comando OPEN.

Vejamos alguns exemplos:

Page 139: Manual de PL1 - Completo

1) DCL ARQ FILE RECORD; OPEN FILE(ARQ) OUTPUT; significando um arquivo de nome ARQ, a ser usado na modalidade RECORD e aberto como um arquivo de saida.

2) DCL ARQ FILE, OPEN FILE(ARQ) RECORD OUTPUT; tendo o mesmo significado que o exemplo anterior.

3) DCL CONTA FILE; OPEN FILE(CONTA) OUTPUT; ..... CLOSE FILE(CONTA); OPEN FILE(CONTA) INPUT; ..... CLOSE FILE(CONTA);

O arquivo CONTA foi aberto como um arquivo de saida, em seguida (depois de um determinado processamento de criacao do arquivo) foi fechado e pos- teriormente aberto como um arquivo de entrada, sendo finalmente fechado.

Um arquivo nao precisa ser fechado no final do programa, pois ele e' automaticamente fechado quando o programa termina.

Alguns atributos sao declarados automaticamente pelo compilador, como e' o caso do atributo STREAM, no ultimo exemplo apresentado, que e' assumido quando nao ha' declaracao do tipo da transmissao de dados (STREAM ou RECORD). Os outros atributos sao: CONSECUTIVE (no ENV), SEQUENTIAL e INPUT.

Os comandos DECLARE e OPEN especificam explicitamente os atributos de arquivos.

18.4. ARQUIVOS STREAM _____________________

Os arquivos STREAM sao aqueles em que os dados sao tratados como uma fileira continua de caracteres.

Os comandos de acesso aos arquivos sao os comandos ja' vistos ate' agora, o GET e o PUT, cujas formas gerais sao:

│GET│ │LIST(lista de dados); │

18. ARQUIVOS

Page 178

│ ││FILE(nome do arquivo)││DATA(lista de dados); │ │PUT│ │EDIT(lista de dados)(lista de FORMAT);│

Quando os arquivos sao os padroes do sistema, SYSIN e SYSPRINT, o termo FILE(nome do arquivo) pode ser omitido dos comandos.

Vejamos uma aplicacao: um programa para criar um arquivo e listar seu conteudo depois de sua criacao.

EX1C18: PROC OPTIONS(MAIN); DCL REG (100) FIXED(2), ARQREG FILE; GET FILE(SYSIN) LIST(REG); OPEN FILE(ARQREG) OUTPUT; PUT FILE(ARQREG) LIST(REG); CLOSE FILE(ARQREG); OPEN FILE(ARQREG) INPUT; GET FILE(ARQREG) LIST(REG); PUT FILE(SYSPRINT) DATA(REG); END EX1C18;

Page 140: Manual de PL1 - Completo

Esse programa le uma ordenacao de 100 elementos, cuja ordem de grandeza varia entre -99 e +99 (para o array REG) da leitora-padrao do sistema (SYSIN), grava-os no arquivo de nome ARQREG (arquivo STREAM) e em se- guida, abre esse mesmo arquivo como um arquivo de entrada, le seu conteudo e imprime na impressora-padrao do sistema (SYSPRINT).

Na aplicacao seguinte, tres valores sao lidos do arquivo-padrao do sis- tema (SYSIN) para as variaveis X, Y e Z, em seguida esses tres valores sao gravados em um arquivo denominado ARQUIVO. Finalmente esse arquivo e' fechado e aberto como INPUT (arquivo de entrada), para entao serem lidos os tres valores gravados anteriormente, o que e' feito por meio do co- mando GET FILE(ARQUIVO) EDIT(A,B,C)(3F(6)); significando que os valores gravados em ARQUIVO vao ser atribuidos 'as variaveis A, B, C, respecti- vamente.

EX2C18: PROC OPTIONS(MAIN); DCL ARQUIVO FILE; GET FILE(SYSIN) DATA(X,Y,Z); OPEN FILE(ARQUIVO) OUTPUT; PUT FILE(ARQUIVO) EDIT(X,Y,Z) (3 F(6)); CLOSE FILE(ARQUIVO); OPEN FILE(ARQUIVO) INPUT; GET FILE(ARQUIVO) EDIT(A,B,C) (3 F(6)); PUT FILE(SYSPRINT) LIST(A,B,C); END EX2C18;

Assim, para uma entrada formatada por X=10, Y=20, Z=30; (por forca do co- mando GET FILE(SYSIN) DATA(X,Y,Z);) teriamos uma saida do tipo:

________________________________________________________________ │

18. ARQUIVOS

Page 179

│ b1.00000E+01 b2.00000E+01 b3.00000E+01 │ │ │ │ │ +- col.1 +- col.25 +- col.49

Vejamos mais um exemplo:

EX3C18: PROC OPTIONS(MAIN); DCL TEST FILE INPUT; ON ENDFILE(TEST) GO TO FIM; DO WHILE('1'B); GET FILE(TEST) EDIT(REG) (A(150)); PUT SKIP FILE(SYSPRINT) LIST(REG); END; FIM; END EX3C18;

Esse programa le, do arquivo denominado TEST, blocos de dados de comprimento igual a 150 caracteres, imprimindo-os na SYSPRINT ate' ser detectado o fim de arquivo (comando ON ENDFILE).

18.5. ARQUIVOS PRINT ____________________

Sao arquivos STREAM e OUTPUT, usados para formatacao de saidas diretamente na impressora, ou entao em forma de "lay-outs" armazenados e discos ou fitas magneticas, para posteriores impressoes.

Eles permitem o uso dos atributos constantes na Fig.18.2.

Page 141: Manual de PL1 - Completo

18. ARQUIVOS

Page 180

______________________________________________________________ │ OPCOES │ LISTA DE FORMATOS │ COMANDOS │ FUNCAO │ │___________│___________________│_____________│________________│ │ │ │ │ │ │LINESIZE(w)│ --- │ OPEN │ nro. maximo │ │ │ │ │ de caracteres │ │ │ │ │ por linha. │ │ │ │ │ │ │PAGESIZE(w)│ --- │ PAGE │ nro. maximo │ │ │ │ │ de linhas por │ │ │ │ │ pagina. │ │ │ │ │ │ │PAGE │ PAGE │ PUT │ mudar de │ │ │ │ │ pagina antes │ │ │ │ │ da impressao │ │ │ │ │ │ │LINE(w) │ LINE(w) │ PUT │ mudar para a │ │ │ │ │ linha w antes │ │ │ │ │ da impressao │ │ │ │ │ │ │SKIP(w) │ SKIP(w) │ PUT │ pular w-1 │ │ │ │ │ linhas antes │ │ │ │ │ da impressao │ │ │ │ │ │ │COL(w) │ COL(w) │ PUT │ passar para a │ │ │ │ │ coluna w antes │ │ │ │ │ da impressao │ │ │ │ │ │ │X(w) │ X(w) │ PUT │ saltar w │ │ │ │ │ espacos antes │ │ │ │ │ da impressao │ │___________│___________________│_____________│________________│

Fig. 18.2

Os arquivos PRINT exigem que seja acrescido de uma unidade o tamanho da linha a ser impressa, justamente para ser colocado o carater de controle de impressao pelo Sistema Operacional.

O arquivo-padrao SYSPRINT, conforme o nome indica, e' um arquivo PRINT e, por conseguinte, um arquivo de saida (OUTPUT) e STREAM.

O comando OPEN FILE(RELAT) OUTPUT STREAM PRINT PAGESIZE(55) LINESIZE(100); declara e abre um arquivo de nome RELAT, com atributo PRINT, onde os dados vao ser impressos (ou gravados) ocupando uma linha de no maximo 100 caracteres e uma pagina de no maximo 55 linhas a serem impressas.

Poder-se-ia ter feito tambem a seguinte combinacao de comandos:

DCL RELAT FILE OUTPUT STREAM PRINT;

OPEN FILE(RELAT) PAGESIZE(55) LINESIZE(100);

18. ARQUIVOS

Page 181

Page 142: Manual de PL1 - Completo

ou qualquer outra combinacao coerente com os atributos declarados.

Dentre as opcoes constantes da Fig. 18.2, somente as opcoes SKIP(w) e LINESIZE(w) podem ser usadas para arquivos STREAM OUTPUT nao PRINT, e nesse caso, se w, em SKIP(w), for omitido ou se assumir valores menores ou iguais a zero, sera' automaticamente considerado como 1 (um).

Vejamos um exemplo completo de arquivo STREAM, OUTPUT, PRINT:

EX4C18; PROC OPTIONS(MAIN); DCL TAB FILE OUTPUT PRINT, TITULO CHAR(26) INIT('RAIZ QUADRADA E POTENCIA DE 2'), (POT,RAIZ) FLOAT(10), PAGIM DEC FIXED(2) INIT(0); OPEN FILE(TAB) PAGESIZE(52) LINESIZE(72); ON ENDPAGE(TAB) BEGIN; PUT FILE(TAB) PAGE; PAGIM=PAGIM+1; PUT FILE(TAB) EDIT('PAGINA',PAGIM) (COL(62),A,F(4)); PUT FILE(TAB) EDIT(TITULO) (X(10),A); PUT FILE(TAB) SKIP(2); KONT=0; END; PUT FILE(TAB) SKIP(60); DO XI= 1.0 TO 10.0 BY 0.1; KONT=KONT+1; RAIX=SORT(XI); POT=XI*XI; PUT FILE(TAB) EDIT(XI,POT,RAIZ) (SKIP,F(4,2),2(X(5), E(15,6))); IF KONT=20 THEN PUT FILE(TAB) SKIP(60); END; CLOSE FILE(TAB); END EX4C18;

O leitor devera' tentar compreender esse programa pela simples analise de seus comandos, observando os recursos usados para quebra de pagina e con- trole de linhas impressas por pagina (20 linhas), nao obstante a definicao de 52 linhas, especificada no atributo PAGESIZE.

A diferenca do numero 52 para as 20 linhas impressas pode ser explicada pela necessidade que se tem, as vezes, de usar um formulario pre'- impresso, de tamanho para 52 linhas, das quais somente 20 podem ser impressas.E' exatamente essa a finalidade didatica do presente exercicio (EX4C18).

18. ARQUIVOS

Page 182

18.6. ARQUIVOS RECORD _____________________

Os arquivos RECORD sao aqueles em que os dados nao sao mais tratados como uma fileira continua de caracteres, mas como grupos separados de caracte- res, formando o que se denomina REGISTROS.

18.6.1. REGISTRO FISICO E LOGICO - FATOR DE BLOCO

Cada grupo de caracteres constitui um REGISTRO LOGICO e cada conjunto de registros logicos (grupos de caracteres) constitui um REGISTRO FISICO

Page 143: Manual de PL1 - Completo

Quando o REGISTRO FISICO e' formado por um grupo de registros logicos, conforme visto na definicao, temos os chamados registros BLOCADOS e, quando o REGISTRO FISICO e' formado por apenas um registro logico (grupo unitario), temos os chamados registros NAO BLOCADOS.

Com relacao ainda aos registros logicos, podemos ter a classificacao de registros de tamanho fixo, tamanho variavel e tamanho indefinido, e, consequentemente, teremos registros fisicos formados por registros logicos de tamanho fixo, variavel e indefinido.

Ao numero de vezes que um registro logico esta' contido num registro fisico denomina-se FATOR DE BLOCO. Quando o registro fisico e' formado por apenas um registro logico, o fator de bloco e' igual a 1.

Para o caso de registros de tamanho fixo, o fator de bloco tem que ser divisor exato do registro fisico, isto e', ele deve indicar exatamente quantos registros logicos existem no registro fisico.

Para o caso de registros de tamanho indefinido, o fator de bloco tem que ser igual a 1.

Para o caso de registros de tamanho variavel, o fator de bloco e' deter- minado automaticamente pelo sistema, de acordo com o menor e o maior va- lor que o registro logico podera' assumir.

Um registro fisico e' a unidade fisica de dados transmitidos de ou para um arquivo. E' tambem chamado BLOCO e constitui o tamanho da area de "buffer" para o programa.

Recapitulando, um registro fisico e' formado por um ou mais registros logicos e um registro logico e' formado por um ou mais dados.

Assim, um conjunto de dados forma um registro logico; um conjunto de re- gistros logicos forma um registro fisico; e um conjunto de registros fisicos forma um ARQUIVO.

Para melhor compreendermos esses conceitos, vejamos uma comparacao dos mesmos com uma biblioteca de livros:

Sistema Operacional ............ Biblioteca

18. ARQUIVOS

Page 183

Arquivos ............ Estantes de Livros Registros Fisicos ............ Livros nas Estantes Registros Logicos ............ Capitulos de Livros Dados ............ Palavras dos Capitulos

Os dados armazenados em dispositivos externos (arquivos), sob forma de registros, sao sempre lidos e gravados do comeco ao fim de um registro fisico (na area de buffer), embora essa operacao seja feita de registro logico em registro logico, por meio dos comandos de entrada-e-saida es- critos no programa.

Em resumo, o acesso ao arquivo pelo programador e' sempre feito por meio de registros logicos e o acesso ao arquivo pelo programa e' sempre feito por meio de registros fisicos (area de buffer).

18.7. ATRIBUTO "ENVIRONMENT" ____________________________

E' por meio desse atributo que se especificam os comprimentos dos regis- tros logico e fisico, os tipos de registros (se fixo, variavel ou indefi- nido) e as organizacoes dos arquivos (CONSECUTIVE, INDEXED, REGIONAL).

Mais uma vez deve ser lembrado que o tipo de organizacao de arquivos de

Page 144: Manual de PL1 - Completo

que estamos tratando e' o CONSECUTIVE (assumido automaticamente quando nao se declara o atributo ENV ou nao se declara no atributo ENV).

Vejamos como se usa o atributo ENVIRONMENT, apenas para especificar os tipos de registros e seus comprimentos.

ENV(F(tamanho do bloco)) indica que os registros de um arquivo sao nao blocados e de tamanho fixo. ENV(F(tamanho do bloco, tamanho do registro)) indica que os registros sao blocados e de tamanho fixo. ENV(V(tamanho do bloco)) indica que os registros de um arquivo sao de tamanho variavel. ENV(U(tamanho do registro)) indica que os registros de um arquivo sao de tamanho indefinido.

18.7.1. REGISTROS DE TAMANHO FIXO

O comando DCL C FILE INPUT ENV(F(320,40)); especifica um arquivo de en- trada (INPUT) cujos registros sao de tamanho fixo (F) e estao blocados , com fator de bloco igual a 8 (320 dividido por 40), isto e', sao regis- tros logicos de comprimento 40 bytes, agrupados em 320 bytes (tamanho do registro fisico = area de buffer do programa para esse arquivo). Ja' o comando DCL C FILE OUTPUT ENV(F(60)); especifica um arquivo (C) de saida (OUTPUT) cujos registros sao de tamanho fixo (F), nao blocados (fator de bloco igual a 1), isto e', o registro logico tem o mesmo comprimento que o registro fisico.

18. ARQUIVOS

Page 184

18.7.2. REGISTROS DE TAMANHO INDEFINIDO

Quando um registro e' de tamanho indefinido, a especificacao no atributo ENV e' a letra U seguida pelo "valor maximo" do comprimento do registro, entre parenteses.

O importante, nesse caso, e' saber que cada registro fisico e' composto por apenas um registro logico, cujo comprimento pode variar ate' o seu valor maximo especificado.

Assim o comando DCL C FILE ENV(U(420)); especifica um arquivo cujos re- gistros sao de tamanho indefinido de comprimento maximo igual a 420 bytes.

O registro de tamanho indefinido e' usado em aplicacoes de teleprocessamento.

18.7.3. REGISTROS DE TAMANHO VARIAVEL

Quando um registro logico e' de tamanho variavel, um campo de 4 bytes e' automaticamente inserido no inicio de cada registro fisico.

Como ilustracao, um bloco de registros de tamanho variavel (registro fisico) tem a seguinte configuracao:

_____________________________________________________________ │ B │ A1 │ RL1 │ A2 │ RL2 │ A3 │ RL3 │ ..... │ An │ RLn │/////│ │___│____│_____│____│_____│____│_____│_______│____│_____│_____│ │ <---> <---> <---> <--->│ │ │ C1 C2 C3 Cn │ │ │ │ │ │ │ │ │<---------- tamanho do bloco ----------------------->│ │ │ │

Page 145: Manual de PL1 - Completo

│<---------- tamanho maximo do bloco -------------------->│ │ │

onde: B - campo de 4 bytes colocado antes do registro fisico (bloco) Ai - campo de 4 bytes colocado antes de cada registro logico-i RLi - campo contendo o registro logico-i Ci - comprimento do registro logico-i

Assim, para se especificar o comprimento maximo do bloco (registro fisico) no atributo ENVIRONMENT, devem-se computar os 4 bytes colocados antes de cada registro fisico, como tambem os colocados antes de cada re- gistro logico, por exemplo:

18. ARQUIVOS

Page 185

1) DCL ARQ FILE OUTPUT ENV(V(180)); podera' referir-se a um arquivo com a seguinte distribuicao de registros:

4 registros de 40 bytes cada um = 160 bytes 1 campo de 4 bytes para o bloco = 4 bytes 4 campos de 4 bytes (cada reg.) = 16 bytes ------------ 180 bytes ou 1 registro de 172 bytes = 172 bytes 1 campo de 4 bytes para o bloco = 4 bytes 1 campo de 4 bytes para o reg. = 4 bytes ------------ 180 bytes

18.8. COMANDOS DE ACESSO AOS ARQUIVOS RECORD ____________________________________________

Os comandos que apresentaremos a seguir sao aplicados aos arquivos de organizacao CONSECUTIVE e na modalidade RECORD. p.Sao eles: COMANDO READ, COMANDO WRITE e COMANDO REWRITE.

18.8.1. COMANDO READ

O comando READ, cuja forma e':

┌───────────────────────────────────────────────────────────────────────┐ | | | READ FILE(nome do arquivo) INTO(variavel); | └───────────────────────────────────────────────────────────────────────┘

tem a finalidade de transmitir um registro do arquivo para a memoria, tornando-o disponivel ao processamento do programa.

A variavel para onde e' lido o registro pode ser uma estrutura (nivel 1), uma variavel array (sem subscrito) ou uma variavel simples.

Por exemplo, READ FILE(ENT) INTO(CAMPO); fara' com que um registro logico seja lido do arquivo denominado ENT (arquivo RECORD INPUT ou UPDATE)para a variavel denominada CAMPO (podendo ser uma estrutura, um array ou uma variavel simples).

18.8.2. COMANDO WRITE

O comando WRITE, cuja forma e':

┌───────────────────────────────────────────────────────────────────────┐

Page 146: Manual de PL1 - Completo

18. ARQUIVOS

Page 186

| | | WRITE FILE(nome do arquivo) FROM(variavel); | └───────────────────────────────────────────────────────────────────────┘

tem a finalidade de transmitir um registro logico da memoria para o arquivo.

A variavel de onde e' transmitido o registro pode ser uma qualquer das apresentadas no comando READ.

Por exemplo, WRITE FILE(SAI) FROM(CAMPO); fara' com que um registro logico seja transmitido da memoria para o arquivo denominado SAI. Esse registro logico foi composto na variavel denominada CAMPO.

18.8.3. COMANDO REWRITE

O comando REWRITE, cuja forma e':

┌───────────────────────────────────────────────────────────────────────┐ | | | REWRITE FILE(nome do arquivo) FROM(variavel); | └───────────────────────────────────────────────────────────────────────┘

tem a finalidade de transmitir um registro logico da memoria para o arquivo no sentido de regravacao do registro, isto e', colocacao do re- gistro no mesmo lugar que ele ocupava no arquivo.

Vistos os tres tipos de comandos, de uma maneira geral, o comando READ acessa o arquivo no sentido de leitura dos seus registros (arquivos ja' existentes); o comando WRITE acessa o arquivo no sentido de gravacao dos seus registros (arquivo sendo criado); e o comando REWRITE acessa o arquivo no sentido de regravacao dos seus registros (arquivo sendo alte- rado).

Vejamos alguns exemplos de programas acessando arquivos RECORD e CONSECU- TIVE.

EX5C18: PROC OPTIONS(MAIN); DCL (REG1,REG2) (100) PIC'99' ,REG PIC'99' ARQREG FILE RECORD ENV(F(50,2)) ; GET FILE(SYSIN) LIST(REG1); OPEN FILE(ARQREG) OUTPUT; DO I = 1 TO 100; REG = REG1(I); WRITE FILE(ARQREG) FROM(REG); END; CLOSE FILE(ARQREG); OPEN FILE(ARQREG) INPUT; DO I = 1 TO 100; READ FILE(ARQREG) INTO(REG);

18. ARQUIVOS

Page 187

REG2(I) = REG; END; PUT FILE(SYSPRINT) DATA(REG2); END EX5C18;

Esse programa cria o arquivo denominado ARQREG com registros de tamanho

Page 147: Manual de PL1 - Completo

fixo, blocados (FB=25), com registros logicos de comprimento igual a 2 bytes cada um e registro fisico de comprimento de 50 bytes. Cada registro logico no arquivo e' um elemento do array REG1.

Vejamos, agora, um outro exemplo, bem semelhante ao anterior, onde os re- gistros logicos nao sao mais os elementos de um array, separadamente, e sim todos os elementos do array juntos, formando um so' registro.

EX6C18: PROC OPTIONS(MAIN); DCL REG(100) PIC'99' ,ARQREG FILE RECORD ENV(F(200)) ; GET FILE(SYSIN) LIST(REG); OPEN FILE(ARQREG) OUTPUT; WRITE FILE(ARQREG) FROM(REG); CLOSE FILE(ARQREG); OPEN FILE(ARQREG) INPUT; READ FILE(ARQREG) INTO(REG); PUT FILE(SYSPRINT) DATA(REG); CLOSE FILE(ARQREG); END EX6C18;

Normalmente, usa-se para determinar um registro o tipo de variavel conhecido como estrutura, que e', realmente, o mais indicado para repre- sentar o lay-out de um registro, pela sua propria configuracao.

EX7C18: PROC OPTIONS(MAIN); DCL ARQIN RECORD INPUT ENV(F(30)) ,ARQ2000 RECORD ENV(F(30)) ,1 EST ,2 NOME ,3 ULTIMO CHAR(15) ,3 PRIMEIRO CHAR(10) ,2 SALARIO PIC'99999' ; ON ENDFILE(ARQIN) GOTO SEG; DO WHILE('1'B); READ FILE(ARQIN) INTO(EST); PUT FILE(SYSPRINT) SKIP DATA(EST); IF SALARIO GT 2000 THEN WRITE FILE(ARQ2000) FROM(EST); END; SEG: CLOSE FILE(ARQ2000);

18. ARQUIVOS

Page 188

OPEN FILE(ARQ2000) INPUT; ON ENDFILE(ARQ2000) GOTO FIM; DO WHILE ('1'B); READ FILE(ARQ2000) INTO(EST); PUT FILE(SYSPRINT) SKIP DATA(EST); END; FIM: END EX7C18;

18.9. CTLASA E CTL360 _____________________

Este topico diz respeito ao uso dos parametros CTLASA e CTL360 para con- trole do carro impressor em arquivos RECORD.

Page 148: Manual de PL1 - Completo

Os registros para esse tipo de arquivo deverao ter um byte a mais no seu inicio, onde sera' armazenado o carater de controle do carro.

Esses parametros sao especificados no atributo ENVIROMENT e o programador tem todo o controle sobre o lay-out de saida, no que se refere a saltos de linhas e de pagina.

A especificacao CTLASA (codigo ANS) e' dada pela Fig. 18.3.

18. ARQUIVOS

Page 189

__________________________________________________________ │ │ │ │ VALOR │ │ │_____________│____________________________________________│ │ │ │ │ branco │ passar para linha seguinte │ │ 0 │ pular uma linha │ │ - │ pular duas linhas │ │ + │ nao mudar de linha │ │ 1 │ mudar de pagina (saltar p/ canal 1) │ │ 2 │ saltar para canal 2 │ │ . │ ... │ │ . │ ... │ │ 8 │ saltar para canal 8 │ │ 9 │ saltar para canal 9 │ │ A │ saltar para canal 10 │ │ B │ saltar para canal 11 │ │ C │ saltar para canal 12 │ │ V │ selecionar escaninho 1 │ │ W │ selecionar escaninho 2 │ │_____________│____________________________________________│

Todas essas funcoes da especificacao CTLASA sao tomadas antes que o re- gistro seja gravado.

Ja' o codigo 360, especificacao CTL360, permite especificar controles para que a funcao seja efetuada antes ou depois da gravacao do registro. E' bem mais rapido que o codigo ANS, porem seu uso e' mais dificil, pois o controle e' feito pela especificacao de 8 bits no carater inicial do registro, destinado para controle do carro impressor.

Como exemplo do uso do codigo 360 (CTL360), temos alguns casos:

00000001 - WRITE 00001001 - WRITE e espaceja uma linha depois da impressao 00010001 - WRITE e espaceja duas linhas depois da impressao .... 10001001 - WRITE e SKIP para o canal 1 depois da impressao .... 00001011 - espacejar uma linha imediatamente e assim sucessivamente.

Vejamos uma aplicacao do parametro CTLASA.

EX8C18: PROC OPTIONS(MAIN); DCL ARQUIVO RECORD ENV(V(73) CTLASA)

Page 149: Manual de PL1 - Completo

,1 CAB ,2 CONTROLE CHAR(1) INIT('1') ,2 BRANCO1 CHAR(13) INIT(' ') ,2 TITULO1 CHAR(5) INIT('VALOR') ,2 BRANCO2 CHAR(6) INIT(' ') ,2 TITULO2 CHAR(8) INIT('QUADRADO') ,2 BRANCO3 CHAR(10) INIT(' ')

18. ARQUIVOS

Page 190

,2 TITULO3 CHAR(4) INIT('CUBO') ,2 BRANCO4 CHAR(5) INIT(' ') ,2 PAGINA CHAR(6) INIT('PAGINA') ,2 PAGIN PIC'Z9' ,1 DETALHE ,2 CONTROLE CHAR(1) INIT('-') ,2 BRANCO1 CHAR(11) INIT(' ') ,2 VALOR PIC'ZZZZ9' ,2 BRANCO2 CHAR(12) INIT(' ') ,2 QUADRADO PIC'ZZZZ9' ,2 BRANCO3 CHAR(12) INIT(' ') ,2 CUBO PIC'ZZZZ9' ; OPEN FILE(ARQUIVO) OUTPUT; PAGIN = 1; WRITE FILE(ARQUIVO) FROM(CAB); K5 = OB; K25 = 101B; PUT FILE(SYSPRINT) SKIP(5) EDIT((70)'*') (A(70)); DO VALOR = 1 TO 30; K5 = K5 + 1B; QUADRADO = VALOR * VALOR; CUBO = QUADRADO * VALOR; PUT FILE(SYSPRINT) SKIP EDIT(DETALHE) (A,3(A,F(5))); WRITE FILE(ARQUIVO) FROM(DETALHE); DETALHE.CONTROLE = ' '; IF K5 = K25 THEN DO; IF K25 = 11001B THEN DO; PAGIN = PAGIN + 1; WRITE FILE(ARQUIVO) FROM(CAB); K25 = 101B; K5 = 0B; END; ELSE K25 = K25 + 101B; DETALHE.CONTROLE = '-'; END; END; END EX8C18;

18. ARQUIVOS

Page 191

Como saida teremos:

************************************************************** - 1 1 1 2 4 8 3 9 27

Page 150: Manual de PL1 - Completo

4 16 64 5 25 125 - 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000 - 11 121 1331 12 144 1728 ... ... ... ... ... ... 26 676 17576 27 729 19683 28 784 21952 29 841 24389 30 900 27000

Essa parte e' a saida provocada pelo comando PUT FILE(SYSPRINT) SKIP EDIT(DETALHE) (A,3(a,F(5)));

18. ARQUIVOS

Page 192

A seguir, a parte da saida provocada pelo comando WRITE FILE (ARQUIVO) FROM(DETALHE);

VALOR QUADRADO CUBO PAGINA 1

1 1 1 2 4 8 3 9 27 4 16 64 5 25 125

6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000

11 121 1331 12 144 1728 13 169 2197 14 196 2744 15 225 3375

16 256 4096 17 289 4913 18 324 5832 19 361 6859 20 400 8000

21 441 9261 22 484 10648 23 529 12167 24 576 13824 25 625 15625

Page 151: Manual de PL1 - Completo

VALOR QUADRADO CUBO

26 676 17576 27 729 19683 28 784 21952 29 841 24389 30 900 27000

18.10. OPCAO 'TITLE' PARA ARQUIVOS __________________________________

E' usada quando desejamos que varios arquivos sejam abertos e usados por meio de um titulo especial.

Esses titulos substituiem os "DDnames" nos cartoes DD.

18. ARQUIVOS

Page 193

Assim, se tivermos, por exemplo, quatro arquivos, poderemos referir-nos a eles apenas por um nome nos comandos READ e WRITE, como tambem na declaracao dos mesmos.

Atraves do comando OPEN, referimo-nos a um arquivo especifico usando a opcao TITLE.

Sua forma e':

_________________________________________________________ │ │ │ OPEN FILE(nome do arq) TITLE(titulo do arq) atributos; │ │_________________________________________________________│

Por exemplo:

DCL TITULO CHAR(4); DCL ARQUIV FILE RECORD; ----- ----- OPEN FILE(ARQUIV) TITLE('ARQ1') input; ----- ----- CLOSE FILE(ARQUIV): TITULO='ARQ2'; OPEN FILE(ARQUIV) TITLE(TITULO) OUTPUT; ----- ----- Nos cartoes DD teriamos: ----- ----- //ARQ1 DD... //ARQ2 DD ... ----- ----- -----

O titulo do arquivo, colocado entre parenteses na opcao TITLE, tem que ser um string de caracteres (variavel ou constante).

Como exemplo de uma aplicacao da opcao TITLE, o programa que se segue lista 3 arquivos, cada um contendo registros de 80 bytes de comprimento, de tamanho fixo, nao blocados e acessados na modalidade RECORD.

EX10C18: PROC OPTIONS(MAIN);

Page 152: Manual de PL1 - Completo

DCL ARQ FILE RECORD INPUT ENV(F(80)) ,REGISTRO CHAR(80) ,TIT(3) CHAR(4) INIT('TIT1','TIT2','TIT3') ,TITN CHAR(4) ; DO I = 1,2,3; PUT SKIP(2) LIST(' ARQUIVO LIDO NUMERO',I); ON ENDFILE(ARQ)

18. ARQUIVOS

Page 194

GOTO FORA; TITN = TIT(I); OPEN FILE(ARQ) TITLE(TITN); LER: READ FILE(ARQ) INTO(REGISTRO); PUT SKIP LIST(REGISTRO); GOTO LER; FORA: CLOSE FILE(ARQ); END: END EX10C18;

e, para esse programa, deverao existir 3 cartoes DD, cujos DDnames sao:

//TIT1 DD . . . . //TIT2 DD . . . . //TIT3 DD . . . .

18.11. APLICACAO ________________

1)Programa para determinar as raizes de uma equacao do 2o. grau qualquer, inclusive com raizes complexas. Perfurara' os valores das raizes em cartoes perfurados e gravara' esses valores num arquivo denominado DISCO.

EX11C18: PROC OPTIONS(MAIN); DCL PERFURA FILE STREAM OUTPUT ,DISCO FILE RECORD OUTPUT SEQUENTIAL ,1 REGISTRO ,2 (A,B,C,RAIZ1,RAIZ2) FLOAT DEC(6) COMPLEX ; ON ENDFILE(SYSSIN) GOTO FIM; OPEN FILE(PERFURA), FILE(DISCO); LER: GET FILE(SYSIN) LIST(A,B,C); RAIZ1 = (-B+SQRT(B*B-4*A*C)) / (2*A); RAIZ2 = (-B-SQRT(B*B-4*A*C)) / (2*A); PUT FILE(PERFURA) EDIT(REGISTRO) (C(E(16,9))); WRITE FILE(DISCO) FROM(REGISTRO); GOTO LER; FIM: CLOSE FILE(PERFURA), FILE(DISCO); END EX11C18;

Sendo os dados de entrada;

5 12 4 4 -10 4 5 16 12 4 -12 10 5 12 9 29 -20 4

obtemos a seguinte saida perfurada em cartoes:

18. ARQUIVOS

Page 153: Manual de PL1 - Completo

Page 195

5.000000000E+00 0.000000000E+00 1.200000000E+01 0.000000000E+00 4.000000000E+00 0.000000000E+00-3.999999762E-01 0.000000000E+00-2.000000000E+00 0.000000000E+00 0.000000000E+00 0.000000000E+00-1.000000000E+01 0.000000000E+00 4.000000000E+00 0.000000000E+00 2.000000000E+00 0.000000000E+00 5.000000000E-01 0000000000E+00 5.000000000E+00 0.000000000E+00 1.600000000E+01 0.000000000E+00 1.200000000E+01 0.000000000E+00-1.199999809E+00 0.000000000E+00-2.000000000E+00 0.000000000E+00 4.000000000E+00 0.000000000E+00-1.200000000E+01 0.000000000E+00 1.000000000E+01 0.000000000E+00 1.500000000E+00 5.000000000E-01 1.500000000E+00 -5.000000000E-01 5.000000000E+00 0.000000000E+00 1.200000000E+01 0.000000000E+00 9.000000000E+00 0.000000000E+00-1.199999809E+00 5.999999642E-01-1.199999809E+00 -5.999999642E-01 2.900000000E+01 0.000000000E+00-2.000000000E-01 0.000000000E+00 4.000000000E+00 0.000000000E+00 3.448275328E-01 1.379309893E-01 3.448275328E-01 -1.379309893E-01

2)Este programa le o arquivo denominado DISCO criado pelo programa ante- rior, imprimindo-o na SYSPRINT. Note-se que o nome do arquivo de entrada, o arquivo DISCO, foi mudado para SOLUCAO, pois, sendo um identificador, e' criado pelo programador e pode ser qualquer nome, desde que respeite as regras de criacao dos identificadores e nao tenha mais do que 7 carac- teres.

EX12C18: PROC OPTIONS(MAIN); DCL SOLUCAO FILE RECORD INPUT SEQUENTIAL ,1 REGISTRO ,2 (A,B,C,RAIZ1,RAIZ2) COMPLEX ; ON ENDFILE(SOLUCAO) GOTO FIM; PUT FILE(SYSPRINT) EDIT('A','B','C','RAIZ1','RAIZ2') (SKIP(5),3 (x(12),A,X(11)),2 (X(9),A,X(10))); PUT SKIP EDIT((120)'*') (A); OPEN FILE(SOLUCAO); LER: READ FILE(SOLUCAO) INTO(REGISTRO); PUT FILE(SYSPRINT) SKIP EDIT(REGISTRO) (C(F(12,2))); GOTO LER; FIM; CLOSE FILE(SOLUCAO); PUT SKIP EDIT((120)'*') (A(120)); END EX12C18;

tendo como saida o seguinte lay-out:

18. ARQUIVOS

Page 196

A B C RAIZ1 RAIZ2 ********************************************************************** 5.00 0.00 12.00 0.00 4.00 0.00 -0.40 0.00 -2.00 0.00 4.00 0.00 -10.00 0.00 4.00 0.00 2.00 0.00 0.50 0.00 5.00 0.00 16.00 0.00 12.00 0.00 -1.20 0.00 -2.00 0.00 4.00 0.00 -12.00 0.00 10.00 0.00 1.50 0.50 1.50 -0.50 5.00 0.00 12.00 0.00 9.00 0.00 -1.20 0.60 -1.20 -0.60 29.00 0.00 -20.00 0.00 4.00 0.00 0.34 0.14 0.34 -0.14

Page 154: Manual de PL1 - Completo

**********************************************************************

Obs: O programa esta' feito para impressao nas 120 posicoes do formulario, no entanto o lay-out apresentado esta' com outras proporcoes, ocupando apenas 65 posicoes.

18. ARQUIVOS

Page 197

SUMARIO _______

1. CONCEITOS BASICOS . . . . . . . . . . . . . . . . . . . . . . . . 2 1.1 NOCOES ELEMENTARES . . . . . . . . . . . . . . . . . . . . . . . 2 1.2 FORMULARIO DE PROGRAMACAO . . . . . . . . . . . . . . . . . . . . 3 1.3 CONCEITO DE COMANDO . . . . . . . . . . . . . . . . . . . . . . . 4 1.4 LABEL OU ROTULO DE COMANDO . . . . . . . . . . . . . . . . . . . 4 1.5 EXEMPLO DE UM PROGRAMA EM PL/1 . . . . . . . . . . . . . . . . . 4 1.6 IDENTIFICADORES . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.7 CONJUNTOS DE CARACTERES . . . . . . . . . . . . . . . . . . . . . 5 1.8 REGRAS DOS IDENTIFICADORES . . . . . . . . . . . . . . . . . . . 9

2. OPERACOES E EXPRESSOES . . . . . . . . . . . . . . . . . . . . . . 10 2.1 INTRODUCAO . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.2 OPERADORES . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.3 HIERARQUIA DAS OPERACOES . . . . . . . . . . . . . . . . . . . . 12 2.4 EXPRESSAO ARITMETICA . . . . . . . . . . . . . . . . . . . . . . 13 2.5 EXPRESSAO DE COMPARACAO . . . . . . . . . . . . . . . . . . . . . 13 2.6 EXPRESSAO LOGICA - String de Bits . . . . . . . . . . . . . . . . 13 2.7 EXPRESSAO DE CONCATENACAO - String de Caracteres . . . . . . . . 14 2.8. CONSTANTES E VARIAVEIS . . . . . . . . . . . . . . . . . . . . . 15

3. PROGRAMACAO ELEMENTAR . . . . . . . . . . . . . . . . . . . . . . 16 3.1. DECLARACAO DE VARIAVEIS E CONSTANTES . . . . . . . . . . . . . . 16 3.2. COMANDO DE ATRIBUICAO . . . . . . . . . . . . . . . . . . . . . 17 3.3. COMANDO LIST . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.4. COPY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.5. PAGE, SKIP e LINE . . . . . . . . . . . . . . . . . . . . . . . 20 3.6. UM PROGRAMA ELEMENTAR . . . . . . . . . . . . . . . . . . . . . 21 3.7. USO DE COMENTARIOS EM PROGRAMACAO . . . . . . . . . . . . . . . 23 3.8. APLICACAO . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

4. DECLARACOES DE VARIAVEIS . . . . . . . . . . . . . . . . . . . . . 26 4.1. COMANDO DECLARE . . . . . . . . . . . . . . . . . . . . . . . . 26 4.2. REAL DECIMAL FIXED(p,q) . . . . . . . . . . . . . . . . . . . . 27 4.3. REAL BINARY FIXED(p,q) . . . . . . . . . . . . . . . . . . . . . 28 4.4. REAL DECIMAL FLOAT(p) . . . . . . . . . . . . . . . . . . . . . 28 4.5. REAL BINARY FLOAT(p) . . . . . . . . . . . . . . . . . . . . . . 29 4.6. COMPLEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 4.7. CHARACTER(n) . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.8. BIT(n) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.9. VARYING . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.10. INITIAL(m) . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Page 155: Manual de PL1 - Completo

4.11. LABEL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.12.DECLARACAO PARCIAL DE VARIAVEIS . . . . . . . . . . . . . . . . 32 4.13. ORDEM DOS ATRIBUTOS NO COMANDO DECLARE . . . . . . . . . . . . 33 4.14. MAIS EXEMPLOS DE APLICACAO DO COMANDO LIST . . . . . . . . . . 33

5. CONVERSOES EM EXPRESSOES ARITMETICAS . . . . . . . . . . . . . . . 38 5.1. INTRODUCAO . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 5.2. EXEMPLOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

6. ARRAY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

Sumario

Page 198

6.1 INTRODUCAO . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 6.2. DIMENSAO DE ARRAYS . . . . . . . . . . . . . . . . . . . . . . . 43 6.3. EXEMPLOS DE ARRAYS . . . . . . . . . . . . . . . . . . . . . . . 44 6.4. LIMITES INFERIORES E SUPERIORES NA DIMENSAO DE ARRAYS . . . . . 45 6.5. USO DE ARRAY EM EXPRESSOES E NO COMANDO LIST . . . . . . . . . . 46 6.6. USO DO ASTERISCO EM ARRAYS (Cross Sections) . . . . . . . . . . 47 6.7. APLICACOES . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

7. COMANDOS DE DESVIOS . . . . . . . . . . . . . . . . . . . . . . . 51 7.1. INTRODUCAO . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 7.2. COMANDO DE DESVIO INCONDICIONAL (GOTO) . . . . . . . . . . . . . 51 7.3. COMANDOS DE DESVIOS CONDICIONAIS . . . . . . . . . . . . . . . . 52 7.4. PREFIXO DE CONDICAO . . . . . . . . . . . . . . . . . . . . . . 62 7.5 APLICACOES . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

8. COMANDO " DO " . . . . . . . . . . . . . . . . . . . . . . . . . . 67 8.1. COMANDO DE EXECUCAO DE 'LACOS' . . . . . . . . . . . . . . . . . 67 8.2. O COMANDO 'DO' . . . . . . . . . . . . . . . . . . . . . . . . . 67 8.3. EXEMPLOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 8.4. APLICACOES . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

9. FUNCOES INTERNAS . . . . . . . . . . . . . . . . . . . . . . . . . 74 9.1. INTRODUCAO . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 9.2. FUNCOES ARITMETICAS . . . . . . . . . . . . . . . . . . . . . . 74 9.3. FUNCOES MATEMATICAS . . . . . . . . . . . . . . . . . . . . . . 76 9.4 FUNCOES " STRING " . . . . . . . . . . . . . . . . . . . . . . . 77 9.5. FUNCOES DE ARRAYS . . . . . . . . . . . . . . . . . . . . . . . 80 9.6. FUNCOES SEM ARGUMENTOS . . . . . . . . . . . . . . . . . . . . . 81 9.7. PSEUDOVARIAVEIS . . . . . . . . . . . . . . . . . . . . . . . . 81 9.8. APLICACOES . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

10. COMANDO "DATA" DE ENTRADA E SAIDA . . . . . . . . . . . . . . . . 86 10.1. INTRODUCAO . . . . . . . . . . . . . . . . . . . . . . . . . . 86 10.2. GET DATA . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 10.3. PUT DATA . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 10.4. APLICACOES . . . . . . . . . . . . . . . . . . . . . . . . . . 88

11. ESPECIFICACAO "PICTURE" . . . . . . . . . . . . . . . . . . . . . 89 11.1. INTRODUCAO . . . . . . . . . . . . . . . . . . . . . . . . . . 89 11.2. PICTURE DE CARACTERES . . . . . . . . . . . . . . . . . . . . . 89 11.3. PICTURE NUMERICA . . . . . . . . . . . . . . . . . . . . . . . 90 11.4. CONVERSOES . . . . . . . . . . . . . . . . . . . . . . . . . . 93 11.5. APLICACOES . . . . . . . . . . . . . . . . . . . . . . . . . . 94

12. ESTRUTURAS . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 12.1. INTRODUCAO . . . . . . . . . . . . . . . . . . . . . . . . . . 96 12.2. REFERENCIA QUALIFICADA . . . . . . . . . . . . . . . . . . . . 98 12.3. ARRAY DE ESTRUTURAS . . . . . . . . . . . . . . . . . . . . . 100 12.4. EXPRESSAO DE ESTRUTURAS . . . . . . . . . . . . . . . . . . . 103 12.5. BY NAME . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 12.6. LIKE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 12.7. APLICACAO . . . . . . . . . . . . . . . . . . . . . . . . . . 107

13. COMANDO 'EDIT' DE ENTRADA E SAIDA . . . . . . . . . . . . . . . 109

Page 156: Manual de PL1 - Completo

13.1. INTRODUCAO . . . . . . . . . . . . . . . . . . . . . . . . . 109

Sumario

Page 199

13.2. ITENS DE FORMAT DE CONTROLE . . . . . . . . . . . . . . . . . 109 13.3. ITENS DE FORMAT DE DADOS . . . . . . . . . . . . . . . . . . 110 13.4. EXEMPLOS . . . . . . . . . . . . . . . . . . . . . . . . . . 114 13.5. FORMAT REMOTO . . . . . . . . . . . . . . . . . . . . . . . . 118 13.6. APLICACOES . . . . . . . . . . . . . . . . . . . . . . . . . 118

14. AREAS COMUNS NA MEMORIA . . . . . . . . . . . . . . . . . . . . 120 14.1. INTRODUCAO . . . . . . . . . . . . . . . . . . . . . . . . . 120 14.2. OPCAO STRING DE E/S . . . . . . . . . . . . . . . . . . . . . 120 14.3. DEFINED . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 14.4. DEFINICAO DE SOBREPOSICAO . . . . . . . . . . . . . . . . . . 123 14.5. DEFINICAO DE CORRESPONDENCIA . . . . . . . . . . . . . . . . 124 14.6. EXEMPLOS . . . . . . . . . . . . . . . . . . . . . . . . . . 126

15. BLOCOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 15.1. BLOCO BEGIN, BLOCO PROCEDURE,GRUPO DO . . . . . . . . . . . . 128 15.2. "SCOPE" DE IDENTIFICADORES . . . . . . . . . . . . . . . . . 131 15.3. BLOCOS INTERNOS E EXTERNOS . . . . . . . . . . . . . . . . . 132 15.4. ATIVACAO DE BLOCOS PROCEDURE . . . . . . . . . . . . . . . . 133 15.5. ATRIBUTOS INTERNAL E EXTERNAL . . . . . . . . . . . . . . . . 135 15.6. APLICACOES . . . . . . . . . . . . . . . . . . . . . . . . . 136

16. SUBPROGRAMAS . . . . . . . . . . . . . . . . . . . . . . . . . 140 16.1. SUB-ROTINAS E FUNCOES . . . . . . . . . . . . . . . . . . . . 140 16.2. PARAMETROS E ARGUMENTOS . . . . . . . . . . . . . . . . . . . 141 16.3. PARAMETROS/ARGUMENTOS E ATRIBUTO "EXTERNAL" . . . . . . . . . 142 16.4. TIPOS DE ELEMENTOS NAS LISTAS DE ARGUMENTOS E DE PARAMETROS . 144 16.5. ATRIBUTOS ENTRY E RETURNS . . . . . . . . . . . . . . . . . . 145 16.6. ATRIBUTO INITIAL CALL . . . . . . . . . . . . . . . . . . . . 147 16.7. APLICACOES . . . . . . . . . . . . . . . . . . . . . . . . . 147

17. ALOCACAO DE MEMORIA . . . . . . . . . . . . . . . . . . . . . . 152 17.1. INTRODUCAO . . . . . . . . . . . . . . . . . . . . . . . . . 152 17.2. STATIC . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 17.3. AUTOMATIC . . . . . . . . . . . . . . . . . . . . . . . . . . 153 17.4. CONTROLLED . . . . . . . . . . . . . . . . . . . . . . . . . 153 17.5. CONTROLE NO COMPRIMENTO DE "STRINGS" . . . . . . . . . . . . 154 17.6. CONTROLE NO DIMENSIONAMENTO DE ARRAYS . . . . . . . . . . . . 155 17.7. BUILT-IN ALLOCATION . . . . . . . . . . . . . . . . . . . . . 156 17.8. BASED . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 17.9. ESPACOS OCUPADOS NA MEMORIA . . . . . . . . . . . . . . . . . 167 17.10. APLICACOES . . . . . . . . . . . . . . . . . . . . . . . . . 169

18. ARQUIVOS . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 18.1. INTRODUCAO . . . . . . . . . . . . . . . . . . . . . . . . . 174 18.2. ATRIBUTOS PARA ARQUIVOS . . . . . . . . . . . . . . . . . . . 175 18.3. COMANDOS OPEN E CLOSE . . . . . . . . . . . . . . . . . . . . 176 18.4. ARQUIVOS STREAM . . . . . . . . . . . . . . . . . . . . . . . 177 18.5. ARQUIVOS PRINT . . . . . . . . . . . . . . . . . . . . . . . 179 18.6. ARQUIVOS RECORD . . . . . . . . . . . . . . . . . . . . . . . 182 18.7. ATRIBUTO "ENVIRONMENT" . . . . . . . . . . . . . . . . . . . 183 18.8. COMANDOS DE ACESSO AOS ARQUIVOS RECORD . . . . . . . . . . . 185 18.9. CTLASA E CTL360 . . . . . . . . . . . . . . . . . . . . . . . 188 18.10. OPCAO 'TITLE' PARA ARQUIVOS . . . . . . . . . . . . . . . . 192 18.11. APLICACAO . . . . . . . . . . . . . . . . . . . . . . . . . 194

Sumario