Prévia do material em texto
José Augusto N. G. Manzano ORCID: 0000-0001-9248-7765 PROGRAMAÇÃO COBOL PARA WINDOWS COM OpenCobol IDE 4.7.6 PRIMEIROS PASSOS COM FORMATO FIXO DIRETO AO PONTO GnuCOBOL 3.1.2 1ª Edição São Paulo 2021 - Propes Vivens © Copyright 2021 by José Augusto N. G. Manzano / Propes Vivens. Todos os direitos reservados. Proibida a reprodução total ou parcial, por qualquer meio ou processo, especialmente por sistemas gráficos, microfílmicos, fotográficos, reprográficos, fonográficos, videográficos, internet, e-books. Vedada a memorização e/ou recuperação total ou parcial em qualquer sistema de processamento de dados e a inclusão de qualquer parte da obra em qualquer programa jus cibernético existentes ou que a venham existir. Essas proibições aplicam-se também às características gráficas da obra e à sua editoração, exceto pelo exporto no próximo parágrafo. A violação dos direitos autorais é punível como crime (art. 184 e parágrafos, do Código Penal, conforme Lei no 10.695, de 07.01.2003) com pena de reclusão, de dois a quatro anos, e multa, conjuntamente com busca e apreensão e indenizações diversas (artigos 102 e 103 parágrafo único, 104, 105, 106 e 107 itens 1, 2 e 3 da Lei no 9.610, de 19.06.1998, Lei dos Direitos Autorais). Esta obra é distribuída gratuitamente em formato digital (somente em PDF) apenas e tão somente no sítio do autor (www.manzano.pro.br) e na forma impressa comercialmente e disponi- bilizada nas plataformas Clube de Autores e Agbook. Nenhum outro local da Internet ou fora dela está autorizado a distribuir, seja gratuitamente ou comercialmente este material. Não é permitido o compartilhamento deste material em qualquer lugar ou por qualquer meio exceto o exposto neste parágrafo, bem como outro formato digital. Os infratores estão sujeitos a processo judicial. O Autor acredita que as informações aqui apresentadas estão corretas e podem ser utilizadas para qualquer fim legal. Entretanto, não existe qualquer garantia, explícita ou implícita, de que o uso de tais procedimentos conduzirá sempre ao resultado desejado. O autor e a editora não poderão ser responsabilizados civilmente ou criminalmente. Os nomes de sítios e empresas, mencionados, foram utilizados apenas como ilustração, não havendo nenhum vínculo com a obra, não garantindo a sua existência nem divulgação a posteriori. Conteúdo de acordo com Acordo Ortográfico da Língua Portuguesa, desde 1 de janeiro de 2009. Imagem de capa com foto de Jeremy Bishop, disponível em Unsplash (https://unsplash.com/). Histórico de edições: 1ª. edição (set/2021) – versão 1.0 Produção, Capa e Editoração: José Augusto Navarro Garcia Manzano Edição: Propes Vivens FERRAMENTAS UTILIZADAS Produto: OpenCobolIDE 4.7.6 Desenvolvedor: Python Software Foundation Sítio: https://pypi.org/project/OpenCobolIDE/ Distribuidor: launchpad.net Sítio: https://launchpad.net/cobcide https://launchpad.net/cobcide/4.0/4.7.6 Produto: GnuCOBOL 3.1.2 Desenvolvedor: Bernard Giroud Brian Tiffin Keisuke Nishida Simon Sobisch Roger While Sítio: https://www.gnu.org/software/gnucobol/ REQUISITOS DE HARDWARE E SOFTWARE Computador padrão IBM-PC (Intel / AMD) de 32 ou 64 bits; Sistema operacional Windows 8.1, 10 ou superior; Mínimo de 8 GB de memória RAM disponível; 10 GB mínimo de espaço em disco rígido; Monitor padrão VGA (resolução mínima 1024 x 768 pontos); Dispositivo de apontamento (mouse); Acesso à Internet. AGRADECIMENTOS Primeiramente, e especialmente, à minha esposa Sandra e à minha filha Audrey, motivos de constante inspi- ração e apoio ao meu trabalho. Pela paciência aos momentos de ausência que tenho mesmo próximo, quan- do estou absorto em escrever, dedicando-me intensamente ao ensino e a você que me lê. Um agradecimento mais do que especial a contra-almirante da Marinha dos Estados Unidos da América, Ana- lista de Sistemas e Professora Grace Hopper (nascimento em 09/12/1906, falecimento em 01/01/1992) cria- dora da linguagem FLOW-MATIC e por ter colaborado como mentora no desenvolvimento da linguagem de programação COBOL que perdura em uso a décadas, sendo uma das linguagens de programação mais usa- das e importantes no mundo. Quero agradecer a Fabio Moraes de Carvalho pelas trocas de ideias e colaboração na realização deste traba- lho iniciado como um rascunho, que avançou por vezes nas madrugadas do período do início da pandemia da COVID-19 do início do ano de 2020 e seu efetivo desenvolvimento até meados do segundo semestre de 2021 quando no final de setembro foi concluído como livro. Não posso deixar de agradecer aos membros da comu- nidade SourceForge relacionados ao projeto GnuCOBOL: Simon Sobisch, László Erdősn, Ralph Linkletter, Eugenio Di Lorenzo e Vincent “Bryan” Coen pela solicitude e atenção no esclarecimento de dúvidas sobre o funcionamento e características do compilador e outras orientações. Quero agradecer a Rafael Ireno e ao expectador de meu canal no Youtube Claudiomar Ben Ysra'el que indi- retamente são responsáveis pela decisão que tomei em publicar esta obra. O Claudiomar em uma postagem no canal sugeriu que eu escrevesse um livro sobre COBOL e o Rafael esteve na escola e realizou uma pales- tra sobre a plataforma de Mainframe IBM Z e divulgou o evento Master the Mainframe para nossos alunos. Durante a palestra, lá pelas tantas um dos estudantes perguntou sobre a linguagem COBOL e se era usada? O Ireno não só confirmou o uso, como disse que a IBM estava de "olho" em profissionais com conhecimentos na linguagem. Alguns estudantes me olharam espantados, pois sempre disse em aula para darem-se a opor- tunidade em aprender COBOL. Espantaram-se, pois muitos achavam que era apenas “papo gordo” do pro- fessor. Atualmente não digo "aprendam COBOL", eu digo, "o que estão fazendo que não estão aprendendo COBOL". Ao término da palestra e da reação provocada nos estudantes achei que era hora de empenhar esforços em escrever um livro sobre a linguagem. Foi quando comecei a idealizar o trabalho que hoje é apre- sentado a toda comunidade de estudantes brasileiros. Obrigado Rafael, por corroborar de forma muito natural e indireta o que sempre digo em sala de aula, e assim dar-me a certeza de que eu não estava lutando contra moinhos de vento, obrigado Claudiomar pela sugestão. A todos os alunos que passaram e passam por minhas mãos, que acreditaram e acreditam na minha pessoa, que seguiram e seguem as orientações que passo; por me incentivarem continuamente quando me questio- nam, por me levarem a um patamar maior e por exigirem, assim, que eu pesquise mais. Vida longa e próspera. SUMÁRIO Capítulo 1 - COBOL 1.1 - Linguagem ................................................................................................................................................................. 23 1.2 - Ferramentas de trabalho ........................................................................................................................................... 24 1.3 - OpenCobolIDE ........................................................................................................................................................... 27 1.4 - Estrutura sintática ..................................................................................................................................................... 33 1.4.1 - IDENTIFICATION DIVISION ............................................................................................................................. 44 1.4.2 - ENVIRONMENT DIVISION ............................................................................................................................... 46 1.4.3 - DATA DIVISION ...............................................................................................................................................IBM-PC COMPATIVEL COBOL 41 Figura 1.42 – Perfuração da instrução: OBJECT-COMPUTER. IBM-PC COMPATIVEL Figura 1.43 – Perfuração da instrução: SPECIAL-NAMES. CONSOLE IS MEU_TERMINAL Figura 1.44 – Perfuração da instrução: LINHA EM BRANCO 42 PROGRAMAÇÃO COBOL Figura 1.45 – Perfuração da instrução: DATA DIVISION Figura 1.46 – Perfuração da instrução: LINHA EM BRANCO Figura 1.47 – Perfuração da instrução: PROCEDURE DIVISION COBOL 43 Figura 1.48 – Perfuração da instrução: DISPLAY "ALO, MUNDO!" UPON MEU_TERMINAL Figura 1.49 – Perfuração da instrução: STOP RUN Figura 1.50 – Perfuração da instrução: END PROGRAM PROG_ALO Veja que nas imagens dos cartões as colunas de 73 até 80 são mostradas a mesma informação definida. Como não se usa mais cartões perfurados as colunas de 73 até 80 de um código COBOL em formato fixo são omitidas. Note também a sequência de identificação de linhas entre as colunas 1 e 6 também omitidas devido ao fato de os ambientes de pro-gramação modernos não necessitarem mais deste recurso e por esta razão não são usados. 44 PROGRAMAÇÃO COBOL Exemplo de codificação em formato livre *> programa exemplo prog_alo prog_alo identification division. prog_alo program-id. prog_alo. prog_alo author. Augusto Manzano. prog_alo installation. Computador padrao IBM-PC, GnuCOBOL em Windows. prog_alo date-written. 10 de marco de 2020. prog_alo date-compiled. 10 de marco de 2020. prog_alo security. Sem restricao de uso e acesso. prog_alo remarks. Programa exemplo ao estilo ansi cobol-68. prog_alo prog_alo environment division. prog_alo configuration section. prog_alo source-computer. IBM-PC compativel. prog_alo object-computer. IBM-PC compativel. prog_alo special-names. console is meu_terminal. prog_alo prog_alo data division. prog_alo prog_alo procedure division. prog_alo display "Alo, mundo!" upon meu_terminal. prog_alo stop run. prog_alo end program prog_alo. PROG_ALO Ao olhar para os códigos do programa exemplo, tanto em formato fixo como livre, vê-se, praticamente, os mesmos comandos: não há diferença na estrutura sintática, exceto o uso do símbolo de comentário (*) em formato fixo e (*>) em formato livre. É claro que em formato livre os símbolos de continuidade (-) e (\) não são aplicados. Dentre os exemplos apresentados é possível notar o uso de divisões, seções e parágrafos: são quatro as divisões padrão encon-tradas em um programa COBOL (identificação, ambiente, dados e procedimento) definidas internamente, segundo a ordem indicada de uso (não se coloca as divisões sob outra ordem), como: IDENTIFICATION DIVISION ENVIRONMENT DIVISION DATA DIVISION PROCEDURE DIVISION O detalhamento dos recursos a seguir leva em consideração o fato de existirem códigos COBOL escritos a muito tempo e que esses estão ainda em execução (código legado). Muito do que se escreve de forma moderna em COBOL não seria possível de execução em computadores mais antigos e vice-versa. As descrições apresentadas de divisões a seguir não são completas, sendo concentrado apenas o mínimo necessário para a produção de programa básicos na linguagem, uma vez que este trabalho objetiva ser um material inicial de estudo da linguagem COBOL. Não há a pre-tensão de tratar o assunto em sua totalidade ou profundidade. 1.4.1 IDENTIFICATION DIVISION A divisão de identificação (IDENTIFICATION DIVISION) é a primeira estrutura a ser usada em um programa, tem por objetivo fornecer informações documentais do código de um programa e identifica-lo junto ao computador. Esta divisão pode basicamente fazer uso dos parágrafos: PROGRAM-ID, AUTHOR, INSTALLATION, DATE-WRITTEN, DATE- COMPILED, SECURITY e REMARKS. Uma característica dessa divisão é que ela é formada apenas por parágrafos e as informações nela contida não são implementadas pelo compilador no programa executável. Esses detalhes são tratados pelo compilador apenas como comentários (elementos de referência documental). O parágrafo PROGRAM-ID é obrigatório e tem por finalidade identificar na memória o nome de referência do programa que poderá ter até trinta caracteres (letras, números e ou hífen), mas somente os oito primeiros caracteres são significa- COBOL 45 tivos para identificar o programa no computador. Opcionalmente pode ser acrescida com a cláusula AS com a referên-cia de um nome de identificação grafado entre aspas inglesas. O parágrafo AUTHOR é opcional e tem por finalidade identificar o nome do desenvolvedor do código. O parágrafo INSTALLATION é opcional e tem por finalidade identificar a empresa ou local de desenvolvimento do pro-grama. O parágrafo DATE-WRITTEN é opcional e tem por finalidade identificar data de criação do programa. O parágrafo DATE-COMPILED é opcional e tem por finalidade identificar data de compilação do programa. O parágrafo SECURITY é opcional e tem por finalidade descrever informações sobre o nível de segurança utilizado no programa. O parágrafo REMARKS é opcional e tem por finalidade definir comentários adicionais sobre detalhes do programa. As cláusulas AUTHOR, INSTALLATION, DATE-WRITTEN, DATE-COMPILED, SECURITY e REMARKS (não se apli- cam mais). No compilador GnuCOBOL essas cláusulas são mantidas por questões de compatibilidade com o padrão 74. No padrão 85 são consideradas obsoletas e foram extinguidas a partir do padrão 2002, não sendo mais usadas. Considerando os elementos apresentados uma IDENTIFICATION DIVISION pode ser referenciada como: IDENTIFICATION DIVISION. PROGRAM-ID. AUTHOR. INSTALLATION. DATE-WRITTEN. DATE-COMPILED. SECURITY. REMARKS. A definição de parágrafos e sentenças na linguagem COBOL é finalizada com o uso de um ponto final como se estives-se escrevendo um texto qualquer de forma normal, ressaltando que um parágrafo pode ser formado por mais de uma sentença. Considerando o que é aceito como válido para a IDENTIFICATION DIVISION ter-se-á no mínimo o formato de citação: IDENTIFICATION DIVISION. PROGRAM-ID. Estrutura da definição válida para um programa exemplo apresentado a partir do padrão COBOL-85 (formato fixo): IDENTIFICATION DIVISION. PROGRAM-ID. PROG_ALO. * AUTOR ................: AUGUSTO MANZANO * INSTALACAO ...........: COMPUTADOR PADRAO IBM-PC, GNUCOBOL EM WINDOW * DATA DE CODIFICACAO ..: 10 DE MARCO DE 2021 * DATA DE COMPILACAO ...: 10 DE ABRIL DE 2021 * SEGURANCA ............: SEM RESTRICAO DE USO E ACESSO * OBS ..................: PROGRAMA EXEMPLO AO ESTILO ANSI COBOL-85 Estrutura da definição válida para um programa exemplo apresentado a partir do padrão COBOL-85 (formato livre): Identification Division. Program-Id. prog_alo.*> Autor ................: Augusto Manzano *> Instalacao ...........: Computador padrao IBM-PC, GnuCOBOL em Window *> Data de Codificacao ..: 10 de marco de 2021 *> Data de Compilacao ...: 10 de abril de 2021 *> Seguranca ............: Sem restricao de uso e acesso *> Obs ..................: Programa exemplo ao estilo ANSI COBOL-85 46 PROGRAMAÇÃO COBOL No passado os comandos da linguagem COBOL eram escritos com os caracteres em formato maiúsculo. Os compila-dores usados em microcomputadores (baixa plataforma) aceitam a definição em letras minúsculas, o que pode ocasio-nar uma série de estilos desastrosos dentro do código. Desta forma, sugere-se usar sempre o estilo de escrita com letras maiúsculas quando estiver em uso o formato fixo e usar o estilo de escrita com letras minúsculas quando estiver em uso formato livre. A cláusula PROGRAM-ID exige para a identificação de um programa o uso apenas de caracteres alfanuméricos e sub-linhado (underline). Nenhum outro caractere poderá ser usado para a composição do nome de referência de um pro-grama. O nome de referência deve possuir no máximo oito caracteres. 1.4.2 ENVIRONMENT DIVISION A divisão de ambiente (ENVIRONMENT DIVISION) é a segunda estrutura a ser usada, tem como objetivo descrever a configuração do computador usado na compilação e execução de um programa. Assim sendo, esta divisão apresenta detalhes sobre a interface do programa com os periféricos usados e sua ligação com o ambiente operacional externo, principalmente no que tange ao uso de arquivos lógicos mapeados a partir da definição de arquivos físicos e a relação operacional com as unidades de entrada e saída. Esta divisão utiliza as seções: CONFIGURATION e INPUT-OUTPUT. A seção CONFIGURATION SECTION destina-se a descrever a estrutura de configuração do ambiente, sendo compos-ta pelos parágrafos: SOURCE-COMPUTER – componente obrigatório que descreve o padrão do computador usado na compilação do código fonte. É o computador do programador; OBJECT-COMPUTER – componente obrigatório que descreve o padrão do computador usado na execução do código compilado. É o computador do usuário; SPECIAL-NAMES – componente opcional usado para especificar ações de formatação de comportamento de certo programa. Pode ser usado com cláusulas, como CONSOLE IS, CURRENCY SIGN IS ou DECIMAL-POINT IS. A clausula CONSOLE IS permite especificar um nome de identificação para o direcionamento a um determinado ter-minal de vídeo a ser usado com o comando DISPLAY, a clausula DECIMAL-POINT IS com a indicação COMMA permite especificar a mudança de comportamento do símbolo de separação de decimais de ponto para vírgula e a cláusula CURRENCY SIGN IS é usada quando há o desejo de se alterar a apresentação do símbolo monetário de dólar por outro símbolo especificado. Além das cláusulas indicadas existem outras que estão sendo propositalmen-te omitidas. A seção INPUT-OUTPUT SECTION destina-se a descrever a configuração do ambiente de gravação e leitura, sendo composta pelos parágrafos FILE-CONTROL e I-O-CONTROL, usados na definição de arquivos e de suas ligações com arquivos físicos e periféricos de entrada e saída: FILE-CONTROL – componente opcional que especifica a ligação dos arquivos de dados com as unidades de en-trada e saída que o programa fará uso; I-O-CONTROL – componente opcional que especifica as áreas de armazenamento dos arquivos compartilhados na memória sendo utilizado para otimizar as operações de entrada e saída de dados. Considerando os elementos apresentados uma ENVIRONMENT DIVISION pode ser estruturalmente referenciada co-mo: ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. OBJECT-COMPUTER. SPECIAL-NAMES. INPUT-OUTPUT SECTION. FILE-CONTROL. I-O-CONTROL. COBOL 47 1.4.3 DATA DIVISION A divisão de dados (DATA DIVISION) é a terceira estrutura a ser usada, tem como objetivo definir uma área de aloca- ção de memória para o processamento de dados de um programa controlando os layouts de uso de variáveis, registros, constantes, tabelas, arquivos de entrada e saída, parâmetros de entrada de dados, parâmetros de retorno de dados, áreas de tratamento de dados, locais de acessos a tabelas de dados, relatórios e telas exibidas. Esta divisão usa as seções: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT e SCREEN. A seção FILE SECTION destina-se a descrever os layouts e características dos registros usados nos arquivos de en-trada e saída de um programa. A seção WORKING-STORAGE SECTION destina-se a descrever as áreas temporárias globais de operação do pro-grama usadas com a definição de variáveis, constantes e registros de dados no processamento de dados que não são parte das ações de entrada e da saída de arquivos externos, mas que são necessários ao processamento interno do programa em uso. A seção LOCAL-STORAGE SECTION assemelhasse a seção WORKING-STORAGE tendo como diferencial o fato de que os dados operacionalizados são inicializados toda vez que um programa é iniciado, ou seja, especifica dados locais. A cada chamada, os itens de dados definidos na seção são realocados e inicializados. A seção LINKAGE SECTION destina-se a descrever a área de memória a ser utilizada para compartilhamento de da-dos entre programa principal e sub-rotinas, descreve os dados que são passados entre programas. A seção REPORT SECTION destina-se a descrever o layout de relatórios a serem gerados e impressos a partir do uso de um recurso chamado escritor de relatórios. A seção SCREEN SECTION destina-se a descrever o layout a ser usado na apresentação de dados no terminal, sendo um recurso encontrado nos compiladores COBOL de baixa plataforma. A linguagem COBOL na alta plataforma (compu-tadores de grande porte) não possui esta seção. Considerando os elementos comentados, uma DATA DIVISION pode ser estruturalmente referenciada como: DATA DIVISION. FILE SECTION. WORKING-STORAGE SECTION. LOCAL-STORAGE SECTION. LINKAGE SECTION. REPORT SECTION. SCREEN SECTION. 1.4.4 PROCEDURE DIVISION A divisão de procedimentos (PROCEDURE DIVISION) é a quarta estrutura a ser usada, tem como objetivo acomodar o código que efetuará o processamento dos dados de um programa, sendo esta, a divisão mais importante entre todas as usadas em um programa COBOL. As divisões IDENTIFICATION, ENVIRONMENT e DATA operam com seções e/ou parágrafos predefinidos. No entanto, a divisão de procedimento permite que o programador defina de maneira customizada suas próprias declarações, pará-grafos e seções a fim de organizar a estrutura lógica de um programa. A definição da área de declaração é realizada com o uso do comando DECLARATIVES seguido de um ponto final. Este recurso é opcional, mas quando em uso deve ser definido imediatamente após PROCEDURE DIVISION, podendo ser definido em qualquer uma das colunas do campo A para o formulário (tanto físico em papel, como virtual junto a tela da IDE. O fechamento de uma área de declaração é realizado com o uso da instrução END DECLARATIVES seguida de um ponto final. A definição de uma área de declaração é usada para manipular e gerenciar ocorrências de erros de exceção em opera-ções de E/S (entrada e saída) sob o uso de arquivos quando estes, por algum motivo, ocorrem na operação de certo programa, ao invés de verificar isoladamente o código do status de erro após cada instrução de E/S. 48 PROGRAMAÇÃO COBOL A estrutura de definição de área de declaração segue o esquemasintático: PROCEDURE DIVISION. DECLARATIVES. [instruções para tratamento de exceção]. STOP RUN. END DECLARATIVES. A área declarada entre o comando DECLARATIVES e a instrução END DECLARATIVES pode conter sequencias de instruções para realizar ações operacionais, bem como ser composta com o uso de seções e/ou parágrafos. Para a criação de parágrafos basta que em PROCEDURE DIVISION ou após o comando DECLARATIVES seja defini-da uma sequência de caracteres (letras, números ou hifens) encerradas por um ponto final. Normalmente usa-se na definição do nome de parágrafo, antes do ponto final um hífen seguido da palavra PARA ou a definição inicial do termo PARAGRAPH ou letra P com um hífen e o nome do parágrafo (há programadores que não utilizam essas estratégias ou fazem uso de outras nomenclaturas). Apesar dos nomes de parágrafos aceitarem o uso do caractere linha baixa (underline), mas este estilo não é comum e não deve ser utilizado. Um parágrafo é encerrado quando outro parágrafo é iniciado, quando ocorre a definição de seções, quando chega-se ao final de uma PROCEDURE DIVISION, quando se encontra o comando USE ou quando se encontra a instrução END DECLARATIVES podendo-se defini-lo em qualquer uma das colunas do campo A para o formulário (tanto físico em papel, como virtual junto a tela da IDE). Os nomes de parágrafos somente poderão se repetir se definidos em diferentes seções. A estrutura básica de criação de parágrafos na PROCEDURE DIVISION deve seguir o esquema sintático: PROCEDURE DIVISION. PARAGRAPH-NOMES. [instruções]. A001-FIRST-PARA. [instruções]. 0001-INICIO-PROGRAMA. [instruções]. P-1000. [instruções]. MAIN-PROGRAM. [instruções]. STOP RUN. A estrutura básica de criação parágrafos entre DECLARATIVES e END DECLARATIVES deve seguir o esquema sintá-tico a seguir, observado abaixo da área de declaração o trecho de início principal do programa: PROCEDURE DIVISION. DECLARATIVES. PARAGRAPH-ERRO. [instruções para tratamento de exceção]. A001-FALHA-PARA. [instruções para tratamento de exceção]. OUT-1000. [instruções para tratamento de exceção]. END DECLARATIVES. PROGRAMA-PRINCIPAL-INICIO. [instruções] STOP RUN. Para a criação de seções deve-se definir um termo de identificação seguido do comando SECTION com a indicação opcional de um valor numérico para identificação do segmento, normalmente definido a partir da quadragésima coluna na área A do formulário fixo. A definição de uma seção encerra-se quando outra seção é iniciada, no final da PROCEDURE DIVISION ou quando encontrada a instrução END DECLARATIVES caso seja definida dentro de uma área de declaração, podendo uma COBOL 49 seção ser definida em qualquer uma das colunas do campo A para o formulário (tanto físico em papel, como virtual junto a tela da IDE). O nome definido para uma seção não poderá ser repetido dentro do programa. A estrutura básica de criação de seções na PROCEDURE DIVISION deve seguir o esquema sintático: PROCEDURE DIVISION. SECAO1 SECTION 10. [instruções]. SECAO2 SECTION 20. [instruções]. DECL-1 SECTION. [instruções]. SECAO3 SECTION. [instruções]. STOP RUN. A estrutura básica de criação de seções com parágrafos na PROCEDURE DIVISION deve seguir o esquema sintático: PROCEDURE DIVISION. SECAO1 SECTION 10. PARAGRAPH-NOMES. [instruções]. SECAO2 SECTION 20. [instruções]. DECL-1 SECTION. [instruções]. A001-FIRST-PARA. [instruções]. SECAO3 SECTION. [instruções]. STOP RUN. A estrutura básica de criação seções entre DECLARATIVES e END DECLARATIVES deve seguir o esquema sintático a seguir: PROCEDURE DIVISION. DECLARATIVES. SECAO1-ERROS SECTION 10. PARAGRAPH-ERRO. [instruções para tratamento de exceção]. A001-FALHA-PARA. [instruções para tratamento de exceção]. SECAO2-ERROS SECTION. OUT-1000. [instruções para tratamento de exceção]. END DECLARATIVES. PROGRAMA-PRINCIPAL-INICIO. [instruções]. STOP RUN. Como comentado a linguagem COBOL foi projetada para parecer-se ao máximo com o idioma inglês escrito e por con-seguinte sua estrutura textual. A partir desta característica o código COBOL busca se parecer ao máximo com a estru-tura escrita do idioma inglês. Desta forma declarações se parecem com capítulos, seções se parecem com tópicos e sentenças são formados por um ou mais parágrafos. O uso dos recursos relacionados a definição de seções e parágrafos são opcionais e podem ser omitidos sem prejuízo direto de execução do programa. Usar ou não esses recursos pode ser uma questão pessoal ou de regras aplicadas a partir do ambiente de trabalho da organização. Segundo, N. Bredin nos Estados Unidos da América há o hábito de se usar seção em detrimento a parágrafo e na Europa ocorre o inverso (https://stackoverflow.com/questions/1675461). 50 PROGRAMAÇÃO COBOL No entanto, usar estes recursos pode tornar o código de um programa melhor esquematizado apesar da aparente ver-bosidade que possa existir. 1.5 OPERAÇÕES INICIAIS A partir da visão geral dos detalhes da linguagem COBOL apresentados, torna-se interessante iniciar um estudo básico com a estrutura do programa mais simples possível de ser codificada na linguagem: o famoso código “ALO, MUNDO!” demonstrando especificamente a PROCEDURE DIVISION. Se perguntar a qualquer programador COBOL experiente que trabalhe com alta plataforma (conhecidos como coboleiros) sobre escrever este tipo de programa, possivelmente terá como resposta algo como: tínhamos coisas mais importantes para escrever na linguagem do que fazer isso. Consi-dere então para a codificação apenas o trecho grafado em azul. ------ LINHAS ------ 1 2 3 4 5 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. ALOMUNDO. PROCEDURE DIVISION. DISPLAY "ALO, MUNDO!". STOP RUN. ------------------------------------------------------------------------ Observe o código anterior escrito com o estilo de formatação na forma fixa e sua representação no editor COBOL usa-do em um computador IBM System z, como demonstra a figura 1.51. Figura 1.51 – Código “ALO, MUNDO!” em IBM System Z (imagem: Fabio Moraes de Carvalho) Os programas apresentados nesta obra são escritos de acordo com o uso do formulário fixo (modo padrão do ambiente OpenCobolIDE), com os comandos da linguagem grafados em formato maiúsculo, respeitando ao máximo a tradição de codificação da linguagem. COBOL 51 Na sequência junto ao ambiente OpenCobolIDE abra uma nova instância vazia para edição, definindo para o arquivo de programa fonte o nome c01ex03, selecionando a extensão COB e estabelecendo a pasta COBOL da pasta Documen- tos. A figura 1.52 mostra o ambiente OpenCobolIDE com o programa indicado. Escreva então o programa, deixando a última linha em branco (tradição na programação COBOL), salve o arquivo e efetue sua compilação e execução. Figura 1.52 – Código exemplo no ambiente OpenCobolIDE O código do programa c01ex03.cob na figura 1.49 mostra o menor programa possível de ser escrito em COBOL man- tendo no código com os detalhes mínimos necessários, o qual executa as seguintes ações: A linha 1 define a divisão de identificação do programa a partir da instrução “IDENTIFICATION DIVISION.”; A linha 2 está define o nome de identificação do programa com a instrução “PROGRAM-ID.ALOMUNDO.”; A linha 3 define a divisão de procedimento do programa a partir da instrução “PROCEDURE DIVISION.”; A linha 4 efetua a partir do uso do comando DISPLAY a apresentação da mensagem “ALO, MUNDO!”; A linha 5 a partir dos comandos STOP e RUN efetua-se a parada da execução do programa. As mensagens a serem apresentadas na linguagem com uso do comando DISPLAY na forma de cadeias, como mos-trado na linha 4, devem ser delimitadas com o uso de aspas inglesas ou aspas simples. Fica a critério escolher o estilo. A instrução STOP RUN tem por finalidade retornar o controle de execução de um programa para o recurso que fez a chamada deste programa ao limite de controle mais próximo desta chamada, parando a execução do processamento. Neste caso, em particular, o programa foi chamado a partir do sistema operacional, sendo então o retorno do programa devolvido ao sistema operacional que é neste caso o limite mais próximo de controle da chamada anteriormente efetu-ado. Na sequência, no ambiente OpenCobolIDE abra uma nova instância vazia para edição, defina para o nome c01ex04, selecione a extensão COB e estabeleça a pasta COBOL da pasta Documentos e codifique o programa a seguir grafa- do em azul. Este programa demostra o uso de parágrafo indicando a instrução em tom laranja na linha 4. Há regras que orientam que a PROCEDURE DIVISION tenha no mínimo um parágrafo. ------ LINHAS ------ 1 2 3 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. ALOMUNDO. PROCEDURE DIVISION. ------------------------------------------------------------------------ 52 PROGRAMAÇÃO COBOL ------ LINHAS ------ 4 5 6 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- PROG-PRINCIPAL-PARA. DISPLAY "ALO, MUNDO!". STOP RUN. ------------------------------------------------------------------------ Observe na linha 4 do programa c01ex04.cob a definição do parágrafo PROG-PRINCIPAL-PARA identificando parte do código como sendo um trecho principal de operação a partir de um parágrafo. Na sequência, no ambiente OpenCobolIDE abra uma nova instância vazia para edição, defina para o nome c01ex05, selecione a extensão COB e estabeleça a pasta COBOL da pasta Documentos e codifique o programa a seguir grafa-do em azul. Este programa demostra o uso de seção em tom vermelho na linha 4. ------ LINHAS ------ 1 2 3 4 5 6 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. ALOMUNDO. PROCEDURE DIVISION. PRINCIPAL SECTION. DISPLAY "ALO, MUNDO!". STOP RUN. ------------------------------------------------------------------------ Observe na linha 4 do programa c01ex05.cob a definição da seção PRINCIPAL SECTION identificando o código com uma seção principal. Na sequência, no ambiente OpenCobolIDE abra uma nova instância vazia para edição, defina para o nome c01ex06, selecione a extensão COB e estabeleça a pasta COBOL da pasta Documentos e codifique o programa a seguir grafa-do em azul. Este programa demostra o uso de seção demarcada em tom vermelho na linha 4 com parágrafo demarcado em tom laranja na linha 5. ------ LINHAS ------ 1 2 3 4 5 6 7 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. ALOMUNDO. PROCEDURE DIVISION. PRINCIPAL SECTION. PROG-PRINCIPAL-PARA. DISPLAY "ALO, MUNDO!". STOP RUN. ------------------------------------------------------------------------ Observe nas linhas 4 e 5 do programa c01ex06.cob respectivamente as definições da seção PRINCIPAL SECTION e do parágrafo PROG-PRINCIPAL-PARA identificando o código com uma seção principal com a definição de um pará- grafo. Os exemplos de codificação anteriores mostram de forma mínima as definições de seções e parágrafos. Na prática os parágrafos são usados para separar o código em lotes de operação dentro de certa característica operacional que po-dem estar definidos em seções. Esta é a forma estruturada que a linguagem COBOL possui para auxiliar a organização do código baseado em certa temática dentro das colunas do campo A do formulário. COBOL 53 Desta forma, apesar de não comum, o código escrito no compilador GnuCOBOL poderá ser organizado de forma en-dentada a fim de acomodar visualmente a estrutura das divisões, seções e parágrafos dentro do campo A. Assim sen-do, no ambiente OpenCobolIDE abra uma nova instância vazia para edição, defina para o nome c01ex07, selecione a extensão COB e estabeleça a pasta COBOL da pasta Documentos e codifique o programa a seguir grafado em azul com as marcações de seção em vermelho e parágrafo em laranja. ------ LINHAS ------ 1 2 3 4 5 6 7 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. ALOMUNDO. PROCEDURE DIVISION. PRINCIPAL SECTION. PROG-PRINCIPAL-PARA. DISPLAY "ALO, MUNDO!". STOP RUN. ------------------------------------------------------------------------ Veja que no código do programa c01ex07.cob a definição da IDENTIFICATION DIVISION é estabelecida na coluna 8, a definição da seção na coluna 9 e a definição do parágrafo na coluna 10. Como comentado, apesar desta forma de formatação não ser comum ela é válida uma vez que esses elementos devem ser declarados na área do campo A. A regra determina usar o campo A mas não restringe o posicionamento de colunas dentro do campo. Um recurso comum usado para melhorar a legibilidade do código é a definição de linhas em branco entre certos grupos de ação do programa. Assim sendo, no ambiente OpenCobolIDE abra uma nova instância vazia para edição, defina para o nome c01ex08, selecione a extensão COB e estabeleça a pasta COBOL da pasta Documentos e codifique o programa a seguir grafado em azul com as marcações de seção em vermelho e parágrafo em laranja seguindo o estilo mais tradicional ao manter a divisão, seção e parágrafo alinhados na coluna 8 do campo A. ------ LINHAS ------ 1 2 3 4 5 6 7 8 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. ALOMUNDO. PROCEDURE DIVISION. PRINCIPAL SECTION. PROG-PRINCIPAL-PARA. DISPLAY "ALO, MUNDO!". STOP RUN. ------------------------------------------------------------------------ Mesmo utilizando-se a forma tradicional de codificação o ambiente OpenCobolIDE mantem a apresentação de uma forma endentada da estrutura hierárquica do có-digo. Veja na figura 1.53 a indicação de um trecho da janela Navigation. A janela Navigation encontra-se, normalmente,posicionada a direita do ambiente mostrando o alinhamento em cascata das divisões, seções e parágrafos que com-põem um programa escrito em linguagem COBOL. Como comentado, o foco deste livro é a escrita de programas em estilo fixo, uma vez que a grande maioria dos compiladores COBOL partem deste princípio. No entanto, uma alternativa que pode ser usada caso não deseje trabalhar no formato fixo é fazer uso do termo SOURCE FORMAT FREE indicado a seguir. Figura 1.53 – Janela Navigator 54 PROGRAMAÇÃO COBOL ------ LINHAS ------ 1 2 3 4 5 6 7 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- OCOBOL >> SOURCE FORMAT FREE IDENTIFICATION DIVISION. PROGRAM-ID. ALOMUNDO. PROCEDURE DIVISION. DISPLAY "ALO, MUNDO!". STOP RUN. ------------------------------------------------------------------------ Observe que para desabilitar a verificação de uso da forma fixa basta acrescentar na primeira linha de código do pro- grama a diretiva >> SOURCE FORMAT FREE a partir da sétima ou oitava posição do formulário, tendo OCOBOL (de OpenCOBOL, também usado GCOBOL) como mero rótulo informativo, podendo ser omitido. Veja que você estará livre para escrever o programa da forma que quiser, em contra partida a diretiva >> SOURCE FORMAT IS FIXED é usada para estabelecer o formulário fixo. É possível até escrever programas alternando-se os modos fixo e livre. No entanto, lembre-se de que há um estilo de escrita que é seguido e respeitado a décadas, deve-se na prática evitar exageros. 1.6 WINDOWS TERMINAL E ATUALIZAÇÃO Anteriormente foi instruído fazer o desvio da forma de saída do programa OpenCobolIDE para a janela de terminal do sistema operacional para maior comodidade operacional por não ser a guia Outuput da janela Logs muito conveniente. Agora é necessário fazer pequenos ajustes na janela do terminal. Para realizar estes ajustes é importante que algum programa esteja em execução a partir do ambiente OpenCobolIDE, pois a janela de terminal apresentada pelo ambiente não é o terminal padrão do Windows, sendo uma janela fornecida pelo próprio ambiente. Portanto, considerando o ambiente OpenCobolIDE com o último programa editado (c01ex08.cob) observe junto a figura 1.54 a janela de terminal possivelmente apresentada em seu sistema. Esta janela é apresentada no tamanho de 120 colunas e 30 linhas com fundo em cor preto e fonte em cor cinza, poden-do ter esses elementos alterados a partir de um menu apresentado quando o ícone a esquerda da barra de títulos da janela é acionado. A figura 1.55 mostra o menu apresentado quando da seleção do ícone da barra de título. Figura 1.54 – Janela do modo Terminal Windows Figura 1.55 – Menu a partir do ícone da barra de título Na sequência selecione no menu a opção Propriedades e será apresentada a caixa de diálogo de mesmo nome como indica a figura 1.56 que oferece para uso as guias Opções, Fonte, Layout, Cores e Terminal. Selecione a guia Layout e altere em Tamanho da Janela a Largura para 80 e a Altura para 24 de modo que se tenha um formato de tela com 80 colunas e 24 linhas, como mostra a figura 1.57. COBOL 55 Figura 1.56 – Caixa de diálogo Propriedades Figura 1.57 – Tamanho 80 colunas e 24 linhas Outra alteração que poderá ser útil é estabelecer a alteração das cores da janela. Por exemplo com fundo branco e texto em preto. Para tanto, selecione a guia Cores e em Tela de Fundo selecione o quadro com a indicação da cor branca, depois em Texto da Tela selecione o quadro com a indicação da cor preta. Quanto as demais guias não há necessidade de alteração. Assim sendo, acione o botão OK. As mudanças solicitadas não são imediatamente aplicadas. Desta forma, feche a janela ativa e execute novamente o programa, neste caso c01ex08.cob e as mudanças efetuadas são apresentadas na janela do terminal como indica a figura 1.58. Figura 1.58 – Janela Terminal após mudanças Antes de concluir este capítulo cabe indicar a possibilidade de se fazer, caso deseje, a atualização do compilador Gnu- COBOL para uma versão mais recente do que a usada pelo ambiente OpenCobolIDE 4.7.6. Acesse o link https://www.arnoldtrembley.com/GC312- BDB-rename-7z-to-exe.7z para baixar o programa de insta- lação. Após baixar o arquivo altere seu nome de GC312-BDB- rename-7z-to-exe.7z para GC312-BDB.exe. Acione o programa com duplo clique do ponteiro do mouse. Se apresentada a caixa de diálogo Abrir arquivo - Aviso de Segurança como indica a figura 1.59 acione o botão Executar. Será apresentada a caixa de diálogo 7-Zip self-extracting archive como mostra a figura 1.60. Neste momento informe no campo Extract to o local C:\GnuCOBOL e acione o botão Extract. Aguarde o conjunto de programas do compilador GnuCOBOL serem descompactados. Figura 1.59 – Caixa de diálogo Abrir arquivo Figura 1.60 – Caixa de diálogo 7-Zip self-extracting archive 56 PROGRAMAÇÃO COBOL A próxima etapa é copiar a pasta GnuCOBOL do drive C: para dentro do local onde o ambiente OpenCobolIDE está instalado. Assim sendo, no programa Windows Explorer selecione a pasta GnuCOBOL do drive C: (não entre na pasta) e execute as teclas de atalho + . Na sequência abra e entre na pasta OpenCobolIDE em Arquivos de programas (x86) e altere o nome da pasta Gnu- COBOL de OpenCobolIDE para GnuCOBOL2 e execute as teclas de atalho + . Pronto o ambiente de seu computador está atualizado com a versão mais recente do compilador GnuCOBOL. Deixe a pasta GnuCOBOL2, pois se ocorrer algum problema fica mais fácil reverter a atualização, bastando apagar a pasta GnuCOBOL e renomear a pasta GnuCOBOL2 para GnuCOBOL. AÇÃO SEQUENCIAL 57 Neste capítulo, você tem contato com o processo de desenvolvimento de programas, utilizando a linguagem COBOL para operar ações de entrada, processamento e saída de dados. São apresentados tipos de dados e seus comportamentos em memória, variáveis, constantes, operadores aritméticos, expressões aritméticas, uso de funções, tratamento das operações de entrada e saída, formatação de valores numéricos, regras so- bre documentação interna de código, estruturação da tabulação e quebra de linhas. 2.1 ESTRUTURAÇÃO DE PROGRAMAS No capítulo anterior, fez-se introdução geral a linguagem, foram apresentados alguns detalhes sobre o uso das divisões COBOL, dando atenção a IDENTIFICATION DIVISION, ENVIRONMENT DIVISION e PROCEDURE DIVISION. A pró-xima divisão a ser vista com maior detalhamento é a DATA DIVISION. O estilo geral de codificação de programas COBOL segue uma estrutura baseada em elementos de divisões, seções, parágrafos, sentenças com definições de frases (formadas por instruções que expressam a partir da aplicação de co- mandos, verbos, cláusulas ou outro elemento sintático, certas ações). Veja a estrutura geral de um programa COBOL: DIVISÃO SEÇÃO PARÁGRAFO SENTENÇA (COMANDO) INSTRUÇÃO (SUBSTANTIVOS, PREPOSIÇÕES, ADJETIVOS E VERBOS) CLÁUSULA (MODIFICADORES) PALAVRA (CARACTERES) A divisão caracteriza-se por ser o principal grupo de operações estabelecida a um programa. É o local onde tudo acon- tece. A seção, quando existente ou definida, tem por finalidade organizar as áreas de uma divisão criando pontos de identifi-cação que facilitam a escrita e manutenção do código. O parágrafo pode ser composto por uma ou mais sentenças e estar definido dentro de uma seção ou divisão. A sentença (ou comando) é a definição de uma ou mais instruções (verbos, cláusulas ou palavras) definidas dentro de uma seção ou divisão. A instrução é a definição de uma ordem de ação estabelecida a partir de comandos expressos na forma de substanti-vos, preposições, adjetivose verbos ou outra determinação da linguagem. Uma cláusula é um conjunto ordenado de sequências de caracteres consecutivos que especificam um atributo de um comando modificando a ação deste comando. A palavra se caracteriza por ser a menor unidade de expressão, formada por qualquer palavra-chave da linguagem e usada para se comunicar com o computador. AÇÃO SEQUENCIAL 2 58 PROGRAMAÇÃO COBOL O estilo geral de codificação COBOL determina o esqueleto de formatação de um programa. É conveniente saber como os elementos seções, parágrafos, sentenças, definições e frases se comportam frente a estrutura das divisões tradicio-nais da linguagem IDENTIFICATION, ENVIRONMENT, DATA e PROCEDURE. No manual de referência da empresa IBM para o compilador Enterprise COBOL versão 6.3, página 49, para o sistema operacional z/OS a uma observação que segue como escrita: A menos que as regras associadas declarem explicitamente o contrário, cada cláusula ou declara- ção requerida deve ser escrita na sequência mostrada em seu formato. Se cláusulas ou instruções opcionais forem usadas, elas deverão ser escritas na sequência mostrada em seus formatos. Es- sas regras são verdadeiras mesmo para cláusulas e declarações tratadas como comentários. Observe então, a estrutura geral de como deve ser feita a estruturação da codificação de programas codificados na linguagem COBOL: IDENTIFICATION DIVISION | definido na área A do formulário fixo | PARÁGRAFO | definido na área A do formulário fixo | DEFINIÇÕES | definido na área B do formulário fixo | CLÁUSULAS | definido na área B do formulário fixo | ENVIRONMENT DIVISION | definido na área A do formulário fixo | SEÇÃO | definido na área A do formulário fixo | PARÁGRAFO | definido na área A do formulário fixo | INSTRUÇÕES | definido na área B do formulário fixo | CLÁUSULAS | definido na área B do formulário fixo | FRASES | definido na área B do formulário fixo | DATA DIVISION | definido na área A do formulário fixo | SEÇÃO | definido na área A do formulário fixo | INTRUÇÕES | definido na área B do formulário fixo | CLÁUSULAS | definido na área B do formulário fixo | FRASES | definido na área B do formulário fixo | PROCEDURE DIVISION | definido na área A do formulário fixo | SEÇÃO (opcional) | definido na área A do formulário fixo | PARÁGRAFO (opcional) | definido na área A do formulário fixo | SENTENÇAS | definido na área B do formulário fixo | INSTRUÇÕES | definido na área B do formulário fixo | FRASES | definido na área B do formulário fixo | A DATA DIVISION é formada por um conjunto de seções que operam detalhes operacionais da linguagem e sua rela-ção direta com a PROCEDURE DIVISION. Entre as seções existentes encontra-se a WORKING-STORAGE SECTION, que é a principal seção que nos interessa neste momento e tem a finalidade ser usada na definição da estrutura opera-cional dos dados que serão manipulados na memória principal do computador. 2.2 DADOS OPERACIONAIS Para que computadores possam executar ações de processamento, estes necessitam receber a entrada de dados para fornecer posterior saída desses dados transformados em possíveis informações. É extremamente importante conhecer o mais detalhadamente possível como a linguagem estrutura esses dados na memória e como os operacionaliza. Neste sentido, observe atentamente os pontos apresentados a seguir. 2.2.1 Layout de dados A linguagem COBOL pode ser operada a partir de três tipos de dados distintos: numérico (composto pelos valores nu- méricos decimais de “0” a “9” para a representação de números inteiros e reais), alfabético (composto pelas letras mai-úsculas de “A” até “Z” e/ou minúsculas de “a” até “z” componentes do abecedário, mais os símbolos de pontuação e o AÇÃO SEQUENCIAL 59 espaço em branco) e alfanumérico (composto apenas pelas letras e pelos números). O layout de tratamento de um dado é obrigatoriamente vinculado ao conteúdo desse dado armazenado em memória. Quando um dado é definido e formatado este é tratado como um campo de operações a ser usado nas ações de entrada, processamento e saída. O layout de dados é definido com a cláusula PIC ou PICTURE para a indicação da máscara de formatação (sendo PIC a forma mais popular de uso) que tem por finalidade especificar as características elementares dos dados tratados em memória a partir da forma sintática. PIC(TURE) Em que código é a indicação obrigatória de um código de formatação que define a máscara de comportamento opera-cional do dado em uso e tamanho é a definição opcional entre parênteses de um valor que o formato do código deve ser considerado. Veja na tabela 2.1 a indicação dos códigos de formatação existentes para a linguagem. Tabela 2.1 – Códigos de formatação dos tipos de dados Código Descrição operacional 9 Define tipo numérico sem sinal (positivo) A Define tipo alfabético (até 256 caracteres) X Define tipo alfanumérico (até 256 caracteres) B Inserção de um espaço em branco na posição em que é indicado V Define posição do decimal implícito S Define tipo numérico com sinal (positivo/negativo) P Define escala de valor decimal Z Omite valor zero na apresentação + / - Mostra sinalização positivo ou negativo $ Mostra símbolo de cifrão "$" a frente do valor * Mostra asterisco no lugar do zero . Inserção de ponto decimal na posição a qual é indicado , Inserção de vírgula na posição na qual é indicada 0 Inserção de zero na posição em que é indicado CR Símbolo de crédito DB Símbolo de débito Os códigos de formatação (9), (S), (V), (P) e (Z) são destinados ao tratamento de valores numéricos; (A) destina-se ao tratamento de valores alfabéticos; (X) é destinado ao tratamento de valores alfanuméricos; os códigos complementares (+), ($), (*), (.), (,), (0), (CR) e (DB) são auxiliares exclusivos aos códigos de operação numérica. A partir de cada código de formatação é possível estabelecer a estrutura dos dados que serão usados nas operações de entrada e saída. A cláusula PIC configura o tipo dos dados no formato esperado pelo usuário tanto na ação de ori- gem (entrada), como na ação editada (saída). As formatações de máscara se dividem em duas categorias: inserção e substituição. A edição por inserção é usada no estabelecimento de formatos: simples, especiais, fixo e flutuantes; a edição por substituição é usada na supressão de zeros com espaços em branco ou asteriscos. 60 PROGRAMAÇÃO COBOL A edição por inserção simples (campos receptores) é usada com dados numéricos e alfanuméricos. O comprimento de uso da cláusula PIC de saída (PICTURE editada) não precisa ser igual ao comprimento da cláusula PIC de entrada (PICTURE de origem). Cada máscara editada calculará sua real posição a partir da máscara de origem com base em sua posição original e substituirá a mesma. A tabela 2.2 mostra exemplos de definição de máscara de origem e editada e seus efeitos de entrada e saída para o modo edição por inserção simples. Tabela 2.2 – Máscara PIC de origem e editada para edição de inserção simples PICTURE de origem (entrada) Dado de origem (entrada) PICTURE editada (saída) Dado editado (saída) 9999999999 9(10) 1234567890 9,999,999,999 9,9(3),9(3),9(3) 1,234,567,890 99999 9(5) 12345 999,B999,B00 999,B9(3),B00 012, 345, 00 XXXXXXXXXXXXXXXXX X(17) ABRACADABRABRASIL X(11)BX(6) ABRACADABRA BRASIL 9(5) 12345 99,999 99,9(3) 12,345 A edição por inserção especial é usada com dados numéricos e de ponto flutuante positivos e negativos. O comprimen-to da cláusula PIC de saída (editada) não precisa ser igual ao comprimento da cláusula PIC de entrada (origem). O ponto decimal (.) é o símbolo de inserção especial para este tipo de dado. A tabela 2.3 mostra exemplos de definiçãode máscara de origem e editada e seus efeitos de entrada e saída para o modo edição de inserção especial. Tabela 2.3 – Máscara PIC de origem e editada para edição de inserção especial PICTURE de origem (entrada) Dado de origem (entrada) PICTURE editada (saída) Dado editado (saída) 9(10) 1234567890 9(10).99 9(10).9(2) 1234567890.00 9(7)V9(2) 12345 9(7).9(2) 0012345.00 9999.99 "1.2345" 9,999.99 0,001.23 9999.99 "12.345" 9,999.99 0,012.34 9999.99 "1.2345" 9,999.99 0,001.23 A edição por inserção fixa é usada apenas com dados numéricos para a apresentação de dados fixos. O comprimento da cláusula PIC de saída (editada) não precisa ser igual ao comprimento da cláusula PIC de entrada (origem). Os sím-bolos usados na formatação são contados no local da PICTURE editada. A tabela 2.4 mostra exemplos de definição de máscara de origem e editada e seus efeitos de entrada e saída para o modo edição de inserção fixa. AÇÃO SEQUENCIAL 61 Tabela 2.4 – Máscara PIC de origem e editada para edição de inserção fixa PICTURE de origem (entrada) Dado de origem (entrada) PICTURE editada (saída) Dado editado (saída) S9(6)V9(2) +123.45 +9(5).9(2) +00123.45 S9(6)V9(2) -123.45 -9(5).9(2) -00123.45 S9(6)V9(2) +123.45 9(5).9(2)+ 00123.45+ S9(6)V9(2) -123.45 9(5).9(2)- 00123.45- S9(6)V9(2) 123.45 $9(5).9(2) $00123.45 S9(6)V9(2) -123.45 9(5).9(2)CR 00123.45CR S9(6)V9(2) +123.45 9(5).9(2)CR 00123.45 S9(6)V9(2) -123.45 9(5).9(2)BCR 00123.45 CR S9(6)V9(2) -123.45 9(5).9(2)DB 00123.45DB S9(6)V9(3) -123.456 9(5).9(2)- 00123.45- A edição por inserção flutuante é usada apenas com dados numéricos. O comprimento da cláusula PIC de saída (edita-da) não precisa ser igual ao comprimento da cláusula PIC de entrada (origem). Os símbolos usados na formatação são contados no local da PICTURE editada. A tabela 2.5 mostra exemplos de definição de máscara de origem e editada e seus efeitos de entrada e saída para o modo edição de inserção fixa ("∕" igual a espaço em branco). Tabela 2.5 – Máscara PIC de origem e editada para edição de inserção flutuante PICTURE de origem (entrada) Dado de origem (entrada) PICTURE editada (saída) Dado editado (saída) S9(6)V9(2) 123.45 $(6).9(2) ∕∕$123.45 S9(6)V9(2) 123.45 ++,+++,9(3).99 ∕∕∕∕∕∕+123.45 S9(6)V9(2) 123.45 +$,$(3),9(3).99 +∕∕∕∕+$123.45 A edição por substituição é usada apenas com dados numéricos, sendo usada para substituir os valores zero nos da-dos de entrada com espaços (uso do código "Z") ou asteriscos (uso do código "*"). O comprimento da cláusula PIC de saída (editada) não precisa ser igual ao comprimento da cláusula PIC de entrada (origem). Os símbolos usados na formatação são contados no local da PICTURE editada. A tabela 2.6 mostra exemplos de definição de máscara de 62 PROGRAMAÇÃO COBOL origem e editada e seus efeitos de entrada e saída para o modo edição de inserção fixa ("∕" igual a espaço em branco). Não use os símbolos "Z" e "*" na mesma máscara. Tabela 2.6 – Máscara PIC de origem e editada para edição de substituição PICTURE de origem (entrada) Dado de origem (entrada) PICTURE editada (saída) Dado editado (saída) S9(6)V9(2) 0.00 *(6).** ******.** S9(6)V9(2) 0.00 Z(6).99 ∕∕∕∕∕∕.00 S9(6)V9(2) 0.00 Z(6).ZZ ∕∕∕∕∕∕∕∕∕ S9(6)V9(2) 0.00 *(6).99 ******.00 S9(6)V9(2) 123.45 +Z(6).99 +∕∕∕123.45 S9(6)V9(2) -123.45 -Z(6).99 -∕∕∕123.45 O comando PICTURE é responsável por definir o layout dos dados usados nos programas. Tem por finalidade ajustar, não só o estilo do dado, mas como o dado se comporta internamente e a quantidade de bytes a ser utilizada na memó-ria para dar o suporte adequado as operações de entrada, processamento e saída. Os códigos (9), (S), (V), (P), (Z), (A), (X), (+), ($), (*), (.), (,), (0), (CR) e (DB) estabelecem grande estilo de formatações e atendem desta forma diversas necessidades operacionais como sugerido na tabela 2.2. O comando PICTURE, como mencionado, estabelece o layout do dado vinculado ao conteúdo armazenado em memó-ria como sendo um campo de dado. Este campo de dado é vinculado a definição prévia de uma variável. 2.2.2 Variáveis Variáveis são áreas ou campos de memória usadas para o armazenamento de dados que são manipulados em compu-tadores. Os dados armazenados na forma de variáveis poderão ser usados na realização de cálculos quando numéri- cos, na realização de movimentações quando forem de qualquer tipo, no armazenamento temporário de dados na me-mória principal ou na apresentação de seus conteúdos. A identificação de uma variável é realizada com a definição de um nome alfanumérico contendo no máximo trinta carac-teres. O nome de identificação de uma variável pode ser iniciado por número, desde que este nome tenha em sua com-posição no mínimo um caractere alfabético. Para a composição dos nomes podem ser usadas letras de A até Z, núme- ros de 0 até 9, hifens (-) e linha baixa (_). A definição de variáveis é feita segundo a especificação de um código que estabelece o nível hierárquico e o compor-tamento de cada variável. Os códigos numéricos usados podem ser os valores de 1 a 49, 66, 77 e 88. Quanto menor o valor, maior será seu nível hierárquico. Uma variável pode ser definida como elemento isolado, ou seja, um item ele-mentar (item individual ou independente) ou ser definida como componente de um grupo (item de grupo ou de campo) não tendo nenhuma relação com outro dado existente. As variáveis do tipo itens de grupo podem ser subdivididas para agruparem variáveis isoladas ou outros itens de grupos que por sua vez podem ser formados por itens elementares ou itens de grupo e assim sucessivamente. Observe na sequência a tabela 2.7 com a definição dos valores de código numérico para o estabelecimento dos níveis numéricos de definição de elementos ou grupos de elementos suportados pela linguagem. AÇÃO SEQUENCIAL 63 Tabela 2.7 – Níveis numéricos hierarquizados para variáveis Nível Descrição operacional 01 Definição de item de grupo (estilo registro) 02 até 49 Definição de itens elementares dentro de grupos 66 Renomear itens de cláusulas, usado com RENAME 77 Definição de item elementar 88 Definição de múltiplos valores (intervalos: estilo lógico) Não há regra para determinar a numeração de variáveis dentro dos itens de grupo (nível 01). Dentro de um grupo po-dem ser definidas variáveis ou outros grupos subordinados. Neste caso, para cada variável ou mesmo grupo subordi-nado usa-se tão somente a numeração de 02 até 49. Apenas o item de grupo principal é definido com o código 01. Há, por parte de alguns programadores, o hábito de estabelecer a numeração subordinada em saltos de 5 em 5 ou 10 em 10. No entanto, poderá ser usado, sem nenhum problema, qualquer valor entre 02 e 49. Não é necessário definir os níveis de forma contínua, o que é importante é manter sua ordem de grandeza crescente. Se o desejo for apenas definir variáveis isoladas como itens elementares o código a ser usado é 77. Os códigos 66 e 88 são especiais e serão tratados em momento mais oportuno. No entanto, há programadores que definem variáveis isola-das com o código 01. Assim sendo, neste momento são apresentados o uso dos códigos 77 e 01 a partir da forma sin-tática: PIC(TURE) [VALUES ] Em que nível é a definição obrigatória do código de estabelecimento de uma variável, variável é a definição obrigatória de um rótulo de identificação para variável, PIC(TURE) é a definição obrigatória da estrutura do campo para a variável (como apresentado) e VALUES é a definição opcional do estabelecimento de um valor inicial para a variável definida. Observe um exemplo de definição de variáveis de itens elementares (código 77) para o armazenamento do NOME com trinta posições alfabéticos, IDADE com três posições numéricas iniciada com valor 100 e ALTURA com uma posição numérica inteira e duas posições numéricas decimais. DATA DIVISION. WORKING-STORAGE SECTION.77 NOME PIC A(30). 77 IDADE PIC 9(03) VALUES 100. 77 ALTURA PIC 9V9(02). Note que foram definidas as PICTURES de formatação A(30) para a variável NOME indicando o uso de variável do tipo alfabética com trinta posições, 9(03) VALUES 100 para a variável IDADE indicando o uso de uma variável do tipo nu- mérica inteiro com três posições iniciada com valor 100 e 9V9(02) para o campo ALTURA indicando o uso de uma variável numérica real com parte da posição para valor inteiro em metros e duas partes da posição para o valor decimal em centímetros. Veja um exemplo para a definição de um item de grupo (código 01) identificado como DADOS-PESSOAIS contendo os itens elementares NOME com trinta posições alfabéticos, IDADE com três posições numéricas iniciada com valor 100 e ALTURA com uma posição numérica inteira e duas posições numéricas decimais. DATA DIVISION. WORKING-STORAGE SECTION. 01 DADOS-PESSOAIS. 02 NOME PIC A(30). 02 IDADE PIC 9(03) VALUES 100. 02 ALTURA PIC 9V9(02). 64 PROGRAMAÇÃO COBOL Observe que o item de grupo DADOS-PESSOAIS está alinhando na coluna 12 e os itens elementares associados ao grupo estão definidos a partir da coluna 18. Este alinhamento visa dar melhor visualização do nivelamento usado e está de acordo com a tabulação usada no ambiente OpenCobolIDE e com a estrutura de um formulário fixo. No entanto, é comum ver essa tabulação estabelecida a partir da coluna 15 como indicado. Fica a critério do programador escolher o estilo. DATA DIVISION. WORKING-STORAGE SECTION. 01 DADOS-PESSOAIS. 02 NOME PIC A(30). 02 IDADE PIC 9(03) VALUES 100. 02 ALTURA PIC 9V9(02). Um detalhe importante é que ao escolher o valor entre 02 e 49 para especificar cada um dos itens elementares este deverá ser mantido em todo o escopo do grupo. Note que foi usado o valor 02 para todos os itens elementares do grupo DADOS-PESSOAIS. Como comentado um item de grupo pode ser formado por outros itens de grupo. Desta forma, considere que o item de grupo DADOS-PESSOAIS (formado pelos itens elementares NOME, IDADE e ALTURA) é parte de um grupo chamado CADASTRO que tenha ainda um grupo chamado DOCUMENTO com os itens elementares CPF e RG. DATA DIVISION. WORKING-STORAGE SECTION. 01 CADASTRO. 05 DADOS-PESSOAIS. 10 NOME PIC A(30) VALUES "AAA BBB CCC". 10 IDADE PIC 9(03) VALUES 111. 10 ALTURA PIC 9V9(02) VALUES 1.76. 05 DOCUMENTO. 10 CPF PIC 9(11). 10 RG PIC 9(10). Atente para o uso do código 01 como estabelecimento do grupo principal (lembrando que todo item de grupo deve ser definido sempre com o código 01). No entanto, qualquer grupo criado (grupo secundário) dentro de um item de grupo 01 poderá ser definido com um valor entre 02 e 49. Neste caso foi escolhido o valor 05 e dentro deste escopo poderá ser usado apenas valores entre 06 e 49 para definir novos itens elementares ou mesmo outros grupos. O uso dos valo-res deverá sempre ser na ordem crescente. Não é possível usar sequencialmente um valor menor ao último valor esta-belecido. Veja que os itens elementares foram definidos com o valor 10, mas poderiam ser valores de 06 até 49. 2.2.3 Espaço de memória Quando se utiliza PICTURE consome-se certo espaço de memória. Os valores alfabéticos e alfanuméricos estão limita-dos ao consumo máximo de até 256 bytes, mas valores numéricos são um caso a parte, pois podem ser especificados como inteiros a partir do código 9 (inteiros não sinalizados) ou S9 (inteiros sinalizados) e reais com o código V (decimal implícito) ocupando 18 bytes de memória. Os dados definidos como inteiros aceitam a realização de operações matemáticas de forma direta, sem nenhum trata-mento especial desse dado, mas o mesmo não ocorre com os dados reais que necessitam ser tratados e devidamente ajustados. O tratamento realizado sobre dados numéricos é chamado de compactação, devendo ser aplicado tanto a dados reais como a dados inteiros. A operação de compactação visa definir ajustes de modo que se controle a quantidade de bytes consumidos em memória a partir do formato especificado para o campo representante do dado. São três as definições de campos a serem considerados para o tratamento numérico: zonados, compactados e binários: Campo zonado é aquele em que o algarismo consome exatamente um byte de memória, é o tipo de campo usado para os valores numéricos sem tratamento de compactação, ocupando sempre 18 bytes de memória para represen-tar um valor numérico de 18 dígitos, sendo a forma padrão da linguagem COBOL; AÇÃO SEQUENCIAL 65 Campo compactado é aquele em que o algarismo é armazenado em formato decimal compactado (BCD - Binary Coded Decimal) utilizando dois dígitos por byte com mais meio byte reservado a sinalização de valores negativos, ocupando até 10 bytes para representar valore com 38 dígitos; Campo binário é aquele que possui a melhor taxa de compactação possível, é usado para representar em um byte a maior quantidade de bits possíveis, por exemplo, em um conjunto de dois bytes é possível armazenar valores po-sitivos de 0 até 65.536, o mesmo espaço em um campo zonado armazena valores positivos de 0 até 99, podendo ser usado para o tratamento de qualquer tipo de dado. Para a definição do tamanho de memória a ser qualificado sobre determinado dado (elementar ou grupo) pode-se usar a cláusula USAGE e o verbo IS. O comando USAGE IS pode ser usado com itens elementares ou de grupos. Se usado com itens elementares (variáveis/campos) deverá ser declarado após o comando PICTURE desde que a variável não seja inicializada. Caso a variável seja inicializa o comando USAGE IS deve ser a última expressão na linha de instrução após a definição do valor de inicialização. No caso de itens de grupo o comando USAGE IS deve ser declarado imedia-tamente ao lado direito do nome do grupo e os itens elementares subordinados a este grupo deverão ser definidos com o mesmo tipo de dado do item de grupo, sendo que basta declarar o tipo de dado para o item de grupo para que todos os seus itens elementares sejam automaticamente qualificados com o mesmo tipo de dado definido. O uso do comando USAGE IS segue de forma geral a sintaxe: 77 PIC [VALUES ] USAGE IS 77 PIC USAGE IS 01 USAGE IS Em que opção é a definição de uma palavra-chave que orienta o compilador a efetuar o tratamento do dado citado. A cláusula USAGE e o verbo IS são opcionais (no passado eram usadas com equipamentos IBM) e por esta razão aca- bam por não serem utilizadas o que leva, normalmente, as linhas de declaração de itens elementares e de grupo serem codificadas como: 77 PIC [VALUES ] 77 PIC 01 A cláusula USAGE e o verbo IS são usados apenas com os níveis 01 e 77 não sendo aplicadas aos demais níveis de qualificação. Os compiladores COBOL disponibilizam algumas opções para a configuração do espaço de armazenamento de dados em memória. Neste texto são consideradas apenas as opções essenciais ao compilador GnuCOBOL. Sugere-se para maior aproveitamento fazer consulta junto a documentação técnica do compilador. Veja algumas das opções computa-cionais importantes de definição de tipos e compactação de dados usadas em conjunto da cláusula PICTURE: BINARY é usado para armazenar valores numéricos inteiros no formato binário puro de até 18 bits formatados com as máscaras 9 ou S. Dependendo da quantidade de bits em uso o dado poderá ocupar até oito bytes. BINARY po-derá ser substituída por seus sinônimos equivalentes COMP (podendo ser COMPUTATIONAL) ou COMP-4 (po-dendo ser COMPUTATIONAL-4). Com 2 bytes (de 1 a 4 dígitos na PICTURE) a faixa de valores operada vai de 0 a 255 ou de -128 até 127), com 4 bytes (de 5 a 9 dígitos na PICTURE) a faixa de valores operada vai de 0 a 65.535 ou de -32.768 até 32.767),com 8 bytes (de 10 a 18 dígitos na PICTURE) a faixa de valores operada vai de 0 a 4.294.967.295 ou de -2.147.483.648 até 2.147.483.647) e com 16 bytes a faixa de valores operada vai de 0 a 18.446.744.073.709.551.615 ou de -9.223.372.036.854.775.807 até 9.223.372.036.854.775.807); COMP-3 (podendo ser COMPUTATIONAL-3) é usado para armazenar valores numéricos decimais compactados de até 38 bits formatados com as máscaras 9, S, V e P. Esta opção armazena dois dígitos em um único byte, manten-do meio byte de memória para indicar a sinalização numérica (para representação de valores negativos), mesmo que o valor não seja sinalizado. Dependendo da quantidade de bits estabelecidos o dado poderá ocupar até 20 bytes. COMP-3 poderá ser substituída por seu sinônimo equivalente PACKED-DECIMAL; COMP-5 (podendo ser COMPUTATIONAL-5) é similar a BINARY, tendo como diferença o fato de que os dados são armazenados em um formato binário dependente da arquitetura do computador (binário nativo), o que pode ocasio-nar problemas de transporte de dados entre computadores de diferentes arquiteturas. Este tipo de dado é usado principalmente para comunicação entre programas externos; 66 PROGRAMAÇÃO COBOL COMP-X (podendo ser COMPUTATIONAL-X) é usado para determinar definições de tipos que usem as máscaras 9 e X tratando os dados como número inteiro binário não sinalizado com armazenamento interno semelhante a opção BINARY. Se usada a máscara X para definir um item, o número de bytes alocados para o item será o mesmo cor-respondente ao número de X usados na máscara. Se usada a máscara 9 será alocado o menor número de bytes necessários ao armazenamento do valor em uso; DISPLAY é usada para armazenar dados do tipo caractere em formato ASCII (American Standard Code for Informa- tion Interchang - Código Padrão Americano para o Intercâmbio de Informação) usados com as máscaras 9, A e X. Desta forma, cada caractere armazenado ocupará um byte de memória (8 bits). Esta opção computacional é o pa-drão de operação da linguagem e por esta razão não há a necessidade de fazer seu uso, a menos que se deseje ser extremamente criterioso. Para maiores detalhes consulte o apêndice desta obra. Observe algumas das opções computacionais importantes de definição de tipos e compactação de dados usadas em sem o uso da cláusula PICTURE: COMP-1 (podendo ser COMPUTATIONAL-1) é usado para armazenar valores numéricos decimais de ponto flutu-ante com precisão simples a partir das máscaras 9, S, V e P, ocupando quatro bytes de comprimento. Para uso des-ta opção não se faz o uso da cláusula PICTURE por ser o tamanho do dado pré-estabelecido. Opera na faixa apro- ximada de valores de -3.4028235×10^38 até 3.4028235×10^3; COMP-2 (podendo ser COMPUTATIONAL-2) é usado para armazenar valores numéricos decimais de ponto flutu-ante com precisão dupla a partir das máscaras 9, S, V e P, ocupando oito bytes de comprimento. Para uso desta opção não se faz o uso da cláusula PICTURE por ser o tamanho do dado pré-estabelecido. Opera na faixa aproxi- mada de valores de -1.797693134862316×10^308 até 1.797693134862316×10^308; POINTER é usado para representar endereços de memória relacionados a outros dados, por este motivo este tipo de dado é representado por valores numéricos inteiros não sinalizados. O dado qualificado como ponteiro não faz uso da cláusula PICTURE, mas aceita a clausula VALUE desde que o valor de inicialização seja NULL (para indicar que o ponteiro não aponta para nenhum dado em específico na memória). Este tipo ocupa 4 ou 8 bytes de memória, o que permite armazenar, respectivamente, endereços de tamanho até 32 ou 64 bits operando na faixa de 0 até o limite, respectivo, de 32 ou 64 bits. Observe um exemplo de definição de uma variável do tipo item elementar para o armazenamento do ANO com iniciali-zação de valor em 2000 para certa data com seu a definição do tipo de dado BINARY: DATA DIVISION. WORKING-STORAGE SECTION. 77 ANO PIC 9999 VALUES 2000 USAGE IS BINARY. Veja neste exemplo a definição de um item de grupo identificado como DADOS-PESSOAIS sem qualificação de tipo de dado contendo os itens elementares NOME com trinta posições alfabéticos, IDADE com três posições numéricas defi- nida com o tipo BINARY com o uso do comando USAGE IS e ALTURA com uma posição numérica inteira e duas posi-ções numéricas decimais definidas com o tipo COMP-3 sem o uso do comando USAGE IS. DATA DIVISION. WORKING-STORAGE SECTION. 01 DADOS-PESSOAIS. 02 NOME PIC A(30). 02 IDADE PIC 9(03) USAGE IS BINARY. 02 ALTURA PIC 9V99 COMP-3. Note no próximo exemplo a definição do item de grupo DATA-CAL com qualificação de tipo de dado BINARY contendo os campos DIA, MES e ANO sem definição de tipo de dado. DATA DIVISION. WORKING-STORAGE SECTION. 01 DATA-CAL USAGE BINARY. 02 DIA PIC 9(02). 02 MES PIC 9(02). 02 ANO PIC 9(04). AÇÃO SEQUENCIAL 67 Observe o uso da opção computacional POINTER inicializada com valor da constante NULL indicando que o ponteiro não está apontando para nenhum endereço de memória. DATA DIVISION. WORKING-STORAGE SECTION. 77 PTR VALUE NULL USAGE POINTER. 77 VAL PIC X(10) VALUES "ABC 123456". PROCEDURE DIVISION. SET PTR TO ADDRESS OF VAL. DISPLAY PTR. Um item elementar do tipo POINTER se caracteriza por ser uma variável especial que armazena apenas endereço de memória e não o conteúdo da posição apontada. Veja que na divisão de procedimento é usado o verbo SET que tem por finalidade colocar em certa variável o conteúdo indicado após a cláusula TO, Neste caso, a instrução coloca em PTR o endereço da variável VAL a partir do uso da cláusula ADDRESS OF (endereço de) e não o conteúdo indicado na variável VAL. A saída do programa é algo como 0x0040e040 indicando o endereço hexadecimal (0x) de memória situ-ada em 0040e040. 2.2.4 Constantes Uma constante caracteriza-se por ser a definição de certo valor imutável de qualquer natureza associado a um determi-nado rótulo. Uma constante não sofre alteração de seu valor ao longo da execução de certo programa. A linguagem COBOL pode ser operada a partir de dois tipos de constantes as internas e as externas. Até a edição da norma ISO 1989:1985 a linguagem COBOL não possuía uma forma explícita de declaração de constan- te. Quando se tinha a necessidade de fazer uso de constantes, simulava-se a definição da constante utilizando-se uma variável com a inicialização de um valor. Após a publicação da norma de 1985 a linguagem recebe a primeira implementação de definição de constante a partir do uso da cláusula CONSTANT e da preposição AS a serem usadas com a definição de nível 01. Com a publicação da norma ISO/IEC 1989:2014 vem a segunda e atual definição de constante a partir do uso do código de nível 07 e a cláu-sula VALUES. Do conjunto de valores constantes existentes no GnuCOBOL duas estão definidas como funções intrínsecas a partir do uso do comando FUNCTION. O trecho a seguir mostra os valores retornados das constantes matemática “E” (logaritmo natural) e “PI” com 95 casas decimais. PROCEDURE DIVISION. DISPLAY FUNCTION E. *> 2.718281828459045235360287471352662497757247093699959 (...) DISPLAY FUNCTION PI. *> 3.141592653589793238462643383279502884197169399375105 (...) Além das funções intrínsecas “E” e “PI” que representam duas constantes matemáticas importantes há a existência de algumas constantes figurativas: ZERO/ZEROS/ZEROES (usadas com máscara numérica); SPACE/SPACES (usadas com máscara alfanumérica); HIGH-VALUE/HIGH-VALUES (usadas com máscara alfanumérica); LOW-VALUE/LOW- VALUES (usadas com máscara alfanumérica); QUOTE/QUOTES (usadas com máscara alfanumérica); NULL/NULLS (usadas com máscara alfanumérica). Note que há constantes figurativas expressas no singular e plural. No singular refere-se a apenas uma ocorrência da constante sobre o dado no plural refere-se a mais de uma ocorrência da constante sobre o dado. No entanto, as formas singular e plural podem ser usadasde maneira intercambiável uma vez que representam, em si, a mesma coisa por serem sinônimos. O uso em singular ou plural é uma maneira de deixar o código do programa mais próximo da escrita do idioma inglês, lembrando que essa foi uma das intenções do desenvolvimento da linguagem. As constantes ZERO, ZEROS e ZEROES representam a definição do valor 0 (zero ou zeros) que dependendo do con-texto de uso poderá ser considerado numérico ou alfanumérico. As constantes SPACE e SPACES representam a definição de caractere de espaço ou espaços em branco considera-dos do tipo alfanumérico. 68 PROGRAMAÇÃO COBOL As constantes HIGH-VALUE e HIGH-VALUES representam a ocorrência de um ou mais caracteres X"FF" (maior valor hexadecimal na posição ordinal da sequência de caracteres EBCDIC) de acordo com o que é definido no parágrafo OBJECT-COMPUTER ou quando nada é especificado utiliza o conjunto de caracteres padrão, normalmente ASCII. As constantes LOW-VALUE e LOW-VALUES representam a ocorrência de um ou mais caracteres X"00" (menor valor hexadecimal na posição ordinal da sequência de caracteres EBCDIC) de acordo com o que é definido no parágrafo OBJECT-COMPUTER ou quando nada é especificado utiliza o conjunto de caracteres padrão, normalmente ASCII. As constantes QUOTE e QUOTES representam a definição de caractere ou caracteres de aspas inglesas considerados do tipo alfanumérico. As constantes NULL e NULLS representam a definição de valor nulo ou nulos (internamente igual a 0), podendo ser aplicada para indicar que o dado não possui endereço de acesso a memória válido. Esta constante pode ser associada a inicialização de ponteiros e referências de objetos. Em relação a definição de constantes externas, estas são apresentadas a seguir das duas formas permitidas. É perti-nente pontuar que a definição de constantes deve ser realizada na seção WORKING-STORAGE e que esta definição não usa a cláusula PICTURE. Observe a forma sintática da definição de valores constantes seguindo a regra da norma ISO 1989:1985 com a cláusula CONSTANT e a preposição AS: 01 CONSTANT AS . Onde constante é o nome atribuído ao recurso e valor é a definição do valor representado pelo rótulo constante. Para a definição de valores numéricos o máximo de dígitos permitidos são 38 em toda a sua extensão. Observe o trecho seguinte demonstrando a definição da constante matemáticas “LN2” respeitando o estilo da norma ISO 1989:1985. Atente para o uso do código 01 e da cláusula CONSTANT e a preposição AS. DATA DIVISION. WORKING-STORAGE SECTION. 01 LN2 CONSTANT AS 0.6931471805599453094. PROCEDURE DIVISION. DISPLAY LN2. Observe a forma sintática da definição de valores constantes seguindo a regra da norma ISO/IEC 1989:2014 com a cláusula VALUES e a preposição AS: 78 VALUES . Observe o trecho seguinte demonstrando a definição da constante matemáticas “LN10” respeitando o estilo da norma ISO 1989:2014. Atente para o uso do código 78 e da cláusula VALUES. DATA DIVISION. WORKING-STORAGE SECTION. 78 LN10 VALUES 2.3025850929940456840. PROCEDURE DIVISION. DISPLAY LN10. Diferentemente de uma variável, o valor de uma constante não ocupa espaço de memória. Isto é perceptível uma vez que na definição de constante não se utiliza a cláusula PICTURE, logo não há ocupação de espaço de memória para o dado. A constante é apenas a definição de um apelido usado para fazer referência de acesso a um determinado valor, facilitando seu uso. AÇÃO SEQUENCIAL 69 2.2.5 Reagrupamento de dados O reagrupamento de itens elementares cria um grupo “lógico” baseado a partir de um grupo “físico” existente que con-tenha itens elementares. A renomeação de grupo é executa com o uso da cláusula RENAME, que necessita do código 66. A cláusula RENAME não usa a cláusula PICTURE e não pode renomear entradas de códigos 01, 66, 77 e 88. O grupo “lógico” usa a mesma área de memória em que o grupo “físico” encontra-se definido. A cláusula RENAME pode ser aplicada apenas no final do grupo “físico”. Itens elementares declarados com a cláusula OCCURS (usada para a criação de tabela, que serão vistas mais adiante nesta obra) não podem ser renomeados. Como exemplo para renomeação de grupo “físico” considere a estrutura do item de grupo DATA-NAS (data de nasci-mento) qualificado como sendo do tipo DISPLAY contendo os campos DIA (com valor 26), MES (com valor 04), ANO (com valor 1965), HORA (com valor 17) e MINUTO (com valor 25) reagrupado como data de aniversário DATA-ANV contendo apenas o acesso aos campos DIA, MES e ANO. DATA DIVISION. WORKING-STORAGE SECTION. 01 DATA-NAS USAGE BINARY. 02 DIA PIC 9(02) VALUES 26. 02 MES PIC 9(02) VALUES 04. 02 ANO PIC 9(04) VALUES 1965. 02 HORA PIC 9(02) VALUES 17. 02 MINUTO PIC 9(04) VALUES 25. 66 DATA-ANV RENAMES DIA THRU ANO. PROCEDURE DIVISION. DISPLAY "DIA ...............: " DIA. DISPLAY "MES ...............: " MES. DISPLAY "ANO ...............: " ANO. DISPLAY "HORA ..............: " HORA. DISPLAY "MINUTO ............: " MINUTO. DISPLAY "DATA NASCIMENTO ...: " DATA-NAS. DISPLAY "DATA ANIVERSARIO ..: " DATA-ANV. Ao ser executado um programa, que contenha a estrutura definida anteriormente, deverá ser apresentada uma saída semelhante a imagem da figura 2.1. Figura 2.1 – Saída de grupo renomeado No exemplo apresentado, grupo DATA-NAS é declarado com cinco campos dispostos contiguamente em certa área de memória. Ao se definir a renomeação da área como DATA-ANV tem-se acesso apenas aos itens indicados do campo DIA até o campo ANO. Neste caso os três primeiros. Observe que a indicação DIA NASCIMENTO tem apresentada a sequência de valores 2604196500170025 contigua-mente e a indicação DIA ANIVERSARIO apresenta apenas os valores 26041965 que corresponde a área de memória acessada pelo item de grupo DATA-ANV. 70 PROGRAMAÇÃO COBOL 2.3 PROCESSAMENTO MATEMÁTICO Após conhecer o conceito de dados operacionais relacionados ao uso de variáveis e constantes, bem como sua estru-turação em memória na DATA DIVISION é importante atentar a principal operação que pode ser imputada sobre esses dados: o processamento matemático que contempla as operações de cálculos realizadas por um computador. A linguagem oferece para a realização de cálculos matemáticos os comandos COMPUTE, DIVIDE, MULTIPLY, ADD e SUBTRACT. O comando COMPUTE atende a maior parte das necessidades de uso de operações com cálculos, pos-suindo uma estrutura de escrita em estilo algébrico mais tradicional baseando-se na indicação de equações, diferente dos demais comandos que expressam a ação algébrica de forma descritiva. No entanto, cada uma das formas possui suas características. 2.3.1 Estilo algébrico O estilo algébrico é operacionalizado pelo comando COMPUTE que define uma instrução para certa ação na realização do processamento aritmético na forma de equação. Devido a sua característica operacional a instrução COMPUTE é executada na PROCEDURE DIVISION a partir do uso de operadores aritméticos e funções intrínsecas. A tabela 2.8 mostra os operadores aritméticos suportados e destinados as ações de processamento aritmético executa-dos com o comando COMPUTE. A ordem de apresentação dos operadores na tabela corresponde a ordem de priorida- de a ser considerada matematicamente. Tabela 2.8 – Operadores aritméticos Operador Operação Resultado com Prioridade ** Exponenciação Inteiro e decimal 1 / Divisão Inteiro e/ou decimal 2 * Multiplicação Inteiro e decimal 2 + Adição Inteiro e decimal 3 - Subtração Inteiro e decimal 3 = Atribuição Qualquer tipo de dado - Como exemplo considere o trecho de código seguinte voltado a apresentar o resultado da área de uma circunferência com cinco casas decimais sem a existência de zeros à esquerda a partir de um raio definido com o valor 5.32. Consid-ere a formula AREA ← PI * RAIO ↑ 2 para calcular AREA-CIRC = FUNCTION PI * RAIO-CIRC ** 2.47 1.4.4 - PROCEDURE DIVISION.................................................................................................................................... 47 1.5 - Operações iniciais ...................................................................................................................................................... 50 1.6 - Windows Terminal e atualização ............................................................................................................................... 54 Capítulo 2 - Ação Sequencial 2.1 - Estruturação de programas ....................................................................................................................................... 57 2.2 - Dados operacionais .................................................................................................................................................... 58 2.2.1 - Layout de dados ............................................................................................................................................. 58 2.2.2 - Variáveis ......................................................................................................................................................... 62 2.2.3 - Espaço de memória......................................................................................................................................... 64 2.2.4 - Constantes ...................................................................................................................................................... 67 2.2.5 - Reagrupamento de dados .............................................................................................................................. 69 2.3 - Processamento matemático ...................................................................................................................................... 70 2.3.1 - Estilo algébrico ............................................................................................................................................... 70 2.3.2 - Estilo descritivo .............................................................................................................................................. 73 2.3.3 - Algébrico versus descritivo ............................................................................................................................. 79 2.3.4 - Funções intrínsecas ........................................................................................................................................ 79 2.4 - Entradas e saídas ....................................................................................................................................................... 80 2.5 - Hora de programar .................................................................................................................................................... 83 2.6 - Documentação: coluna 7 ............................................................................................................................................ 89 Capítulo 3 - Ação In/condicional 3.1 - Processamento lógico ................................................................................................................................................ 97 3.2 - Desvios condicionais .................................................................................................................................................. 99 3.2.1 - Desvio simples ................................................................................................................................................ 99 3.2.2 - Desvio composto .......................................................................................................................................... 101 3.2.3 - Desvio seletivo ............................................................................................................................................. 102 3.3 - Ações condicionais ................................................................................................................................................... 104 3.3.1 - Teste de classe .............................................................................................................................................. 104 3.3.2 - Teste de sinal ................................................................................................................................................ 104 3.3.3 - Nomes condicionais ...................................................................................................................................... 105 3.4 - Desvios incondicionais ............................................................................................................................................. 106 3.5 - Laços para repetições .............................................................................................................................................. 109 3.5.1 - Ciclo interativo ............................................................................................................................................. 109 3.5.2 - Ciclo iterativo ............................................................................................................................................... 111 3.5.3 - Ciclo seletivo ................................................................................................................................................ 112 3.6 - Divisibilidade ........................................................................................................................................................... 113 3.7 - Interrupção de laços ................................................................................................................................................ 115 3.8 - Hora de programar .................................................................................................................................................. 116 Capítulo 4 - Processamento com Coleções de Dados 4.1 - Coleção de dados...................................................................................................................................................... 133 4.2 – Estruturas de dados estáticas .................................................................................................................................. 134 4.2.1 - Manipulação de listas ................................................................................................................................... 134 4.2.2 - Manipulação de tabelas ................................................................................................................................ 136 4.2.3 - Listas e tabelas internas ............................................................................................................................... 139 4.3 - Ações complementares ............................................................................................................................................ 144 4.3.1 - Inicialização de variáveis .............................................................................................................................. 145 4.3.2 - Classificação de dados .................................................................................................................................. 147 4.3.3 - Pesquisas de dados ....................................................................................................................................... 149 4.3.4 - Campos variáveis .......................................................................................................................................... 152 4.3.5 - Aleatoriedade variável .................................................................................................................................DATA DIVISION. WORKING-STORAGE SECTION. 77 AREA-CIRC PIC 9(03)V9(05) VALUES ZERO. 77 RAIO-CIRC PIC 9(03)V9(05). 77 RAIO-DISP PIC Z(03).9(05). PROCEDURE DIVISION. COMPUTE RAIO-CIRC = 5.32. COMPUTE AREA-CIRC = FUNCTION PI * RAIO-CIRC ** 2. MOVE AREA-CIRC TO RAIO-DISP. DISPLAY RAIO-DISP. Para a demonstração foram definidas duas variáveis para a efetivação do cálculo, sendo AREA-CIRC e RAIO-CIRC na DATA DIVISION, em que AREA-CIRC é a variável que armazena o resultado do cálculo realizado e RAIO-CIRC é a variável que fornece a fórmula um valor para a operação. AÇÃO SEQUENCIAL 71 Observe que a variável AREA-CIRC que armazena o resultado foi inicializada com a definição do valor zero a partir da instrução 77 AREA-CIRC PIC 9(03)V9(05) VALUES ZERO, atente para o uso da cláusula VALUES com a definição de uso da constante figurativa ZERO. A variável RAIO-CIRC está definida apenas com a máscara 9(03)V9(05) de formatação e a inicialização de seu valor está definida na PROCEDURE DIVISION a partir da instrução COMPUTE RAIO-CIRC = 5.32. Veja que COMPUTE pode ser utilizado para determinar a inicialização de variáveis, além do uso da clausula VALUES. Note que tanto a variável AREA-CIRC como RAIO-CIRC usam a máscara 9(03)V9(05) que determinam um espaço de memória adequado para representar um valor numérico no formato 999.99999. Uma das ações solicitadas é a apresentação do resultado do cálculo sem a ocorrência de zeros à esquerda. Para que isso seja possível foi definida a variável AREA-DISP a partir da máscara Z(3).9(5) que determina um formato numérico para valores no estilo 999.99999. Atente para o uso de duas máscaras diferentes para o mesmo formato numérico, 9(03)V9(05) e Z(03).9(05). Qual é a diferença, se ambas usam o estilo 999.99999. A diferença é que a máscara 9(03)V9(05) formata os valores na memória ajustando o espaço exigido, sendo essa más- cara direcionada ao armazenamento de dados e consequentemente seu processamento. Já a máscara Z(03).9(05) é a definição de uma ação “cosmética” para a apresentação de dados com o comando DISPLAY. No contexto apresentado a variável AREA-DISP é, o que se chama, de campo editado. Um campo editado é um recur-so que só pode ser utilizado para efeitos de exibição do dado no monitor de vídeo, não pode ser usado em operações aritméticas ou algébricas. Há um detalhe importante a ser considerado em relação ao uso da variável AREA-DISP que apesar de estar formatada para a recepção de valor numérico, não é uma variável numérica e por conseguinte não poderá ser usada diretamente para a realização de cálculos matemáticos. As variáveis AREA-CIRC e RAIO-CIRC são numéricas decimais e AREA-DISP é alfanumérica e para fazer com que o conteúdo de uma variável numérica seja atribuído a uma variável alfanumérica usa-se o comando MOVE em conjunto com a preposição TO. Desta forma, a instrução MOVE AREA-CIRC TO RAIO-DISP move o conteúdo numérico decimal da variável AREA-CIRC para a variável RAIO-DISP ajustando o valor numérico dentro do formato alfanumérico definido para RAIO-DISP. O comando MOVE tem a finalidade transferir dados de uma área de armazenamento (dado remetente) para outra área de armazenamento (dado receptor). A forma de movimentação do conteúdo é determinada pelo campo receptor po-dendo-se transferir itens de elementos ou itens de grupo. A movimentação só pode ser realizada se houver compatibili- dade de tipo entre os dados, isso permitiria no código exemplo usar a instrução MOVE 5.32 TO RAIO-CIRC. Em substi-tuição a instrução COMPUTE RAIO-CIRC = 5.32. O comando COMPUTE tem ainda a característica de atribuir um mesmo resultado calculado de certa operação a mais de uma variável. Observe a seguir a soma de A com valor 1 e B com valor 2 atribuídas de uma única vez as variáveis R1, R2 e R3. DATA DIVISION. WORKING-STORAGE SECTION. 77 A PIC 9 VALUES 1. 77 B PIC 9 VALUES 2. 77 R1 PIC 9. 77 R2 PIC 9. 77 R3 PIC 9. PROCEDURE DIVISION. COMPUTE R1 R2 R3 = A + B. DISPLAY R1. DISPLAY R2. DISPLAY R3. 72 PROGRAMAÇÃO COBOL A execução do código anterior apresenta três vezes o número 3 como resultado da operação para as variáveis R1, R2 e R3 a partir da instrução COMPUTE R1 R2 R3 = A + B. O comando COMPUTE para realizar as operações aritméticas segue a hierarquia matemática na aplicação dos opera- dores. Desejando alterar a ordem da prioridade das operações use parênteses sobre a operação de menor prioridade. É indicado que antes de abrir e fechar parêntese deixe pelo menos um espaço em branco. As operações aritméticas com valores decimais poderão sofrer ações de truncamento, dependendo da quantidade de casas decimais disponíveis. Por exemplo, um valor 5.29 será expresso em uma casa decimal como 5.2 quando trunca-do. No entanto, esta é uma situação que a apresentação do valor pode ocorrer como 5.3. Para conseguir este efeito basta usar o adjetivo ROUNDED logo após a variável que receberá o resultado da operação. Como exemplo, considere a definição de duas variáveis, sendo A formatada em duas casas decimais contendo o valor 5.20 e B formatada com duas casas decimais contendo o valor 0.09 e a variável R formatada apenas com uma casa decimal e qualificada para ser arredonda. DATA DIVISION. WORKING-STORAGE SECTION. 77 A PIC 99V99 VALUES 5.20. 77 B PIC 99V99 VALUES .09. 77 R PIC 99V9. PROCEDURE DIVISION. COMPUTE R = A + B. DISPLAY R. COMPUTE R ROUNDED = A + B. DISPLAY R. Se executadas as instruções anteriores serão apresentados os valores 05.2 e 05.3, sendo o primeiro truncado e o se-gundo arredondado. Observe que o uso de ROUNDED fez sua aproximação no dígito menos significativo somando 1 ao dígito mais significativo, o que fez o valor de 5.2 passar para 5.3. A operação de arredondamento para mais ou para menos é realizada quando o dígito mais significativo a ser truncado for maior ou igual a 5. Além do tratamento sobre truncamento de valores decimais podem ocorrer algumas situações de erro. Neste caso, o tratamento do erro é realizado pela frase [NOT] ON SIZE ERROR que possui a estrutura sintática: [NOT] ON SIZE ERROR . Onde mensagem é a definição personalizada de uma mensagem informativa de advertência apresentada quando al-guma situação de erro ocorre no programa. As mensagens devem ser operacionalizadas com o comando DISPLAY. As situações de erro que geram ocorrências são: Divisão por zero; Estouro de ponto flutuante ou insuficiente; O resultado da operação aritmética é maior que o campo de ponto fixo definido; Um número negativo elevado a uma potência fracionária; Zero aumentado para um número negativo; Zero elevado à potência zero. No sentido de fazer uma demonstração desta operação considere uma situação de estouro decimal com resultado de uma operação aritmética maior que o campo definido. Como exemplo, considere a definição de duas variáveis, sendo A formatada em duas casas decimais e uma posição antes do ponto decimal contendo o valor 9.5 e B formatada com duas casas decimais e uma posição antes do ponto decimal contendo o valor 1.5 e a variável R formatada com duas casas decimais e uma posição antes do ponto decimal. AÇÃO SEQUENCIAL 73 DATA DIVISION. WORKING-STORAGE SECTION. 77 A PIC 9V99 VALUES 9.5. 77 B PIC 9V99 VALUES 1.5. 77 R PIC 9V99. PROCEDURE DIVISION. COMPUTE R = A + B. DISPLAY R. Se executa as instruções anteriores será apresentado o valor 1.00 como resposta, sendo este um resultado inconclusi-vo, uma vez que deveria ser apresentado o valor 11.0. Assim sendo, observe a seguir o uso do trecho de tratamento de erro preparado para apresentar no monitor de vídeo uma mensagem de erro. Para fazer uso da frase ON SIZE ERROR com o comando COMPUTE deve-se colocado no final da expressão aritmética. DATA DIVISION. WORKING-STORAGE SECTION. 77 A PIC 9V99 VALUES 9.5. 77 B PIC 9V99 VALUES 1.5. 77 R PIC 9V99. PROCEDURE DIVISION. COMPUTE R = A + B ON SIZE ERRORDISPLAY "Inconclusivo". DISPLAY R. Se executadas as instruções ocorrerá a apresentação da mensagem “Inclusivo” em uma linha e a indicação do valor 0.00 na linha de baixo. Diferentemente da versão anterior, neste caso o resultado não é apresentado devido ao uso da frase [NOT] ON SIZE ERROR. Veja que a frase ON SIZE ERROR pode opcionalmente ser negada com o operador NOT. De fato, o modo de operação padrão do compilador é de NOT ON SIZE ERROR quando nenhuma situação de anormalidade ocorre. 2.3.2 Estilo descritivo O estilo descritivo de ação aritmética é realizado pelos verbos ADD, SUBTRACT, MULTIPLY e DIVIDE que fazem uso dos chamados operandos (variáveis ou constantes) que podem ser citados com ou sem separação por vírgulas. Devido a sua característica operacional esses verbos são executados na PROCEDURE DIVISION. ADD A declaração ADD efetua a soma dos operandos numéricos definidos e armazena o resultante da soma. Há, basica-mente, duas formas típicas para uso deste verbo - com auxílio da preposição TO e/ou com auxílio do verbo GIVING. Para realização dos testes relacionados as operações de adição a seguir considere a definição das variáveis A, B e C respectivamente com os valores 1.5, 2.5 e 3.5 definidas na DATA DIVISION com a máscara 9V99. DATA DIVISION. WORKING-STORAGE SECTION. 77 A PIC 9V99 VALUES 1.5. 77 B PIC 9V99 VALUES 2.5. 77 C PIC 9V99 VALUES 3.5. Para que a preposição TO possa ser usada é necessário que haja entre ADD e TO no mínimo um operando. Sua forma sintática segue o modelo: ADD VALOR-1 [[[VALOR-2] VALOR-3] ... VALOR-M] TO VALOR-N. 74 PROGRAMAÇÃO COBOL Quando a preposição TO é usada, os valores dos operandos que o antecedem são somados com o operando que o sucede, armazenando o resultado da soma sobre o operando sucessor. Como exemplo observe a apresentação da ação da soma realizada com o uso da preposição TO para os valores 1.5, 2.5 e 3.5 respectivamente relacionados as variáveis A, B e C, definidas anteriormente. PROCEDURE DIVISION. ADD A B TO C. DISPLAY C. Após a execução do exemplo é apresentado o resultado 7.50, sendo a soma dos valores das variáveis A, B e C com atualização do resultado sobre a variável C. Internamente ocorre a operação algébrica C = A + B + C. Para que o verbo GIVING possa ser usado é necessário que haja entre ADD e GIVING no mínimo dois operandos. Sua forma sintática segue o modelo: ADD VALOR-1 VALOR-2 [[VALOR-3] ... VALOR-M] GIVING VALOR-N. Quando o verbo GIVING é usado os valores dos operandos que o antecedem são somados e armazenados sobre o operando definido após o verbo GIVING, sobrepondo o valor deste operando. PROCEDURE DIVISION. ADD A B GIVING C. DISPLAY C. Após a execução do exemplo é apresentado o resultado 4.00, sendo a soma dos valores das variáveis A e B com atri-buição do resultado sobre a variável C, sobrepondo seu valor. Internamente ocorre a operação algébrica C = A + B. Foi comentado que o comando COMPUTE tem a característica de atribuir um mesmo resultado calculado a mais de uma variável, sendo que o mesmo se aplica ao uso do verbo ADD. Assim sendo, considere a soma da variável A com valor 1 e variável B com valor 2 atribuídas de uma única vez as variáveis R1, R2 e R3, todas com a máscara 9 DATA DIVISION. WORKING-STORAGE SECTION. 77 A PIC 9 VALUES 1. 77 B PIC 9 VALUES 2. 77 R1 PIC 9. 77 R2 PIC 9. 77 R3 PIC 9. PROCEDURE DIVISION. ADD A B GIVING R1 R2 R3. DISPLAY R1. DISPLAY R2. DISPLAY R3. Caso necessite usar com o verbo ADD o adjetivo ROUNDED para produzir valores arredondados após o uso da prepo- sição TO ou o verbo GIVING coloque-o no final da expressão seguindo o estilo: ADD A B TO C ROUNDED. ADD A B GIVING C ROUNDED. Caso necessite usar com o verbo ADD a frase ON SIZE ERROR para conter alguma ação indevida deve-se escrevê-la ao final da expressão, de acordo com o estilo: ADD A B TO C ON SIZE ERROR DISPLAY "Inconclusivo". ADD A B GIVING C ON SIZE ERROR DISPLAY "Inconclusivo". É perfeitamente possível fazer uso em conjunto do adjetivo ROUNDED e da frase ON SIZE ERROR como: AÇÃO SEQUENCIAL 75 ADD A B TO C ROUNDED ON SIZE ERROR DISPLAY "Inconclusivo". ADD A B GIVING C ROUNDED ON SIZE ERROR DISPLAY "Inconclusivo". Caso a composição de uma linha de instrução ultrapasse a septuagésima segunda coluna o conteúdo escrito poderá ficar dividido em duas ou mais linhas. Observe o exemplo seguinte: ADD A B TO C ROUNDED ON SIZE ERROR DISPLAY "Inconclusivo". ADD A B GIVING C ROUNDED ON SIZE ERROR DISPLAY "Inconclusivo". SUBTRACT A declaração SUBTRACT efetua a subtração de um ou faz a soma de dois ou mais operandos para em seguida subtrair e armazena o resultado obtido da diferença. Há, basicamente, duas formas típicas para uso deste verbo - com auxílio da preposição FROM e do verbo GIVING. Para realização dos testes relacionados as operações de subtração a seguir considere a definição das variáveis A, B, C e D respectivamente com os valores 1.5, 2.5, 3.5 e 0 definidas na DATA DIVISION com a máscara S9V99. DATA DIVISION. WORKING-STORAGE SECTION. 77 A PIC S9V99 VALUES 1.5. 77 B PIC S9V99 VALUES 2.5. 77 C PIC S9V99 VALUES 3.5. 77 D PIC S9V99 VALUES 0. Para que a preposição FROM possa ser usada é necessário que haja entre SUBTRACT e FROM no mínimo um ope-rando. Sua forma sintática segue o modelo: SUBTRACT VALOR-1 VALOR-2 [[VALOR-3] ... VALOR-M] FROM VALOR-N. Quando a preposição FROM é usada, os valores dos operandos que o antecedem são somados e subtraídos do ope-rando que o sucede, armazenando o resultado da subtração sobre o operando sucessor. Como exemplo observe a apresentação da ação da subtração realizada com o uso da preposição FROM para os valo- res 1.5, 2.5 e 3.5 respectivamente relacionados as variáveis A, B e C, definidas anteriormente. PROCEDURE DIVISION. SUBTRACT A B FROM C. DISPLAY C. Após a execução do anterior é apresentado o resultado -0.50, sendo este a soma dos valores das variáveis A e B sub- traídos do valor da variável C com atualização do resultado sobre a variável C. Internamente ocorre a operação algébri-ca C = C - (A + B). Para que o verbo GIVING possa ser usado é necessário que haja entre SUBTRACT e GIVING no mínimo dois operan-dos antecedentes a FROM. Sua forma sintática segue o modelo: SUBTRACT VALOR-1 VALOR-2 [[VALOR-3] ... VALOR-M] FROM VALOR-M GIVING VALOR-N. Quando o verbo GIVING é usado os valores dos operandos que o antecedem são somados e subtraídos do operando que antecede FROM tendo o resultado da operação armazenado no operando de sucede GIVING, preservando o con-teúdo do operando definido após FROM. Como exemplo observe a apresentação da ação da subtração realizada com o uso da preposição GIVING para os valores 1.5, 2.5, 3.5 e 0 respectivamente relacionados as variáveis A, B, C e D definidas anteriormente. 76 PROGRAMAÇÃO COBOL PROCEDURE DIVISION. SUBTRACT A B FROM C GIVING D. DISPLAY D. Após a execução do exemplo é apresentado o resultado -0.50, sendo este a soma dos valores das variáveis A e B subtraídos do valor da variável C e transferidos para a variável D e preservando assim o valor da variável C. Interna-mente ocorre a operação algébrica D = C - (A + B). Assim como COMPUTE e ADD o verbo SUBTRACT tem a característica de atribuir um mesmo resultado calculado a mais de uma variável. Assim sendo, considere a soma da variável A com valor 1.5, a variável B com valor 2.5 e a variá- vel C com valor 3.5 (sem alterar o valor de C) atribuídas de uma única vez as variáveis R1, R2 e R3, todas com a más-cara S9V99. DATA DIVISION. WORKING-STORAGE SECTION. 77 A PIC S9V99 VALUES 1.5. 77 B PIC S9V99 VALUES 2.5. 77 C PIC S9V99 VALUES 3.5. 77 R1 PIC S9V99. 77 R2 PIC S9V99. 77 R3 PIC S9V99. PROCEDURE DIVISION. SUBTRACTA B FROM C GIVING R1 R2 R3. DISPLAY R1. DISPLAY R2. DISPLAY R3. Problemas com arredondamento ou truncamentos de valores podem ser corrigidos com o uso do adjetivo ROUNDED e/ou da frase ON SIZE ERROR seguindo as mesmas regras apontadas no uso do verbo ADD. MULTIPLY A declaração MULTIPLY efetua a multiplicação de dois operandos e armazena o resultado do produto. Há, basicamen-te, duas formas típicas para uso deste verbo - com auxílio da preposição BY e do verbo GIVING. Para realização dos testes relacionados as operações de subtração a seguir considere a definição das variáveis A, B, C e D respectivamente com os valores 2, 3, 4 e 5 definidas na DATA DIVISION com a máscara 999. DATA DIVISION. WORKING-STORAGE SECTION. 77 A PIC 999 VALUES 2. 77 B PIC 999 VALUES 3. 77 C PIC 999 VALUES 4. 77 D PIC 999 VALUES 5. Para que a preposição BY possa ser usada é necessário que haja entre MULTIPLY e BY apenas um operando. Sua forma sintática segue o modelo: MULTIPLY VALOR-1 BY VALOR-2 [[VALOR-3] ... VALOR-N]. Quando a preposição BY é usada, o valor do operando que o antecede é multiplicado distributivamente pelos operan-dos definidos após a preposição BY armazenando os resultados nos operandos sucessores. Como exemplo observe a apresentação da ação da multiplicação realizada com o uso da preposição BY para os valo- res 2 e 3 respectivamente relacionados as variáveis A e B, definidas anteriormente. AÇÃO SEQUENCIAL 77 PROCEDURE DIVISION. MULTIPLY A BY B. DISPLAY B. Após a execução do anterior é apresentado o resultado 006, sendo este a multiplicação dos valores das variáveis A e B com atualização do resultado sobre a variável B. Internamente ocorre a operação algébrica B = A × B. Veja agora outro exemplo em que o valor da variável A é multiplicado pelo valor da variável B e pelo valor da variável C a partir do uso da preposição BY. PROCEDURE DIVISION. MULTIPLY A BY B C. DISPLAY B. DISPLAY C. Após a execução do exemplo anterior são apresentados os resultados 006 e 008, sendo o primeiro o valor da variável A multiplicado pelo valor da variável B e o segundo o valor da variável A multiplicado pelo valor da variável C. Para que o verbo GIVING possa ser usado é necessário que haja entre MULTIPLY e BY haja um operando. Sua forma sintática segue o modelo: MULTIPLY VALOR-1 BY VALOR-2 [[VALOR-3] ... VALOR-N] GIVING [VALOR-M]. Quando o verbo GIVING é usado os valores dos operandos entre a preposição BY são multiplicados distributivamente (se assim for o caso) tendo o resultado da operação armazenado no operando de sucede GIVING, preservando o con-teúdo dos operandos definidos após BY. PROCEDURE DIVISION. MULTIPLY A BY B GIVING C. DISPLAY C. Após a execução do exemplo é apresentado o resultado 006, sendo este a multiplicação dos valores das variáveis A com a variável B transferidos para a variável C e preservando assim o valor da variável B. Internamente ocorre a ope-ração algébrica C = A × B. Assim como COMPUTE, ADD e SUBTRACT o verbo MULTIPLY tem a característica de atribuir um mesmo resultado calculado a mais de uma variável, bastando indicar as variáveis receptoras uma a uma após o verbo GIVING. Problemas com arredondamento ou truncamentos de valores podem ser corrigidos com o uso do adjetivo ROUNDED e/ou da frase ON SIZE ERROR seguindo as mesmas regras apontadas no uso do verbo ADD. DIVIDE A declaração DIVIDE efetua a divisão de dois operandos e armazena o resultado do quociente. Há, basicamente, três formas típicas para uso deste verbo - com auxílio das preposições BY ou INTO e do verbo GIVING. Para realização dos testes relacionados as operações de subtração a seguir considere a definição das variáveis A, B, Q e R respectivamente com os valores 9, 7, 0 e 0 definidas na DATA DIVISION com a máscara S99V99. DATA DIVISION. WORKING-STORAGE SECTION. 77 A PIC S99V99 VALUES 9. 77 B PIC S99V99 VALUES 7. 77 Q PIC S99V99 VALUES 0. 77 R PIC S99V99 VALUES 0. Para que as preposições BY e INTO possam ser usadas é necessário que haja entre DIVIDE e BY ou INTO apenas um operando. No caso de uso da preposição BY usar o verbo GIVING será obrigatório. Sua forma sintática segue o mode-lo: 78 PROGRAMAÇÃO COBOL DIVIDE VALOR-1 BY[|INTO] VALOR-2 GIVING [VALOR-3]. Quando a preposição BY é usada, o valor do operando que antecede a preposição será dividido pelo valor que sucede a preposição, ou seja, VALOR-1 será dividido pelo VALOR-2 e o resultado do quociente será atribuído a VALOR-3. No entanto, se estiver em uso a preposição INTO ocorrerá o contrário o VALOR-2 será dividido pelo VALOR-1 e o resulta-do ficará armazenado em VALOR-2. Como exemplo observe a apresentação da ação da divisão realizada com o uso da preposição BY para os valores 9 e 7 respectivamente relacionados as variáveis A e B com armazenamento do quociente na variável Q definidas anterior-mente. PROCEDURE DIVISION. DIVIDE A BY B GIVING Q. DISPLAY Q. Após a execução do exemplo é apresentado o resultado +01.28, sendo este a divisão dos valores da variável A sobre a variável B com armazenamento do quociente na variável B. Internamente ocorre a operação aritmética Q = A ÷ B. Como exemplo observe a apresentação da ação da divisão realizada com o uso da preposição INTO para o valor 7 sobre o valor 9 relacionados as variáveis A com valor 9 e B com valor 7 tendo o armazenamento do quociente na variá-vel B definidas anteriormente. PROCEDURE DIVISION. DIVIDE A INTO B. DISPLAY B. Após a execução do exemplo é apresentado o resultado +00.77, sendo este a divisão dos valores da variável B sobre a variável A com armazenamento do quociente na variável B. Internamente ocorre a operação aritmética B = B ÷ A. O cálculo de divisão permite obter o resultado do resto a partir do uso do comando (substantivo) REMAINDER usado ao final de uma expressão de divisão. Sua forma sintática segue o modelo: DIVIDE VALOR-1 BY[|INTO] VALOR-2 GIVING [VALOR-3] REMAINDER [VALOR-4]. Para fazer uso do comando REMAINDER é obrigatório usar em conjunto o verbo GIVING, lembrando que esse coman-do é ideal para operar com valores inteiros e não decimais. Assim sendo, é necessário ajustar os valores das variáveis A, B, Q e R na DATA DIVISION para 9 e 7 mantendo as demais variáveis com 0. Use a máscara 9. Como exemplo observe a apresentação da ação da divisão realizada com o uso da preposição BY para os valores 9 e 7 respectivamente relacionados as variáveis A e B com armazenamento do quociente na variável Q e valor de resto armazenado na variável R definidas anteriormente. PROCEDURE DIVISION. DIVIDE A BY B GIVING Q REMAINDER R. DISPLAY Q. DISPLAY R. Após a execução do exemplo é apresentado o resultado do quociente como 1 e do resto da divisão como 2 sendo o primeiro valor o resultado da divisão com quociente inteiro da variável A sobre a variável B e o segundo valor sendo o resultado resto da divisão obtido a partir do valor do dividendo (variável A) subtraído do valor do divisor (variável B) multiplicado pelo valor do quociente da divisão da variável A sobre a variável B. Problemas com arredondamento ou truncamentos de valores podem ser corrigidos com o uso do adjetivo ROUNDED e/ou da frase ON SIZE ERROR seguindo as mesmas regras apontadas no uso do verbo ADD. AÇÃO SEQUENCIAL 79 2.3.3 Algébrico versus descritivo Diferentemente de outras linguagens de programação, a linguagem COBOL possui dois estilos para o estabelecimento de operações aritméticas a partir de definições algébricas para a realização do processamento matemático, o que pode ocasionar certa dúvida no sentido de intuir qual dos estilos deve ou pode ser usado. Qual dos estilos usar? Algébrico ou descritivo? Para responder esta pergunta é necessário perceber, primeiro, que a forma descritiva usa um estilo sintático como se fosse a escrita de uma frase com substantivos, verbos, preposições e adjetivos. Aliás essas figuras são perceptíveis neste estilo, como foi apresentado,dando um toque mais “humano” na linguagem. O estilo descritivo deixa a forma escrita de uma expressão matemática mais humanizada, menos matematizada, o que, de certa maneira, é interessante. No entanto causa um efeito colateral, chamado em computação de verbosidade. A linguagem COBOL é, por sua natureza, verbosa uma vez que busca se aproximar da forma escrita da língua inglesa, isso faz com que a escrita de instruções se torne maior do que, eventualmente, poderia ser e muitas vezes pode se tornar muito confusa para as pessoas, dependendo do grau de conhecimento e experiência na linguagem que essas pessoas tenham. Para dar ideia sobre o que está sendo comentado, observe o exemplo a seguir para a realização do cálculo do valor de venda de um produto. O exemplo apresentado é uma adaptação do material de estudo da linguagem COBOL disponibi-lizado por Carlos Alberto Dornelles no sítio cadcobol (http://www.cadcobol.com.br/). MULTIPLY QUANT BY VLR-UNIT GIVING VENDAS DIVIDE TAXA INTO VENDAS Observe na sequência forma descrita ao estilo algébrico. COMPUTE VENDAS = QUANT * VLR-UNIT / TAXA É perceptível que o estilo algébrico em sua forma matematizada expressa a operação como uma equação. Isso faz com que a leitura da expressão seja mais rápida e confortável, desde que o programador se sinta à vontade com o estilo matemático. No entanto, haverá ocasiões que usar o estilo descritivo será mais vantajoso que usar o estilo algébrico. Na prática é importante ao programador COBOL conhecer adequadamente as formas algébrica e descritiva de expres-sar operações matemáticas para perceber quando usar um ou outro estilo. Outro ponto importante em saber bem as duas formas é que parte do trabalho computacional é realizar serviços de manutenção em programas que estão a muito em execução. A possibilidade de encontrar essa diversidade operacional nas organizações é muito grande. Cada pessoa desenvolve sua percepção e aceitação operacional sobre um ou outro estilo. Desta forma, as respostas para as perguntas feitas anteriormente, é basicamente simples. Escolha o estilo que melhor lhe convém em determina-do momento. Em sistemas mais antigos a probabilidade de encontrar o estilo descritivo é maior que o uso da forma algébrica, mas também seu uso é encontrado em programas mais recentes. Em relação a este tema há algo a ser levado em grande consideração. Preferencialmente em seu código de programa, adote um estilo em detrimento ao outro, seja qual for. Evite misturar em excesso essas formas em seu código, pois isto poderá trazer dificuldades nas ações de manutenção dos programas. Use simultaneamente os dois estilos em caso de alguma das formas não atender adequadamente e eficientemente o que é necessário ser feito. 2.3.4 Funções intrínsecas A operação mais importante realizada por um computador, não importa seu tamanho e tipo, é sem sombra de dúvidas o processamento de dados, principalmente as operações que realizam os cálculos matemáticos. Além dos recursos exis-tentes para a definição de variáveis e constantes, a linguagem COBOL possui internamente uma coleção de funcionali-dades que dão suporte a realização de tarefas matemáticas, lógicas, estatísticas, calendário, financeiras, entre outras. Uma função é um recurso que efetua uma operação e devolve uma resposta sobre a operação realizada. Uma função pode fazer ou não uso de argumentos. Por exemplo, as funções anteriormente usadas como constantes “E” e “PI” são exemplos de funções que são operacionalizadas sem o uso de argumentos. Há funções que operam com um ou mais argumentos ou mesmo uma lista de valores. 80 PROGRAMAÇÃO COBOL A título de ilustração é apresentado um pequeno conjunto de funções estatísticas e matemáticas que utilizam argumen-tos como valores isolados, mais de um valor e lista de valores. FUNÇÕES ESTATÍSTICAS As funções estatísticas são usadas para auxiliar o tratamento, análise, interpretação e apresentação de dados numéri-cos. Neste sentido, para auxiliar esta tarefa a linguagem COBOL oferece algumas funções, das quais estão sendo des-tacadas as funções MAX (extrai o maior valor numérico de uma lista), MEDIAN (calcula a média dos valores de uma lista), MIN (extrai o menor valor numérico de uma lista) e SUM (calcula o somatório dos valores de uma lista). O trecho de código a seguir mostra como exemplo alguns resultados estatísticos obtidos a partir de uma pequena lista de valores (5, 1, 9, 2, 8, 3, 7, 4, 6) definidos na PROCEDURE DIVISION e apresentadas com o comando DISPLAY. PROCEDURE DIVISION. DISPLAY FUNCTION MAX(5, 1, 9, 2, 8, 3, 7, 4, 6). | mostra o valor: 9 DISPLAY FUNCTION MEDIAN(5, 1, 9, 2, 8, 3, 7, 4, 6). | mostra o valor: 5 DISPLAY FUNCTION MIN(5, 1, 9, 2, 8, 3, 7, 4, 6). | mostra o valor: 1 DISPLAY FUNCTION SUM(5, 1, 9, 2, 8, 3, 7, 4, 6). | mostra o valor: 45 FUNÇÕES MATEMÁTICAS As funções matemáticas são usadas para auxiliar diversas operações que necessitam de ações de cunho genéricos. Neste sentido, para auxiliar esta tarefa a linguagem COBOL oferece algumas funções, das quais estão sendo destaca-das as funções ABS (retornar o valor indicado sempre como positivo), FACTORIAL (retornar a multiplicação sucessiva de 1 até o valor fornecido como limite), INTEGER (retornar de um valor numérico decimal apena s a parte inteira), REM (retornar o valor do resto de uma divisão de dois valores) e SQRT (retornar a raiz quadrada de um valor informado). PROCEDURE DIVISION. DISPLAY FUNCTION ABS(-5). | mostra o valor: +5 DISPLAY FUNCTION FACTORIAL(5). | mostra o valor: 120 DISPLAY FUNCTION INTEGER(8.25). | mostra o valor: 8 DISPLAY FUNCTION REM(9, 7). | mostra o valor: 2 DISPLAY FUNCTION SQRT(2). | mostra o valor: 1.41421356237309504880168 (...) Não é objetivo descrever na totalidade as funções existentes na linguagem. Para conhece-las consulte qualquer manual de referência, normalmente chamado language reference para acesso a lista completa de funções do compilador em uso. Para o GnuCOBOL a relação de funções encontra-se no manual GNU COBOL 2.0 Programmer´s Guide disponí- vel para obtenção no sítio https://open-cobol.sourceforge.io/guides/GNUCobol2.pdf, seção 6.1.7, página 6-21. Atente para o fato de serem essas funções mecanismos auxiliares para a realização de ações de cálculos na etapa de processamento matemático. Eventualmente outras funções são apresentadas neste livro na medida em que necessita-rem serem utilizadas. 2.4 ENTRADAS E SAÍDAS Após tratar o tema sobre processamento matemático, uma das etapas mais importantes na programação de computa-dores cabe agora tratar o tema relacionado as ações de entrada e saída de dados que cumprem com o processamento atender ao tema central deste capítulo: ação sequencial. Um programa de computador executa as etapas de entrada de dados, processamento de dados e saída de dados que servirão como base para a geração de informações que serão usadas nas estratégias de tomadas de decisões pelas organizações. Parte das ações de saída de dados foram usadas desde o capítulo anterior por meio do comando DISPLAY demons-trado de forma simples, apenas para contextualizar alguns exemplos operacionais. Neste tópico o comando DISPLAY AÇÃO SEQUENCIAL 81 destinado a saída será operacionalizado em conjunto com o comando ACCEPT responsável pela execução da entrada de dados com um nível de detalhe maior. O comando DISPLAY possui alguns estilos de definição e escrita, mas neste momento é apresentado apenas a forma básica para a definição da ação de saída de dados de forma genérica DISPLAY [UPON ] [WITH NO ADVANCING] Onde, mensagem é algo a ser impresso no monitor de vídeo (conteúdo entre aspas inglesas na forma de cadeia) e dispositivo é a definição de um nome de referência interno do ambiente vinculado como saída e mencionado na seção de configuração da ENVIRONMENT DIVISION no parágrafo SPECIAL-NAMES da seção CONFIGURATION SECTION com a indicação de uso do substantivoCONSOLE e o verbo IS. O comando DISPLAY tem por finalidade transferir o conteúdo de cada operando (variáveis ou campos) que se encon-tram na memória para o dispositivo de saída, normalmente monitor de vídeo. O uso da preposição UPON é opcional e deverá ser usada se houver a definição de um nome de referência para o dispositivo de saída na seção de configuração. Caso seja omitido é assumido como padrão o dispositivo de saída de dados conectado ao computador: monitor de vídeo. A preposição UPON pode ser associada a nomes de dispositivos de saída, como CONSOLE, SYSOUT, SYSLIST, SYSLST ou STDOUT que estejam relacionados ao parágrafo SPECI- AL-NAMES. Em particular as indicações: CONSOLE, SYSOUT, SYSLIST e SYSLST são formas lógicas de se fazer referência ao dispositivo de saída físico conectado ao sistema denominado STDOUT. A frase WITH NO ADVANCING é opcional e tem por finalidade manter o cursor na linha após a apresentação da men-sagem. O comando ACCEPT também possui alguns estilos de definição e escrita, mas neste momento é apresentado apenas a forma básica para a definição da ação de entrada de dados de forma genérica. ACCEPT [FROM ] Onde, identificador é um dado de entrada fornecido pelo sistema operacional ou via teclado pelo usuário do programa e dispositivo é a definição de um nome de referência interno do ambiente vinculado como entrada e mencionado na seção de armazenamento da ENVIRONMENT DIVISION do parágrafo SPECIAL-NAMES da seção CONFIGURATION SECTION com a indicação de uso do substantivo CONSOLE e o verbo IS. O comando ACCEPT tem por finalidade transferir o conteúdo do dispositivo de entrada, normalmente o teclado para os operandos (variáveis ou campos) a fim de armazená-los em memória. O uso da preposição FROM é opcional e é usada se houver a definição de um nome de referência para o dispositivo de saída na seção de configuração. Caso seja omitido o programa assume como padrão o dispositivo de entrada de dados conectado ao computador: o teclado. A preposição FROM pode ser associada a nomes de dispositivos de entrada, como CONSOLE, SYSIN, SYSIPT ou STDIN que estejam relacionados ao parágrafo SPECIAL-NAMES. Em particular as indicações: CONSOLE, SYSIN e SYSIPT são formas lógicas de se fazer referência ao dispositivo de entrada físico conectado ao sistema denominado STDIN. Tomando por base o que foi explicado considere como exemplo de uso dos comandos de entrada e saída o trecho de código exemplificado a seguir que solicita a entrada do nome em formato alfabético do usuário contendo 30 caracteres de tamanho e apresenta uma mensagem de saudação. DATA DIVISION. WORKING-STORAGE SECTION. 77 NOME PIC A(30). PROCEDURE DIVISION. DISPLAY "Entre seu nome, por favor: " WITH NO ADVANCING ACCEPT NOME. DISPLAY "Ola, " NOME. 82 PROGRAMAÇÃO COBOL Ao ser executado um programa, que contenha a estrutura definida anteriormente, será apresentada inicialmente a men-sagem solicitando a entrada. Neste momento o programa fica aguardando a entrada. Após realizar a entrada ocorre a apresentação da mensagem de saudação do nome e mostram as imagens das figuras 2.2 e 2.3. Figura 2.2 – Mensagem de entrada Figura 2.3 – Mensagem de saída Com o objetivo de apresentar a utilização dos adjetivos FROM e UPON respectivamente para os comandos ACCEPT e DISPLAY considere como exemplo a mesma situação anterior e observe os trechos sinalizados colorizados apontando o uso desses recursos. Para o direcionamento da saída é definido o dispositivo com o nome MEU-VIDEO e para o direcionamento da entrada é definido o dispositivo com o nome MEU-TECLA. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. CONSOLE IS MEU-VIDEO. CONSOLE IS MEU-TECLA. DATA DIVISION. WORKING-STORAGE SECTION. 77 NOME PIC A(30). PROCEDURE DIVISION. DISPLAY "Entre seu nome, por favor: " UPON MEU-VIDEO WITH NO ADVANCING. ACCEPT NOME FROM MEU-TECLA. DISPLAY "Ola, " NOME UPON MEU-VIDEO. Uma atenção especial no trecho de código apresentado é a separação da linha de instrução com o comando DISPLAY que mostra a mensagem solicitando a entrada do nome. Note que a frase WITH NO ADVANCING é posicionada logo abaixo do comando DISPLAY. Isto foi feito, pois a linha de código completa ultrapassa a septuagésima segunda coluna do formulário, e tudo que passa da coluna 72 não é avaliado pelo compilador. Outro detalhe, é a citação do dispositivo CONSOLE indicando ações de entrada e saída. Essa forma pode ser definida com outros sinônimos deixando o código do programa menos genérico, dando-lhe mais especificidade. Observe o tre-cho do parágrafo SPECIAL-NAMES com as indicações de STDIN para a entrada e STDOUT para a saída, podendo-se usar qualquer outra referência das indicadas, cada qual, representado seu dispositivo de ação. O único nome de dispo-sitivo que pode ser usado em comum é CONSOLE. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. STDOUT IS MEU-VIDEO. STDIN IS MEU-TECLA. AÇÃO SEQUENCIAL 83 A partir de agora já se tem em mãos o que é necessário para começar a escrever os primeiros programas codificados e contextualizados em COBOL, pois todas as ferramentas, mínimas, necessárias foram apresentadas: ações de entrada, ações de processamento (variáveis, constantes, operadores aritméticos e funções) e ações de saída. 2.5 HORA DE PROGRAMAR Nesta etapa são colocadas em prática, grande parte do que foi visto nos tópicos e capítulo anterior e mais alguns deta-lhes, apresentados. A partir deste ponto você terá em mãos o ferramental mínimo necessário para começar a escrever seus primeiros programas, ainda simples, mas muito impactantes. Nesta parte são apresentados três problemas com- putacionais genéricos e codificação dos problemas na forma de programas com grau de rigor mínimo. É fundamental perceber que quem trabalha com desenvolvimento de software estará sempre a frente de algum proble-ma que deve primeiro ser resolvido por ele mesmo para depois dar uma solução computacional. Desta forma, mantenha sua atenção a cada problema apresentado, bem como a solução indicada. CÁLCULO DE ADIÇÃO SIMPLES Elaborar programa de computador que efetue a entrada de dois valores numéricos inteiros desconhecidos negativos ou positivos de até três posições (unidade, dezena e centena) e apresente em seguida o resultado da soma dos valores fornecidos. Para o desenvolvimento deste programa há um detalhe importante a ser considerado: tomando por base que a entrada dos dados usará a máscara 999, torna-se necessário intuir que para a saída do resultado será necessário uma máscara com a configuração 9999, pois a soma do valor 800 com o valor 200 resulta no valor 1000, ou seja, somar dois valores de três posições (unidade, dezena e centena) pode resultar na obtenção máxima de um valor de quatro posições (uni-dade, dezena, centena e unidade de milhar). Selecione e defina um projeto do programa vazio com o nome c02ex01.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C02EX01 AS "Capitulo 2 – Exemplo 1". DATA DIVISION. WORKING-STORAGE SECTION. 77 EA PIC S9(3). 77 EB PIC S9(3). 77 RC PIC S9(4). 77 SR PIC Z(4). 78 CR VALUE X"0D". 77 EN PIC X. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY "Entre valor : " WITH NO ADVANCING. ACCEPT EA. DISPLAY "Entre valor : " WITH NO ADVANCING. ACCEPT EB. COMPUTE RC = EA + EB. MOVE RC TO SR. DISPLAY CR. DISPLAY "Resultado =" SR. DISPLAY X"0D". DISPLAY "Tecle para encerrar... " ------------------------------------------------------------------------ 84 PROGRAMAÇÃO COBOL ------ LINHAS ------ 23 24 25 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- WITH NO ADVANCING. ACCEPT EN. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. Você verá diversos detalhes conhecidos e outros nem tanto. Um detalhe comentado, mas não exemplificado encontra-se na linha 2. Veja que após a identificação do programa com o comando PROGRAM-ID que deve ter no máximo oito caracteres usa-se a preposição AS com um termo de identifica- ção para o programa que poderá ter no máximo 31 caracteres. Esse recurso permite identificar um programa de manei-ra mais legível que o indicativo de PROGRAM-ID. Na linha 15 é definido um parágrafo personalizado PROG-PRINCIPAL-PARA na PROCEDURE DIVISION. Dentro das recomendações de codificação COBOL há a orientação de que as instruções da divisão de procedimento sejam escri-tas dentro de um parágrafo (no mínimo). A ausência deste parágrafo personalizado não interfere na execução do pro-grama, serve apenas como elementos de formatação de código. As variáveis EA (Entra A) e EB (Entra B) definidas respectivamente nas linhas 6 e 7 são usadas para a efetivação das ações de entrada nas linhas 17 e 19 a partir do uso do comando ACCEPT. A linha 8 apresenta a definição da variável RC (R Calculado) usada na linha 20 para a efetivação do processamento e atribuição do resultado calculado com o comando COMPUTE, além de ser usada para ter seu conteúdo movimentado para a variável SR (Saída de R) na linha 21 que efetivamente retira os zeros a esquerda existentes quando do uso das más- caras formatadas com o código 9. Na linha 9 é definida a variável SR usada como campo editado para auxiliar a formatação do valor numérico do resultado de RC transferido para esta variável a partir da execução da instrução da linha 21 com o objetivo de ser apresentado na linha 23. A linha 11 apresenta a definição da constante chamada CR (Carriege Return, ou seja, a tecla ) associada ao valor X"0D". O valor X"0D" indica por meio do código X o uso de um número hexadecimal, neste caso 0D (código ASCII referente a tecla ) que permitirá definir um caractere de salto de linha para pular linhas na apresentação de informações no monitor de vídeo como efetuado na linha 22. Na linha 12 é definida a variável EN (Entrada) com apenas uma posição alfanumérica que será usada na ação da linha 27. O conjunto de linhas de código entre 16 e 19 são usadas para proceder a entrada dos dados no programa. Observe que nas linhas 16 e 18 usa-se a frase WITH NO ADVANCING com o objetivo de manter o cursor na mesma linha após a apresenta- ção das mensagens. Nas linhas 17 e 19 são efetivadas as entradas com o comando ACCEPT. A linha 20 efetua o processamento da soma das variáveis EA e EB atribuindo o resultado da operação na variável RC. Na linha 21 ocorre a movimentação do conteúdo da variável RC para a variável SR. Nesta etapa os valores zeros de uma máscara com código 9 são suprimidos devido a definição da máscara da variável SR com o código Z. A linha 22 efetua a apresentação do conteúdo da variável CR que neste caso efetua um salto de linha em branco no monitor de vídeo. Na linha 23 ocorre a apresentação do resultado no monitor de vídeo sem a existência de zeros à esquerda caso o valor apre- sentado seja menor que quatro posições. A linha 24 efetua um salto de linha em branco com o uso direto do valor X"0D". Neste momento, é deixado como exemplo uma segunda alternativa para executar saltos de linha, ficando a critério do programador escolher qual forma a ser usada. Nas linhas 25 e 26 encontra-se definida a apresentação da mensagem solicitando que a tecla seja acionada para que o programa tenha continuidade. Pelo fato dessa instrução ultrapassar o limite de 72 posições permitida no formulário, fez-se sua divisão em duas linhas. Nesta obra, as linhas divididas, para melhor visualização, serão grafadas com endentação de duas posições abaixo de sua continuidade. AÇÃO SEQUENCIAL 85 A linha 27 é feita uma parara temporária de execução no programa, neste caso aguardando que o usuário tecle, no teclado, a tecla . Não existe na linguagem COBOL um comando específico para o estabelecimento de pausas temporárias em programas, o que leva a necessidade de definição de um mecanismo de interrupção como o apresentado. O conteúdo arma- zenado na variável EN não é, tipicamente, tratado. Os detalhes usados entre as linhas de 25 até 27 são um mero artifício de interrupção. CÁLCULO SALARIAL Elaborar programa de computador que calcule o salário líquido de um profissional que trabalhe por hora. Para tanto, é necessário possuir alguns dados, tais como valor da hora de trabalho (variável HT), número de horas trabalhadas no mês (variável VH) e o percentual de desconto do INSS (variável PD), para que seja possível apresentar os resultados do salário bruto (variável SB), do valor descontado (variável VH) e do salário líquido (variável SL). Para o desenvolvimento deste programa é levado em consideração algumas informações adicionais para a devida configuração do espaço de memória a ser utilizado e do uso adequado da aplicação uso. Imagine operar a saída de valores com a máscara financeira $ 99.999,99. Neste caso, a máscara ideal para a entrada de dados é 9,999.99. Para a taxa o ideal é uma máscara que opera na faixa de valores entre 0.0000 até 1.0000 (equivalente de 0% a 100%). As variáveis de entrada HT e VH são formatadas com base na estrutura 9999.99 a partir da máscara 9(4)V99. A variá-vel de entrada PD baseada na estrutura 9.9999 é formatada com a máscara 9V9(4). As variáveis de recepção dos cálculos SB, TD e SL são formatadas com base na estrutura 99999.99 a partir da másca-ra 9(5)V99. Observe, como regra geral, que é sempre adequado colocar um dígito a mais de tamanho nas variáveis que recepcio-nam resultados de processamento. Por exemplo, se for somada a unidade 1 com a unidade 9 tem-se o valor 0 na uni-dade e o vai-um do 1 excedente para a dezena formando o valor 10. Outra preocupação que se deve ter no modelo de programação COBOL é a definição das variáveis de saída formatadas a partir de campos de edição. Essas variáveis não são, e não podem ser usadas na realização das operações algébricas e aritméticas, elas servem apenas para auxi-liar a saída desses dados. Para este programa essas variáveis são representadas pelos rótulos S-SB, S-TD e S-SL utilizando-se a máscara $BZZ,ZZ9.99 a fim de proporcionar o formato de saída como $ 99.999,99. Selecione e defina um projeto do programa vazio com o nome c02ex02.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C02EX02 AS "Capitulo 2 – Exemplo 2". DATA DIVISION. WORKING-STORAGE SECTION. 77 HT PIC 9(4)V99. 77 VH PIC 9(4)V99. 77 PD PIC 9V9(4). 77 SB PIC 9(5)V99. 77 TD PIC 9(5)V99. 77 SL PIC 9(5)V99. 77 S-SB PIC $BZZ,ZZ9.99. 77 S-TD PIC $BZZ,ZZ9.99. 77 S-SL PIC $BZZ,ZZ9.99. 77 EN PIC X. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY "Entre horas trabalhadas ........: " WITH NOADVANCING. ACCEPT HT. ------------------------------------------------------------------------ 86 PROGRAMAÇÃO COBOL ------ LINHAS ------ 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- DISPLAY "Entre valor da hora ............: " WITH NO ADVANCING. ACCEPT VH. DISPLAY "Entre percentual de desconto ...: " WITH NO ADVANCING. ACCEPT PD. COMPUTE SB = HT * VH. COMPUTE TD = (PD / 100) * SB. COMPUTE SL = SB - TD. MOVE SB TO S-SB. MOVE TD TO S-TD. MOVE SL TO S-SL. DISPLAY X"0D". DISPLAY "Salario bruto ....: " S-SB. DISPLAY "Desconto .........: " S-TD. DISPLAY "Salario liquido ..: " S-SL. DISPLAY X"0D". DISPLAY "Tecle para encerrar... " WITH NO ADVANCING. ACCEPT EN. STOP RUN. ------------------------------------------------------------------------ Após compilar, coloque o programa em execução, forneça os valores 100 (horas trabalhadas), 250 (valor da hora) e 5.5 (percentual de desconto) e veja o conjunto de dados apresentados com os valores do salário bruto, desconto calculado e salário líquido. Esse conjunto de dados forma a base de uma informação: o contra cheque de um trabalhador. Salario bruto ....: $ 25,000.00 Desconto .........: $ 1,375.00 Salario liquido ..: $ 23,625.00 Observe que o programa opera seus valores financeiros no formato usado nos Estados Unidos da América com milha-res separadas por vírgulas e decimais separados por ponto, diferente do padrão usado no Brasil em que milhares são separadas por pontos e decimais separadas por vírgula. O fato é que a linguagem COBOL possui um recurso especifi- co para tratar exclusivamente este tipo de formatação. Veja no código seguinte algumas alterações no programa. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 12 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C02EX02 AS "Capitulo 2 – Exemplo 2". ENVIRONMENT DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. DECIMAL-POINT IS COMMA. DATA DIVISION. WORKING-STORAGE SECTION. 77 HT PIC 9(4)V99. 77 VH PIC 9(4)V99. 77 PD PIC 9V9(4). 77 SB PIC 9(5)V99. ------------------------------------------------------------------------ AÇÃO SEQUENCIAL 87 ------ LINHAS ------ 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- 77 TD PIC 9(5)V99. 77 SL PIC 9(5)V99. 77 S-SB PIC $BZZ.ZZ9,99. 77 S-TD PIC $BZZ.ZZ9,99. 77 S-SL PIC $BZZ.ZZ9,99. 77 EN PIC X. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY "Entre horas trabalhadas ........: " WITH NO ADVANCING. ACCEPT HT. DISPLAY "Entre valor da hora ............: " WITH NO ADVANCING. ACCEPT VH. DISPLAY "Entre percentual de desconto ...: " WITH NO ADVANCING. ACCEPT PD. COMPUTE SB = HT * VH. COMPUTE TD = (PD / 100) * SB. COMPUTE SL = SB - TD. MOVE SB TO S-SB. MOVE TD TO S-TD. MOVE SL TO S-SL. DISPLAY X"0D". DISPLAY "Salario bruto ....: " S-SB. DISPLAY "Desconto .........: " S-TD. DISPLAY "Salario liquido ..: " S-SL. DISPLAY X"0D". DISPLAY "Tecle para encerrar... " WITH NO ADVANCING. ACCEPT EN. STOP RUN. ------------------------------------------------------------------------ Após recompilar, coloque o programa em nova execução e entre respectivamente os valores 100, 250 e 5,5 atentando para o fato de fornecer a vírgula decimal na entrada do valor 5,5. Se a vírgula não for fornecida ocorrerá erro no pro-cessamento do cálculo. Veja o conjunto de dados apresentados após a alteração de ponto decimal para vírgula deci-mal. Salario bruto ....: $ 25.000,00 Desconto .........: $ 1.375,00 Salario liquido ..: $ 23.625,00 Observe no código as indicações das linhas 3 a 6 na cor vermelho. Na linha 3 é definida a ENVIRONMENT DIVISION, responsável por configurar e alterar o comportamento do ambiente do programa, veja na CONFIGURATION SECTION indicada na linha 4 a definição do parágrafo SPECIAL-NAMES indicado na linha 5 contendo na linha 6 a definição da frase para configuração DECIMAL-POINT IS COMMA. A frase DECIMAL-POINT IS COMMA orienta que o ponto deci- mal (DECIMAL-POINT) é a partir de agora (IS) representado por vírgula (COMMA). Com a troca da simbologia de representação de valores financeiro no padrão brasileiro torna-se necessário no progra-ma proceder a uma outra alteração. As máscaras definidas como $BZZ,ZZ9.99 devem ser alteradas para $BZZ.ZZ9,99, trocando-se o ponto para vírgula e a vírgula para ponto como indicado na cor verde. 88 PROGRAMAÇÃO COBOL DIVISÃO DE INTEIROS Elaborar programa de computador que a partir da entrada dos valores inteiros do dividendo e do divisor apresente como resultado os valores do quociente inteiro e do resto da divisão. Para o desenvolvimento deste programa deve ser levado em consideração que há duas maneiras de resolve-lo: utili-zando-se o estilo algébrico ou estilo descritivo. No estilo descritivo existem todos os recursos para conseguir este inten-to. No entanto, o estilo algébrico não possui um recurso definido para o cálculo do resto da divisão, devendo esta ques- tão ser tratada pelo programador. O estilo a seguir baseia-se na forma algébrica, no intuito de demonstrar uma solução por parte do programador e não da linguagem. A final de contas, para que serve um programador? Selecione e defina um projeto do programa vazio com o nome c02ex03.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C02EX03 AS "Capitulo 2 – Exemplo 3". DATA DIVISION. WORKING-STORAGE SECTION. 77 EN PIC 9(3). 77 ED PIC 9(3). 77 QC PIC 9(3). 77 RC PIC 9(3). 77 SQ PIC Z(3). 77 SR PIC Z(3). PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY "Entre o dividendo ..: " WITH NO ADVANCING. ACCEPT EN. DISPLAY "Entre o divisor ....: " WITH NO ADVANCING. ACCEPT ED. COMPUTE QC = EN / ED. COMPUTE RC = EN - ED * QC. MOVE QC TO SQ. MOVE RC TO SR DISPLAY X"0D". DISPLAY "Quociente ..........: " SQ. DISPLAY "Resto ..............: " SR. DISPLAY X"0D". DISPLAY "Tecle para encerrar... "WITH NO ADVANCING. ACCEPT EN. STOP RUN. ------------------------------------------------------------------------ Ao ser executado o programa informe os valores do dividendo e do divisor é o programa apresentará os resultados do quociente e resto calculados a partir do estilo algébrico e não descritivo. Entre os recursos usados no programa, sua maioria já conhecidos, ocorre o uso da operação COMPUTE QC = EN / ED usada na linha 19 que efetua a divisão de duas variáveis definidas como valores inteiros e neste caso gera como quoci-ente um valor inteiro. O operador de divisão se adapta ao tipo de dado usado. AÇÃO SEQUENCIAL 89 2.6 DOCUMENTAÇÃO: COLUNA 7 Um dos pontos importantes em programação é a definição no código escrito de linhas de comentários que descrevam e lembrem ao programador detalhes e/ou características definidos no programa para uma eventual manutenção do códi-go fonte. A linhagem COBOL possui três formas de estabelecer este princípio: uma com o uso do símbolo asterisco (*) ou (*>) para documentação de linhas. O asterisco (*) deve sempre ser definido na sétima coluna do formulário (coluna CONT de continuity - continuidade) quando se usa o estilo de codificação em formato fixo, o símbolo (*>) pode ser usado em qualquer lugar do código para comentar uma linha ou ser usado nos comentários do formato livre Parte da documentação do código é auxiliada pelo próprio compilador, pois este pode apresentar mensagens de adver-tência informando que determinado recurso em uso é obsoleto. Neste caso, é hora de aprender a fazer a mesma coisa de outra forma, pois isto significa que o recurso apontado como obsoleto não estará presente na próxima revisão de padrão da linguagem. Aqui tem-se a primeira barreira de auxílio a documentação avisando alterações mais radicais da linguagem. Outro detalhe importante é que parte da documentação de um código COBOL pode ser definido dentro da EVIRONMENT DIVISION. Os programas escritos em COBOL seguem a uma estrutura baseada em divisões, seções, parágrafos, sentenças, ins-truções, cláusulas e frases que permitem a definição de documentação setorizada. Uma pequena introdução a forma de documentação foi apresentada anteriormente, no capítulo 1, quando da criação de um projeto de programa no ambiente OpenCobolIDE. Neste tópico este assunto será tratado com maior profundidade. Para que linhas de comentário e outras definições de documentação sejam usadas em COBOL é importante inicia-las sempre a partir da sétima posição do formulário com o símbolo asterisco. Observe a seguir as instruções com os princí-pios básicos dessa tarefa. As orientações descritas a seguir podem ser adotadas de forma diferente em certas organi-zações. Existe um grau liberdade em configurá-las. Segue aqui uma pequena sugestão de como proceder este evento, de acordo com o que se tem em média no mercado. O primeiro ponto considerado na documentação COBOL é a definição de linhas de separação para as divisões padrão da linguagem. Normalmente, usa-se para separar divisões uma sequência de símbolos de igualdade (=). *================================================================= IDENTIFICATION DIVISION. *================================================================= O segundo ponto de documentação COBOL a ser considerado é a identificação das pessoas envolvidas com o desen-volvimento da aplicação como analistas de sistemas responsáveis, programadores envolvidos, identificação da empre-sa, data de criação do programa, data de modificação do programa, descrição da finalidade do programa, etc. Este nível de documentação é definido abaixo da PROGRAM-ID na IDENTIFICATION DIVISION. Normalmente, usa-se para este trecho uma sequência de símbolos asterisco (*). Os campos marcados com X e 9 devem ser substituídos pelas informações desejadas ou necessárias. ****************************************************************** ** ** ** AUGUSTO MANZANO – TECNOLOGIA DA INFORMACAO ** ** ** ** ANALISTA: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ** ** PROGRAMADOR: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ** ** ** ** DATA: 99/99/9999 ** ** MODIFICACAO: 99/99/9999 ** ** ** ** FINALIDADE: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ** ** XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ** ** XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ** ** XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ** ** ** ****************************************************************** 90 PROGRAMAÇÃO COBOL O terceiro ponto considerado na documentação COBOL é a definição de linhas de separação para as seções padrão da linguagem. Normalmente, usa-se para separar divisões uma sequência de símbolos de traços (-). *----------------------------------------------------------------- CONFIGURATION SECTION. *----------------------------------------------------------------- O quarto ponto considerado na documentação COBOL é a definição de linhas em branco no código devem ser indica-das apenas com um caractere asterisco (*) sem nada escrito a frente. * O quinto ponto considerado é a possibilidade de inserir rótulos de informação no meio do código em quantas linhas forem necessárias com a finalidade de apresentar descrições das partes que sucedem este tipo de comentário. Nor-malmente, usa-se para separar divisões uma sequência de símbolos de traços (.). *................................................................. * Este trecho do programa executa importante acao de processamento * Para obtenção de informacoes para relatorio geral. *................................................................. O sexto ponto considerado na documentação COBOL é a definição da descrição de certa funcionalidade no programa, definição de seus dados (variáveis e constantes como itens elementares e de grupo). Usa-se o asterisco na sétima coluna e coloca-se a descrição desejada sobre o bloco de detalhes que se deseja referenciar na décima segunda colu-na. * DADOS DO CLIENTE Além da documentação do código baseando-se nos grupos de divisão, seção e parágrafo há também definições inter-nas que podem ser definidas a fim de facilitar diversas ações como a leitura do código, localização de itens e manuten-ções. O sétimo ponto a ser considerado é a definição dos nomes dos itens elementares e de grupo que podem ser criados em certas áreas do código. Até aqui foi indicado o uso desses elementos na WORKING-SOTORAGE SECTION. Neste sentido, há o costume de alguns programadores iniciarem alguns de seus itens com a qualificação (sigla de identifica-ção) WS de Working Storage para indicar que é um item definido exclusivamente na área WORKING-SOTORAGE SECTION e não em outro lugar. Esse tipo de documentação se assemelha a forma seguinte. DATA DIVISION. FILE SECTION. WORKING-STORAGE SECTION. 01 WS-CLIENTE. 05 WS-DADOS-PESSOAIS. 10 WS-NOME. 10 WS-SOBRENOME. 05 WS-DOCUMENTOS. 10 WS-CPF. 10 WS-RG. 05 WS-ENDERECO Observe as definições WS a frente dos nomes dos itens de grupo e dos itens elementares. Usando-se esta estratégia é possível usar nomes semelhantes desses elementos em outras partes do programa, desde que não se use o qualifica-dor WS. Há programadores que ao invés de fazerem referência a essas variáveis com o qualificador WS usam como substituto o qualificador AS, referência a Área de Salvamento. Este evento ou forma de definição não é uma regra, mais uma cultu-ra seguida por programadores COBOL no sentido de estabelecer uma maneira mais adequada de fazerreferência ao AÇÃO SEQUENCIAL 91 tipo de conteúdo que certa variável ou grupo de variáveis possui. A tabela 2.9 apresenta algumas sugestões para a definição de qualificadores de identificação. Tabela 2.9 – Qualificadores de variáveis e campos (sugestões de uso) Qualificador Descrição Exemplo WS- ou AS- Utilizado para representar variáveis usadas em ope- rações de entrada e saída de dados na área de sal- vamento ou na seção working storange. AS-ENTRA-NUMERO WS-ENTRA-NUMERO TB- Utilizado para representar o uso de variáveis associ- adas a tabelas. TB-DADOS-CLIENTE TB-ALUNOS-CURSO IX- Utilizado para representar variáveis que fazem refe- rências a indexação de tabelas. IX-DADOS-CLIENTE IX-ALUNOS-CURSO CH- Utilizado para representar chaves de variáveis lógi- cas (booleanas). CH-ACHEI-DADO CH-FLAG-LIGADO LK- Utilizado para representar o uso de variáveis decla- radas na seção linkage. LK-ENTRA-NUMERO LS- Utilizado para representar o uso de variáveis decla- radas na seção local estorange. LS-ENTRA-NUMERO AC- Utilizado para representar variáveis que utilizam valores numéricos na totalização como acumulado- res. AC-TOTAL-ITENS AC-SOMATORIO FS- Utilizado para representar estruturas de dados na definição de arquivos na file section. FS-CADFUN FS-CAD-CLIENTES F999- Utilizado para representar campos de registros. F001-NUM-MATRICULA F001-CLI-NOME S999- Utilizado para representar campos do modo de des- crição de classificação. S001-NUM-MATRICULA S001-CLI-NOME REL99- Utilizado para representar a indicação de relatórios de dados que podem existir em um programa. REL01-CABEÇALHO REL02-CABEÇALHO CB99- Utilizado para representar a indicação do cabeçalho de um relatório de dados. RELATÓRIO-CB01 RELATÓRIO-CB02 SS-TELA Utilizado para representar a indicação de telas na SCREEN SECTION. SS-TELA01 SS-TELA01-MENU Essa forma de definição é chamada de mnemônico e serve para auxiliar na identificação dos muitos elementos existen-tes em um programa de forma particularizada. Outras regras podem ser aplicadas para a definição de apoio a documentação de código. Neste tópico estão apresen- tadas as formas e estilos mais comuns. No sentido de demonstrar o uso da ação de documentação de código, em um sentido mais amplo, considere como exemplo um programa que apresente a data e a hora existentes no sistema. Ob-serve as partes colorizadas em vermelho e amarelo. Selecione e defina um projeto do programa vazio com o nome c02ex04.cob na pasta COBOL da pasta Documentos e escreva o código de programa seguinte. 92 PROGRAMAÇÃO COBOL ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- *================================================================= IDENTIFICATION DIVISION. *================================================================= * PROGRAM-ID. C02EX04 AS "Capitulo 2 – Exemplo 4". * ****************************************************************** ** ** ** AUGUSTO MANZANO – TECNOLOGIA DA INFORMACAO ** ** ** ** ANALISTA: JOSE AUGUSTO MANZANO ** ** PROGRAMADOR: JOSE AUGUSTO MANZANO ** ** ** ** DATA: 23/02/2021 ** ** MODIFICACAO: 15/04/2021 ** ** ** ** FINALIDADE: PROGRAMA DESTINADO A APRESENTAR A DATA E HORA ** ** RETORNA A PARTIR DO SISTEMA OPERACIONAL EM USO. ** ** ** ****************************************************************** * *================================================================= ENVIRONMENT DIVISION. *================================================================= * *----------------------------------------------------------------- CONFIGURATION SECTION. *----------------------------------------------------------------- * SOURCE-COMPUTER. IBM-PC COMPATIVEL. OBJECT-COMPUTER. IBM-PC COMPATIVEL. * *================================================================= DATA DIVISION. *================================================================= * *----------------------------------------------------------------- FILE SECTION. *----------------------------------------------------------------- * * DADOS OBTIDOS PARA A DATA E HORA DO SISTEMA WORKING-STORAGE SECTION. 01 WS-DATA-CORRENTE-SISTEMA. 05 WS-DATA-CORRENTE. 10 WS-DATA-CORRENTE-ANO PIC 9(04). 10 WS-DATA-CORRENTE-MES PIC 9(02). 10 WS-DATA-CORRENTE-DIA PIC 9(02). 05 WS-HORA-CORRENTE. 10 WS-HORA-CORRENTE-HRA PIC 9(02). 10 WS-HORA-CORRENTE-MIN PIC 9(02). 10 WS-HORA-CORRENTE-SEG PIC 9(02). 10 WS-HORA-CORRENTE-CEN PIC 9(02). * ------------------------------------------------------------------------ AÇÃO SEQUENCIAL 93 ------ LINHAS ------ 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- *================================================================= PROCEDURE DIVISION. *================================================================= * *................................................................. * Este trecho de codigo apresenta as informacoes de data e hora * obtidas a partir do sistema operacional. *................................................................. * PROG-PRINCIPAL-PARA. MOVE FUNCTION CURRENT-DATE TO WS-DATA-CORRENTE-SISTEMA. DISPLAY "Data e hora total .....: " WS-DATA-CORRENTE-SISTEMA. DISPLAY "Somente a data ........: " WS-DATA-CORRENTE. DISPLAY "Dia ...................: " WS-DATA-CORRENTE-DIA. DISPLAY "Mes ...................: " WS-DATA-CORRENTE-MES. DISPLAY "Ano ...................: " WS-DATA-CORRENTE-ANO. DISPLAY "Somente a hora ........: " WS-HORA-CORRENTE. DISPLAY "Horas .................: " WS-HORA-CORRENTE-HRA. DISPLAY "Minutos ...............: " WS-HORA-CORRENTE-MIN. DISPLAY "Segundos ..............: " WS-HORA-CORRENTE-SEG. DISPLAY "Centesimos ...........: " WS-HORA-CORRENTE-CEN. STOP RUN. ------------------------------------------------------------------------ Quando se define linhas de comentários em um programa o código escrito fica muito mais extenso do que se não tives- se essas linhas definidas. No entanto, essas informações são desconsideradas pelo compilador no momento da compi-lação, servindo tão somente como elementos de informação para nós humanos. Isso significa dizer que não importa se seu programa possui ou não linhas de comentários, o tamanho do programacompilado será o mesmo. O programa quando executado apresenta um conjunto de informações relacionadas a data e hora do sistema como sendo uma única sequencia numérica, que no programa foi desmembrada para apresentação das partes. Data e hora total .....: 2021041520472203 Somente a data ........: 20200415 Dia ...................: 15 Mes ...................: 04 Ano ...................: 2021 Somente a hora ........: 20472203 Horas .................: 20 Minutos ...............: 47 Segundos ..............: 22 Centesimos ...........: 03 Este programa apresenta um recurso novo. O uso da função CURRENT-DATE explica detalhadamente a seguir. Entre as linhas 42 e 52 é definida uma estrutura de dados para operação do programa com os dados de data e hora do sistema. Na linha 42 é definido o item de grupo WS-DATA-CORRENTE-SISTEMA que possui como itens de subgrupo WS-DATA-CORRENTE definido na linha 44 e WS-HORA-CORRENTE definido na linha 48. Entre as linhas 45 e 47 encontra-se os itens elementares que representam os componentes ANO, MES e DIA e entre as linhas 49 e 52 encontram-se os componentes HRA (hora), MIN, SEG e CEN. Esses componentes são os elementos de decomposição da data e hora do sistema obtidos a partir do uso da função CURRENT-DATE na linha 63. A função CURRENT-DATE opera seus valores dentro de certos limites. O componente ano usa a faixa de valores entre as datas de 01/01/1601 até 31/12/9999, o componente mês opera a faixa de valores entre 1 e 12, o componente dia 94 PROGRAMAÇÃO COBOL opera a faixa de valores entre 1 e 31, o componente hora opera a faixa de valores entre 0 e 23, o componente minuto opera a faixa de valores entre 0 e 59, o componente segundos opera a faixa de valores entre 0 e 59 e o componente centésimos opera a faixa de valores entre 0 e 99. Além do caractere asterisco para a definição de comentários em linhas de programas há a possibilidade de se fazer uso do caractere barra (/). O caractere barra é usado para duas finalidades conjuntas: gerar um salto de página na impres-são do código e apresentar no topo da nova página o comentário definido, sendo usado para separar o código do pro-grama em partes estruturais a critério da equipe de desenvolvimento. O comentário definido com a barra deverá estar expresso em apenas uma linha, observe o trecho a seguir com o uso do caractere barra demarcado em vermelho. -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. BARRATST. / Este trecho sera forçosamente impresso na proxima pagina ENVIRONMENT DIVISION. DATA DIVISION. PROCEDURE DIVISION. ------------------------------------------------------------------------ O salto de página será controlado pelo compilador quando solicitada a impressão do programa na impressora a partir do próprio compilador. A tentativa de usar qualquer editor de texto para a impressão do código não surtirá o efeito dese-jado. Mas cabe ressaltar que o compilador GnuCOBOL não possui este evento implementado. A área de codificação do programa no formulário (mesmo em um computador) fica limitada entre a oitava e septuagé-sima segunda colunas distribuídas nas áreas A (colunas de 8 a 11) para a definição das divisões, seções e parágrafos B (colunas de 12 a 72) para a definição das instruções de um programa. Ao todo tem-se apenas 64 colunas para a escrita do código, mas usa-se efetivamente 60 colunas. Com 60/64 colunas disponíveis para a escrita de código em algum momento ocorrerá a situação em que uma linha de instrução não poderá ser escrita em uma única linha. No caso da escrita de instruções comuns ou expressões algébri-cas basta parar a codificação na septuagésima segunda coluna, ou antes dela, e dar continuidade na linha de baixo a partir da décima segunda coluna sem nenhum problema, exceto a definição de uma linha de texto entre aspas inglesas. Quando se utiliza textos entre aspas inglesas tem-se a definição de uma literal (cadeia de caracteres - string) que pode- rá ter uma extensão de escrita maior que 60 colunas. Neste caso escreve-se o texto até a septuagésima coluna e sem fechar as aspas inglesas dá-se continuidade na linha de baixo, colocando-se na sétima coluna o caractere hífen e con-tinuando o texto a partir décima segunda coluna com a colocação de aspas inglesas antes da continuidade. Segue-se esta mesma regra até terminar a sequencia de caracteres que deverá ser finalizada com aspas inglesas. Observe um exemplo da necessidade de uso do caractere hífen para a apresentação de uma literal que excede as 72 colunas do formulário. Atente para as partes marcadas na cor vermelha. -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- PROCEDURE DIVISION. DISPLAY "Ignorar o COBOL e ' ignorar, entre outras coisas, a a - "rte de programar computadores - Joel Saade". ------------------------------------------------------------------------ Atente na indicação da terceira linha de código a colocação sutil do hífen na sétima coluna e a continuidade da defini- ção da sequencia de caracteres da literal anterior com a abertura e fechamento das aspas inglesas. Observe que a mensagem antes da continuidade é expressa apenas com abertura de aspas inglesas. AÇÃO SEQUENCIAL 95 Os programas produzidos nos demais capítulos desta obra não farão uso dos recursos de documentação por questão de espaço e para não deixar o texto extenso em demasiado. No entanto, isso que aqui é apresentado deve ser levado muito a sério profissionalmente. 96 PROGRAMAÇÃO COBOL Anotações ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ ________________________________________________________________________________________________ AÇÃO IN/CONDICIONAL 97 Este capítulo aborda o tema relacionado ao uso de ações condicionais e incondicionais com condição, deci- são, operadores relacionais, operadores lógicos, ações com detecção se sinal, reconhecimento de formato de caracteres, execução de laços condicional e incondicional, além de fornecer outros detalhes relacionados as operações de controle da linguagem COBOL. 3.1 PROCESSAMENTO LÓGICO Para que um programa de computador possa realizar154 4.4 - Estruturas de dados dinâmicas ................................................................................................................................ 156 4.5 - Hora de programar .................................................................................................................................................. 157 Capítulo 5 - Modularização 5.1 - Programação estruturada ........................................................................................................................................ 169 5.2 - Seções customizadas ................................................................................................................................................ 170 5.3 - Sub-rotinas (módulos) .............................................................................................................................................. 173 5.4 - Passagens de parâmetro .......................................................................................................................................... 176 5.4.1 - Chamada por referência ............................................................................................................................... 177 5.4.2 - Chamada por conteúdo................................................................................................................................. 178 5.4.3 - Uso integrado de conteúdo e referência ...................................................................................................... 180 5.5 - Livro de cópia ........................................................................................................................................................... 181 5.6 - Escopo e comportamento de variáveis ..................................................................................................................... 183 5.7 - Sub-rotinas recursivas .............................................................................................................................................. 185 5.8 - Ações complementares ............................................................................................................................................ 187 5.8.1 - Dados renomeados ....................................................................................................................................... 187 5.8.2 - Acesso externo .............................................................................................................................................. 198 5.8.3 - Funções definidas ......................................................................................................................................... 191 5.8.4 - Funções recursivas ........................................................................................................................................ 192 5.9 - Hora de programar .................................................................................................................................................. 201 Capítulo 6 - Manipulação de Cadeias de Caracteres 6.1 - Concatenação de textos ........................................................................................................................................... 213 6.2 - Decomposição de textos .......................................................................................................................................... 217 6.3 - Inspeção de textos ................................................................................................................................................... 218 6.4 - Funções para caracteres ........................................................................................................................................... 220 6.5 - Dígito verificador ..................................................................................................................................................... 223 6.6 - Hora de programar .................................................................................................................................................. 228 Capítulo 7 - Utilização de Arquivos 7.1 - Arquivo, registro e campo ........................................................................................................................................ 237 7.2 - Preparação para uso de arquivos ............................................................................................................................. 239 7.3 - Modos de acesso e formas de organização............................................................................................................... 242 7.4 - Ações operacionais ................................................................................................................................................... 245 7.5 - Controle de acesso ................................................................................................................................................... 249 7.5.1 - Detecção de erro no acesso a arquivos ......................................................................................................... 249 7.5.2 - Tratamento das mensagens de erro ............................................................................................................. 253 7.6 - Manipulação básica de arquivos .............................................................................................................................. 257 7.6.1 - Arquivo sequencial linear para acesso sequencial ....................................................................................... 258 7.6.2 - Arquivo sequencial de registro para acesso sequencial ............................................................................... 268 7.6.3 - Arquivo relativo para acesso sequencial ...................................................................................................... 274 7.6.4 - Arquivo indexado para acesso sequencial .................................................................................................... 284 7.6.5 - Arquivo relativo para acesso randômico ...................................................................................................... 305 7.6.6 - Arquivo indexado para acesso randômico .................................................................................................... 311 7.6.7 - Arquivo relativo para acesso dinâmico ......................................................................................................... 317 7.6.8 - Arquivo indexado para acesso dinâmico ...................................................................................................... 324 7.7 - Classificação, agrupamento e junção de registros ................................................................................................... 335 7.8 - Contagem de registros............................................................................................................................................. 346 7.9 - Melhoria no controle de acesso aos registros de um arquivo .................................................................................. 348 Capítulo 8 - Interfaces com o Usuário 8.1 - Utilização de relatórios ............................................................................................................................................ 351 8.1.1 - Relatório com arquivo de impressão em disco ............................................................................................. 352 8.1.2 - Relatório com arquivo de impressão em papel ............................................................................................ 360 8.1.3 - Introdução ao escritor de relatórios ............................................................................................................. 368 8.1.4ações de processamento lógico é necessário definir certas rela- ções condicionais. É a partir dessas relações que decisões poderão ser tomadas pela máquina. Uma condição do ponto de vista da ciência da computação é o estabelecimento de uma relação lógica entre elementos computáveis formados por variáveis, constantes e operadores relacionais na forma de operandos, que são as expressões lógicas. A tomada de decisão é pautada sobre o uso de uma condição ou de um conjunto de condições por meio de operadores lógicos. Condições são ações usadas principalmente e especialmente pelos comandos IF, EVALUATE e PERFORM, os quais efetuam no fluxo do programa algum tipo de desvio operacional. Essas condições podem ser usadas na realização de operações de desvio simples, composto e seletivo, além dos testes de classe e sinal, acrescentando-se as ações para a definição de nomes de condições. Para que uma condição possa ser estabelecida é necessário fazer uso de ferramentas especiais chamadas operadores relacionais. Na linguagem COBOL há dois modos de definição de condições com operadores relacionais: uso de símbo-los ou uso de descrições. A tabela 3.1 mostra os operadores relacionais nas formas simbólicas e descritivas usados nas definições do estabelecimento de condições. Tabela 2.1 – Símbolos de formatação dos tipos de dados Simbólico Descritivo Significado [IS] = [IS] EQUAL [EQUALS] TO Igual a [IS] > [IS] GREATER THAN Maior que [IS] = [IS] GREATER THAN OR EQUAL TO Maior ou igual a [IS] = | pode substituir = por IS EQUAL TO > | pode substituir > por IS GREATER THAN | pode substituir >= | pode substituir >= por IS GREATER THAN OR EQUAL TO | pode substituir NOT = | pode substituir NOT = por IS NOT EQUAL TO Uma decisão pode ser tomada com base em uma ou mais condições. Quando houver a necessidade de fazer uso de mais de uma condição será necessário usar um recurso que vincule duas ou mais condições por meio dos operadores lógicos de ligação AND (conjunção) e OR (disjunção) que podem ser contextualmente definidos a partir das relações. AND [ ... AND ] OR [ ... OR ] Se estiver em uso o operador lógico AND será realizada ação de conjunção que resultará na obtenção de um resultado verdadeiro quando todas as condições da expressão lógica forem verdadeiras. Se estiver em uso o operador lógico OR será realizada ação de disjunção que resultará na obtenção de um resultado verdadeiro quando uma ou mais condições da expressão lógica forem verdadeiras. No uso de expressões lógicas contendo em conjunto os operadores lógicos AND e OR o operador AND terá sempre maior precedência sobre o operador OR. Caso deseje alterar o nível de precedência use parênteses na parte de menor precedência. Assim sendo, considere as seguintes expressões lógicas. 1 - OR AND 2 - ( OR ) AND Na expressão 1 a resposta lógica final será obtida a partir da avaliação de AND para em seguida avaliar o resultado obtido com o restante da expressão em OR com relação a . Na expressão 2 a resposta lógica final será obtida a partir da avaliação de OR para em seguida avaliar o resultado obtido com o restante da expressão em AND com relação a . Considerando como base de avaliação apenas duas condições a tabela 2.2 apresenta os resultados lógicos possíveis de serem obtidos com o uso dos operadores lógicos AND e OR. Tabela 2.2 – Operadores lógicos AND e OR Condição 1 Condição 2 Resultado AND Resultado OR V V V V V F F V F V F V F F F F A definição de relações condicionais em COBOL vai mais à frente se comparada com outras linguagens de programa-ção, pois apresentam recursos operacionais que em outras linguagens para serem usados necessitam de funções in- trínsecas, destacando-se neste caso as ações de verificação de classe e de sinal. AÇÃO IN/CONDICIONAL 99 O teste de classe permite validar se o operando em uso possui um valor numérico ou alfabético (maiúsculo, minúsculo ou ambos). Essa condição é, principalmente, útil para validar as entradas de dados realizadas por um usuário. Veja os exemplos contextualizados possíveis de aplicação para testes de classe. IS [NOT] NUMERIC IS [NOT] ALPHABETIC IS [NOT] ALPHABETIC-LOWER IS [NOT] ALPHABETIC-UPPER O teste de sinal permite determinar se o valor numérico de um operando é maior que zero quando positivo, menor que zero quando for negativo ou se o valor é igual a zero, quando for zero. Veja os exemplos contextualizados possíveis de aplicação para testes de sinal. IS [NOT] POSITIVE / NEGATIVE / ZERO Qualquer relação condicional poderá ser negada com o uso do operador lógico de negação NOT. Neste caso se a con- dição tiver resultado verdadeiro será considerado este como falso e vice-versa quando a condição for falsa. Para a devida verificação condicional é importante que os elementos avaliados na relação lógica sejam do mesmo tipo. Nunca estabeleça relações condicionais com tipos de dados diferentes. 3.2 DESVIOS CONDICIONAIS Desvios condicionais estão associados ao uso de condições definidas em um programa de computador. Uma decisão (expressão condicional) a ser tomada pode ser verdadeira ou falsa dependendo da condição estabelecida. Se a condi-ção for verdadeira determinada ação será executada (ocorrerá um desvio do fluxo do programa); se falsa poderá de-terminar outra ação (um desvio de fluxo) a ser feita ou não executar nenhuma ação (mantendo o programa no mesmo fluxo de execução). Um desvio condicional pode ser simples, composto ou seletivo. 3.2.1 Desvio simples Um desvio condicional simples direciona a execução do fluxo de programa para certo ponto do código toda vez que a condição for verdadeira, após a conclusão do desvio o programa retorna à linha de fluxo que estava em operação antes do desvio. Se a condição for falsa nada acontecerá, o programa mantém seu fluxo sem desviar e segue sua execução. Um desvio condicional simples é definido com a estrutura sintática: IF [THEN] Ação executada se expressão condicional for verdadeira [END-IF]. As cláusulas THEN e END-IF foram inseridas na linguagem a partir da publicação do padrão COBOL-85, sendo opcio-nais em seu uso. Sua inclusão se deu ao fato de aproximar a estrutura sintática da linguagem as regras de conspecção do modelo estruturado do paradigma imperativo. Nesta obra, as decisões serão escritas com a cláusula END-IF, tendo a cláusula THEN omitida, no entanto use-a se preferir. Observe que após a definição do comando END-IF usa-se um ponto de finalização para encerrar todo o conjunto condi- cional. Dentro do escopo do bloco delimitado entre IF e END-IF não use ponto de finalização em nenhuma instrução, observe que o comando IF abre umafrase de instrução que é encerrada com um ponto de finalização após o comando END-IF. Caso END-IF seja omitido (seguindo o padrão COBOL-74) o ponto de finalização deve ser colocado obrigatori-amente na última linha de operação do bloco condicional. O padrão estético de endentação para o conteúdo do bloco dentro dos comandos IF/THEN e END-IF é normalmente de quatro posições. Nesta obra a formatação será de três posições. 100 PROGRAMAÇÃO COBOL Considere, como exemplo, a definição de uma condição que verifique se a idade informada do usuário é maior ou igual a 18, sendo a condição verdadeira apresente a mensagem "Maior de idade". Caso a idade não esteja dentro da condi-ção esperada nada deverá ser feito. DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-IDADE PIC 9(3). PROCEDURE DIVISION. DISPLAY "Informe sua idade: " WITH NO ADVANCING. ACCEPT WS-IDADE. IF WS-IDADE >= 18 DISPLAY "Maior de idade" END-IF. Note que a mensagem somente é apresentada quando o valor da variável WS-IDADE for maior ou igual a 18. Veja na sequencia o trecho da PROCEDURE DIVISION usando a forma descritiva de uso de operador relacional expresso de forma completa com o uso do verbo IS. PROCEDURE DIVISION. DISPLAY "Informe sua idade: " WITH NO ADVANCING. ACCEPT WS-IDADE. IF WS-IDADE IS GREATER THAN OR EQUAL TO 18 DISPLAY "Maior de idade" END-IF. Atente que tanto faz fazer uso da forma simbólica ou descritiva. Aqui tem-se a mesma questão discutida em relação ao uso dos operadores aritméticos, valendo as mesmas observações. Os próximos exemplos usam a forma simbólica. Dentro do bloco IF/THEN e END-IF poderá existir diversas outras operações de entrada, processamento matemático, saída, bem como a definição de outras decisões. Neste caso, passa-se a ter o que se chamada encadeamento de deci-sões indicadas com a estrutura sintática seguinte. Observe os pontos colorizados, veja que o bloco condicional verde está definido dentro (encadeado) do escopo do bloco condicional vermelho. IF Ação executada se expressão condicional 1 for verdadeira IF Ação executada se expressão condicional 1 E 2 forem verdadeiras END-IF END-IF. Atente a um detalhe importante, quando se usa encadeamento de tomadas de decisão apenas o final da última decisão terá o uso de ponto de finalização. Há ainda a possibilidade de se trabalhar com sequencias de tomadas de decisão uma após a outra como demonstrado em seguida. IF Ação executada se expressão condicional 1 for verdadeira END-IF. IF Ação executada se expressão condicional 2 for verdadeira END-IF. Para o caso de uso de tomadas de decisões sequencias cada tomada de decisão terá o registro de seu ponto de finali-zação. As estruturas sequenciais e aninhadas poderão ser utilizadas de diversas formas, mescladas entre si. Não há limites para o uso integrado das ações de tomada de decisão com elas mesmas. AÇÃO IN/CONDICIONAL 101 3.2.2 Desvio composto Um desvio condicional composto direciona a execução do fluxo de programa para certo ponto do código toda vez que a condição for verdadeira. Se a condição for falsa a execução do programa será direcionada a outro ponto do código. Em ambos os casos após concluir um dos desvios a execução do programa volta à linha de fluxo que estava em operação antes do desvio ocorrer e segue sua execução. Um desvio condicional composto é definido com a estrutura sintática: IF [THEN] Ação executada se expressão condicional for verdadeira ELSE Ação executada se expressão condicional for falsa [END-IF]. Considere, como exemplo, a definição de uma condição que verifique se a idade do usuário informada é maior ou igual a 18, sendo a condição verdadeira apresente a mensagem "Maior de idade". Caso a condição seja falsa deve ser apresentada a mensagem "Menor de idade". DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-IDADE PIC 9(3). PROCEDURE DIVISION. DISPLAY "Informe sua idade: " WITH NO ADVANCING. ACCEPT WS-IDADE. IF WS-IDADE >= 18 DISPLAY "Maior de idade" ELSE DISPLAY "Menor de idade" END-IF. Assim como o desvio condicional simples, o desvio condicional composto pode operar com encadeamentos e sequên- cias de decisões tanto no escopo do bloco IF/THEN e ELSE como no bloco ELSE e END-IF. Não há limites, o uso de-penderá da necessidade existente. É possível combinar decisões simples com decisões compostas e vice-versa. A linguagem COBOL possui um recurso que é existente em poucas linguagens de programação: a capacidade de prio-rizar tomada de decisão simples sobre o uso de condição falsa. A maior parte das linguagens de programação apenas prioriza ações em tomada de decisão simples baseadas em condições verdadeiras. No entanto, para esta ação é ne- cessário o uso de estrutura condicional composta auxiliada pelo comando CONTINUE ou instrução NEXT SENTENCE a partir da estrutura sintática: IF [THEN] CONTINUE / NEXT SENTENCE ELSE Ação executada se expressão condicional for falsa [END-IF]. Considere, como exemplo, a definição de uma condição que verifique se a idade informada do usuário é maior ou igual a 18, sendo não faça absolutamente nada. Caso a idade não esteja dentro da condição esperada apresente a mensa-gem "Menor de idade". DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-IDADE PIC 9(3). PROCEDURE DIVISION. DISPLAY "Informe sua idade: " WITH NO ADVANCING. 102 PROGRAMAÇÃO COBOL ACCEPT WS-IDADE. IF WS-IDADE >= 18 CONTINUE ELSE DISPLAY "Maior de idade" END-IF. Observe que se a idade informada for maior ou igual a 18 ocorrerá a execução do bloco definido ente IF e ELSE que direcionará o fluxo para a execução do comando CONTINUE que “pegará” este fluxo e o direcionará para fora do bloco de tomada de decisão, após END-IF, abandonando-o. Sendo a condição falsa é processado o que se encontra definido no bloco ELSE e END-IF. O comando CONTINUE pode ser plenamente substituído pela instrução NEXT SENTENCE. No entanto, cabe algumas observações a este respeito. A instrução NEXT SENTENCE é típica para uso no COBOL-74, tendo sido retirada do padrão COBOL-85 e retornada a partir do padrão COBOL-2002 e considerada no COBOL-2014. No entanto, o compila-dor GnuCOBOL considerada a instrução NEXT SENTENCE arcaica, mantende-a por questões de compatibilidade, e por esta razão incentiva fortemente seu desuso. Mas, poderá haver algum compilador mais recente, dentro das regras de padrões atualizados, não aceitar o uso do comando CONTINUE em detrimento a instrução NEXT SENTENCE. 3.2.3 Desvio seletivo Ao trabalhar com grande quantidade de desvios encadeados ou sequenciais, pode-se deixar o programa com uma estrutura difícil de ser interpretada e escrita. Considere, como exemplo uma estrutura sequencial de quatro opções em que dependendo da opção selecionada uma determinada ação deve ser realizada. A estrutura somente pode aceitar valores dento do limite das opções existentes, ou seja, opção 1, opção 2, opção 3 e opção 4. Caso um valor diferente de opção seja fornecido o programa deve indicar erro de ação. Observe o esqueleto seguinte para esta situação se-guinte. IF AND IF Ação 1 END-IF IF Ação 2 END-IF IF Ação 3 END-IF IF Ação 4 END-IF ELSE END-IF. Veja o trecho proposto implementado na linguagem na forma de definição de entrada de um valor numérico e apresen-tação de mensagens indicando qual opção foi escolhida e mensagem de erro informando que a entrada foi incorreta. DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-OPCAO PIC 9. PROCEDURE DIVISION. DISPLAY"Informe opcao: " WITH NO ADVANCING. ACCEPT WS-OPCAO. IF WS-OPCAO >= 1 AND WS-OPCAO WHEN 1 Ação 1 WHEN 2 Ação 2 WHEN 3 Ação 3 WHEN 4 Ação 4 WHEN OTHER END-EVALUATE. Não é só a simplificação de escrita que os comandos EVALUATE e END-EVALUATE se diferenciam dos comandos IF e END-IF. A diferença principal está em sua funcionalidade. O uso dos comandos IF e END-IF dispostos de forma sequencial são em média mais lentos que a execução dos comandos EVALUATE e END-EVALUATE. Isto ocorre, pois nos IFs cada referência do bloco é verificada particularmente, mesmo que a referência anterior tenha sido realizada. O efeito no uso de EVALUATE é diferente, pois sendo uma certa condi- ção satisfeita o fluxo do programa é desviado para fora do bloco, evitando a verificação desnecessária das condições que estão a frente da condição satisfeita. Tomando por base a mesma situação apresentada anteriormente observe detalhadamente a forma de definição dos comandos EVALUATE e END-EVALUATE e os compare com os comandos sequenciais IF e END-IF. DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-OPCAO PIC 9. PROCEDURE DIVISION. DISPLAY "Informe opcao: " WITH NO ADVANCING. ACCEPT WS-OPCAO. EVALUATE WS-OPCAO WHEN 1 DISPLAY "Escolheu opcao '1'" WHEN 2 DISPLAY "Escolheu opcao '2'" 104 PROGRAMAÇÃO COBOL WHEN 3 DISPLAY "Escolheu opcao '3'" WHEN 4 DISPLAY "Escolheu opcao '4'" WHEN OTHER DISPLAY "Entrada incorreta" END-EVALUATE. Apesar dos comandos EVALUATE e END-EVALUATE serem superiores a funcionalidade dos comandos IF e END-IF, há uma fragilidade que deve ser considerada com muita atenção. Este comando só pode ser usado para condições baseadas em igualdade. Não há possibilidade de usá-la para situações que encovam os demais operes relacionais. 3.3 AÇÕES CONDICIONAIS Além das definições de tratamento de tomadas de decisão apresentadas e comum de serem encontradas em diversas linguagens de programação, COBOL possui alguns recursos a mais que possibilitam a realização de algumas opera-ções mais seguras como detecção de dado fornecido, validação numérica e análise condicional descritos neste tópico. 3.3.1 Teste de classe O teste de classe é uma ação que permite verificar o estado de um dado em relação ao tipo definido na sua qualificação na seção WORKING-STORAGE da divisão DATA. Desta forma, pode-se detectar o estado da entrada do usuário evi-tando-se que um valor incorreto, segundo seu tipo, seja fornecido e cause problemas ao programa. São quatro as pos-sibilidades de validação sendo: numérica, alfabética (letras maiúsculas e minúsculas), alfabética maiúscula e alfabética minúscula, respectivamente pelos operadores NUMERIC, ALPHABETIC-UPPER/LOWER e ALPHABETIC. Como exemplo considere um trecho de programa para detecção de entrada de dados alfabéticos maiúsculos e/ou mi-núsculos que apresente a mensagem "Entrada OK.". Qualquer valor quer não seja um caractere alfabético maiúsculo ou minúsculo deve apresentar a mensagem "Erro na entrada.". São valores alfabéticos as letras e o espaço em bran-co. Qualquer outro caractere gerado pelo teclado não é aceito como caractere válido para este teste de classe. DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-VALOR PIC X(10). PROCEDURE DIVISION. DISPLAY "Entre sequencia de caracteres: " WITH NO ADVANCING. ACCEPT WS-VALOR. IF WS-VALOR IS ALPHABETIC DISPLAY "Entrada OK." ELSE DISPLAY "Erro na entrada." END-IF. Para conseguir ter acesso aos caracteres que não são alfabéticos basta usar a condição IS NOT ALPHABETIC rever-tendo o teste. 3.3.2 Teste de sinal O teste de sinal efetua a comparação de certo valor numérico a zero e determina se o valor é positivo (quando for maior que zero), negativo (quando for menor que zero) ou igual a zero, quando efetivamente for zero. Este teste também pode ser processado com o uso dos operadores relacionais. É possível com este teste verificar as condições POSITIVE, NEGATIVE e ZERO. AÇÃO IN/CONDICIONAL 105 Como exemplo considere um trecho de programa que ao receber uma entrada numérico informe o estado do número como sendo positivo, negativo ou zero. DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-VALOR PIC S9(5)V99. PROCEDURE DIVISION. DISPLAY "Entre valor numerico: " WITH NO ADVANCING. ACCEPT WS-VALOR. IF WS-VALOR IS POSITIVE DISPLAY "Valor positivo." END-IF. IF WS-VALOR IS NEGATIVE DISPLAY "Valor negativo." END-IF. IF WS-VALOR IS ZERO DISPLAY "Valor zero." END-IF. O uso das condições de teste de sinal pode ser negado com a utilização do operador lógico NOT. No entanto é funda-mental prestar atenção e um detalhe: dizer IS NOT NEGATIVE não é o mesmo que dizer IS POSITIVE. Um valor positi-vo é qualquer valor acima de zero, dizer não negativo significa incluir o valor zero na análise. A menos que se deseje expressar valores positivos e maiores que zero, usar IS NOT NEGATIVE poderá ser um grande problema. 3.3.3 Nomes condicionais O nome condicional é a definição de um nome de variável associado ao valor que esta variável possa ter. A definição do nome condicional é feita com o código de nível 88 na DATA DIVISION semelhantemente a forma de definição de itens elementares em itens de grupo. O nível 88 não cria um item elementar em um item de grupo, cria um nome condi-cional dentro de um item de grupo. Os nomes condicionais são usados com qualquer comando que use condições. Quando um nome condicional é declarado com código de nível 88 dentro de um item de grupo o que se faz é dizer que cada item elementar do grupo se refere a um ou mais valores. Nomes condicionais não usam o comando PICTURE para definição de máscaras, mas usam o comando VALUE. A máscara é definida apenas no item de grupo. O formato geral de definição de um campo condicional na forma de item elementar segue a estrutura sintática: 88 VALUES Imagine a definição de um item de grupo chamado CH-FORMACAO (para formação escolar), com os nomes condicio-nais CH-FORM-BASICO com valor 1, CH-FORM-MEDIO com valor 2 e CH-FORM-SUPERIOR com valor 3, além da lista de valores destinada a auxiliar a validação da entrada CH-FORM-VALIDADE com os valores 1, 2 e 3. 01 CH-FORMACAO PIC 9. 88 CH-FORM-VALIDADE VALUE 1 2 3. 88 CH-FORM-BASICO VALUE 1. 88 CH-FORM-MEDIO VALUE 2. 88 CH-FORM-SUPERIOR VALUE 3. Veja que os nomes condicionais indicam os estados de valores 1, 2 ou 3 para cada grau escolar. Neste sentido, pode-se usar as referências CH-FORM-BASICO, CH-FORM-MEDIO e CH-FORM-SUPERIOR para indicar os valores 1, 2 e 3, como se fossem as definições de constantes. O nome condicional CH-FORM-VALIDADE está sendo definido para auxiliar e garantir que não ocorra nenhum erro se algum valor fora da faixa for informado, veja que é possível criar no- mes condicionais com mais de um valor e neste sentido pode-se usar, para facilitar, a cláusula THRU para definir faixasde valores a um nome condicional como 88 CH-FORM-VALIDADE VALUES 1 THRU 3. 106 PROGRAMAÇÃO COBOL Quando o valor do item de grupo CH-FORMACAO for igual a 1 ter-se-á a condição CH-FORM-BASICO, se igual a 2 ter-se-á a condição CH-FORM-MEDIO e assim por diante. O nome condicional CH-FORM-VALIDADE opera com um de três valores possíveis. O uso de nomes condicionais proporciona a utilização de uma estrutura lógica customizada e suavizada, pois é possível facilmente criar uma condição simplificada de validação. Por exemplo, definir a checagem se os valores permitidos 1, 2 ou 3 são os usados, basta escrever: IF CH-FORM-VALIDADE De outra forma, mais tradicional, seria escrever algo como: IF CH-FORMACAO = 1 OR CH-FORMACAO = 2 OR CH-FORMACAO = 3 A partir do exemplo estruturado de nome condicional considere o trecho de código a seguir que solicitada a entrada de um nível de formação e a partir do uso dos nomes condicionais apresenta a informação correspondente. DATA DIVISION. WORKING-STORAGE SECTION. 01 CH-FORMACAO PIC 9. 88 CH-FORM-VALIDADE VALUE 1 2 3. 88 CH-FORM-BASICO VALUE 1. 88 CH-FORM-MEDIO VALUE 2. 88 CH-FORM-SUPERIOR VALUE 3. PROCEDURE DIVISION. DISPLAY "1 - Ensino basico" DISPLAY "2 - Ensino medio" DISPLAY "3 - Ensino superior" DISPLAY X"0D". DISPLAY "Qual sua formacao: " WITH NO ADVANCING. ACCEPT CH-FORMACAO. IF CH-FORM-VALIDADE IF CH-FORM-BASICO DISPLAY "Formacao no ensino basico" END-IF IF CH-FORM-MEDIO DISPLAY "Formacao no ensino medio" END-IF IF CH-FORM-SUPERIOR DISPLAY "Formacao no ensino superior" END-IF END-IF. No exemplo faz-se a solicitação de um valor armazenando-o no item de grupo CH-FORMACAO. Em seguida faz-se a validação do valor fornecido junto a nome condicional CH-FORM-VALIDADE para determinar se o valor fornecido está dentro da faixa de valores a serem aceitos, sendo o valor verdadeiro o bloco da tomada de decisão é processado. Se algum valor fora da faixa for informado a tomada de decisão não processa sei bloco interno. Dentro do bloco de validação do valor informado é realizada a verificação de cada referência existente, dependendo do valor indicado a mensagem correspondente a formação é apresentada. 3.4 DESVIOS INCONDICIONAIS Desvios condicionais são controlados por meio de operadores relacionais e lógicos; ações condicionais usam para os testes de classe e de sinal o verbo IS que pode ser usado com os operadores relacionais, além dos campos condicio- nais que são usados em situações lógicas de comparação com igualdade. Em contrapartida desvios incondicionais AÇÃO IN/CONDICIONAL 107 podem ser executados sem o controle de certa condição simplesmente seguindo o fluxo a eles indicados ou se utilizar de algum critério condicional para controla-lo um pouco melhor. Este é um momento crítico neste estudo, pois entra em um tema considerado obscuro por abordar um comando exis- tente em diversas linguagens que é renegado, injuriado, deprecado e malfadado. No entanto, linguagens de programa-ção modernas mantêm em seu kernel a existência deste comando: o famigerado GO TO, por qual motivo? Muitos dizem para não o usar sob pena de assumir grande desgraça de proporção catastrófica, como se cometesse um crime capital. Na verdade, o problema é o mau uso que muitos programadores fazem deste comando por não compre-enderem quando e onde podem fazê-lo. É mais fácil proibir e achincalhar do que efetivamente ensinar. Há duas formas de se utilizar GO TO em seus programas: a forma certa e a forma errada. Se a forma usada não é a certa, então é a errada não importando seus motivos. Se o comando existe na linguagem, este poderá ser usado. Não de qualquer forma, mas sob rígidos conceitos de aplicação. O comando GO TO transfere o fluxo de ação de um programa de um ponto da PROCEDURE DIVISION a outro por meio de parágrafo ou seção de ligação. Obviamente em programas estruturados este comando deve ser evitado ao máximo. Veja que a orientação de se evitar seu uso ao máximo significa entender para não o usar inadvertidamente, apenas usá-lo em situa- ções raras. A transferência realizada é direcionada para a primeira instrução no parágrafo ou seção identificada em certo procedimento (tema que será visto mais adiante). São duas as formas previstas de GO TO no compilador GnuCOBOL: in- condicional e condicional. A sintaxe do comando para ação incondicional segue a estrutura sintática seguinte, sendo a forma mais popular: GO [TO] Onde, referência é a indicação do nome de um procedimento nomeado ou seção existente na PROCEDURE DIVISION em que o comando GO TO faça referência para acesso. A palavra TO do comando é opcional e poderá ser omitido, o que é um pouco raro de acontecer uma vez que diminui a legibilidade do código. Mantenha muita atenção no uso do comando GO TO incondicional, pois quando este comando não é a última instrução, as instruções que o seguem não são executadas. A sintaxe do comando para ação condicional segue a estrutura sintática: GO [TO] DEPENDING ON Onde, referências é a indicação de um ou mais nomes de procedimentos nomeados ou seções existentes na PROCEDURE DIVISION, até 255 referências onde estejam os comandos GO TO. O identificador de DEPENDING ON é a definição de um item de dado numérico inteiro, que faz associação direta ao item indicado em referências. Se o valor do parâmetro identificador for 1 o controle é transferido para a primeira instrução do primeiro procedimento indicado em referências, se for 2 o controle é transferido para a primeira instrução do segundo procedimento e assim por diante não excedendo 255. Neste momento será usado apenas o modo incondicional do comando GO TO, ficando o modo condicional a ser visto mais adiante nesta obra. No tópico anterior foi indicado o uso de nome condicional e sugerido um exemplo. No exemplo apresentado foi utilizado uma sequência de decisões sequenciais para a realização de cada ação encadeada a uma decisão que efetua a vali-dação para a entrada ou não na estrutura sequencial de decisões. Veja que este modelo é apresentado após a indica-ção da estrutura dos comandos EVALUATE e END-EVALUATE, que teoricamente poderia ter sido usada no exemplo, mas não foi pelo motivo de que os comandos EVALUATE e END-EVALUATE não aceitam o uso de nome condicional. Já é sabido que as ações de decisão executadas por IFs sequenciais são mais lentas que a ação executada pela estru- tura EVALUATE e END-EVALUATE, mas não podendo usá-la torna-se propício o uso do comando GO TO para que se busque uma performance semelhante a EVALUATE e END-EVALUATE mesmo usando IFs sequenciais. Mantendo exemplo semelhante ao do tópico anterior observe como ilustração os detalhes indicados para uso do comando GO TO em estilo incondicional simulando a ação dos comandos EVALUATE e END-EVALUATE. Atente para o uso da variável de entrada de dados WS-ENTRADA. DATA DIVISION. WORKING-STORAGE SECTION. 108 PROGRAMAÇÃO COBOL 01 WS-FORMACAO PIC 9. 88 WS-FORM-VALIDADE VALUE 1 2 3. 88 WS-FORM-BASICO VALUE 1. 88 WS-FORM-MEDIO VALUE 2. 88 WS-FORM-SUPERIOR VALUE 3. 77 WS-ESCOLAR PIC 9. PROCEDURE DIVISION. DISPLAY "1 - Ensino basico" DISPLAY "2 - Ensino medio" DISPLAY "3 - Ensino superior" DISPLAY X"0D". DISPLAY "Qual sua formacao: " WITH NO ADVANCING. ACCEPT WS-ESCOLAR. IF WS-ESCOLAR >= 1 AND WS-ESCOLARensino medio". GO TO SAIDA-PARA. MENS3-PARA. DISPLAY "Formacao no ensino superior". GO TO SAIDA-PARA. SAIDA-PARA. STOP RUN. Observe que o uso do comando GO TO é mais confuso que outros comandos da linguagem. É exatamente por este motivo que o comando deve ser ao máximo evitado. Seu uso desnecessário torna o código de difícil manutenção e pode gerar o que se chama de “código espaguete”, ou seja, um código com um emaranhado de comandos que nin-guém consegue entender onde começa e termina. Somente use este recurso, como última alternativa, caso não haja na linguagem uma maneira de realizar ação desejada de outra forma. Para simular a ação dos comandos EVALUATE e END-EVALUATE é definido no trecho final de código antes de STOP RUN um ponto de saída com o parágrafo SAIDA-PARA. Note que MES1-PARA, MENS2-PARA e MENS3-PARA após executarem suas ações direcionam o fluxo do programa para o parágrafo SAIDA-PARA a partir do uso da instrução GO TO SAIDA-PARA. Isso permite que após executar a ação de cada parágrafo de mensagem o fluxo do programa seja direcionado para um ponto de convergência, que neste caso é o encerramento do programa. Outro detalhe, a ser observado, no código é o direcionamento realizado dentro da estrutura de tomada de decisão para cada um dos parágrafos contendo as mensagens a serem apresentadas. Veja que para fazer uso adequado do coman-do GO TO incondicional de forma mais eficiente é necessário o apoio de instruções IFs. O trecho anterior mostra a entrada do usuário na variável WS-ESCOLAR que é verificada para se saber se possui o valor fornecido de forma válida. Sendo válido executa suas operações e não sendo válido o fluxo do programa é direci-onada para o parágrafo SAIDA-PARA. Veja que, sendo a condição verdadeira a primeira ação dentro do bloco validado AÇÃO IN/CONDICIONAL 109 realizada é a transferência do conteúdo da variável WS-ESCOLAR para o nome condicional WS-FORMACAO por meio da instrução MOVE WS-ESCOLAR TO WS-FORMACAO. Anteriormente o comando MOVE foi mostrado como alternativa de atribuição de valor em substituição ao uso de atribui- ções em expressões algébricas. A ação de atribuição só é permitida em variáveis numéricas devido ao uso do comando COMPUTE. No caso indicado isto não é possível, e por esta razão usa-se o comando MOVE. O comando GO TO não deve ser utilizado por programadores inexperientes, pois exige alto grau de abstração sobre a lógica de programação e grande disciplina para conseguir fazer com que o código fique o mais legível possível, o que é uma tarefa bastante difícil como pode ser observado no trecho de código exemplificado. 3.5 LAÇOS PARA REPETIÇÕES Os laços para repetições (também conhecidos como loopings, malhas ou ciclos) possibilitam executar determinado trecho de código de um programa várias vezes. A ideia geral do conceito de laço decorre do fato de um laço ser um nó corredio facilmente desatável a partir de uma ou mais alças. Dessa forma, é possível definir quantidades de repetições, com laços determinísticos (quando se sabe o número de vezes que o laço deve ser executado: iterativo) e laços inde-terminados (quando não se sabe quantas vezes o laço deve ser executado, dependendo de uma resposta positiva do usuário para fazê-lo: interativos). A execução de laços em COBOL é realizada com o eclético comando PERFORM finalizado com END-PERFORM. Este comando é usado, não só, para a execução de sequências de instruções ou seções por certo número de vezes, mas pode também ser usado para desviar a execução do fluxo de programa para determinado parágrafo ou seção, executar as instruções desses locais e ao final retornar para a primeira instrução após sua chamada. Neste momento, apenas a aplicação relacionada a execução de laços será tratada. Laços de repetição PERFORM são estruturas que repetem um conjunto de instruções certo número de vezes. A quanti-dade de repetições poderá ser conhecida ou desconhecida. Os laços cuja a quantidade de vezes é conhecida são chamados de laços iterativos, mas os laços em que não se sabe de antemão quantas vezes ocorrerá a execução são chamados de laços interativos. A estrutura geral de laços em COBOL é escrita de acordo com a forma sintática simplifi-cada seguinte: PERFORM [[] [VARYING FROM BY ] UNTIL [NOT] ] | [ TIMES] END-PERFORM. Onde, local é uma definição opcional de onde o comando deverá atuar (este efeito não será tratado neste capítulo), o trecho VARYING FROM BY é opcional e destinado a execução de laços iterativos. O parâmetro con- dição é obrigatório tanto para laços interativos como iterativos e determina a condição de encerramento de um laço. O trecho VARYING FROM BY é usado para determinar uma variável (var) que será usada para ar-mazenar de forma acumulada a contagem de valores iniciados a partir (FROM) do valor inicial , variando (VARYING) a contagem com passos do valor de (BY) até chegar ao final da contagem verificada com a condição (cond) estabelecida em UNTIL (até que), podendo a condição ser usada fora do trecho VARYING FROM BY . O laço PERFORM pode fazer uso apenas do trecho TIMES, onde “n” determina o número de vezes (TIMES) que as instruções internas ao laço serão executadas. 3.5.1 Ciclo interativo O estilo padrão de laço com ciclo interativo é usado em COBOL com os comandos FERFORM e UNTIL que se caracte-rizam por ser do tipo pré-teste com fluxo de ação falso, pois somente é encerrado quando a condição se torna verdadei- ra. Esta forma de laço pode ser usada para a definição de laços interativos e iterativos. No sentido de exemplificar um trecho de código que apresente no monitor de vídeo os valores de 1 a 5 na forma condi-cional iterativa observe os detalhes seguintes: 110 PROGRAMAÇÃO COBOL DATA DIVISION. WORKING-STORAGE SECTION. 77 AC-CONT PIC 9. PROCEDURE DIVISION. COMPUTE AC-CONT = 1. PERFORM UNTIL AC-CONT > 5 DISPLAY AC-CONT COMPUTE AC-CONT = AC-CONT + 1 END-PERFORM. Nesta forma de laço faz-se a definição de uma variável que será usada na ação de contagem, neste caso AC-CONT. A variável contadora deve ser inicializada (COMPUTE AC-CONT = 1) para assegurar ação adequada do laço e seu limite de contagem verificado por UNTIL AC-CONT > 5. Veja que a contagem será realizada até que a variável AC-CONT atinja um valor maior que o limite, neste caso 5. A cada verificação falsa o bloco entre FERFORM e END-PERFORM é executado quando o valor da variável contadora é apresentado com DISPLAY AC-CONT e o valor da variável que controla a operação é acrescida com o valor de in-cremento, neste caso COMPUTE AC-CONT = AC-CONT + 1. Caso necessite produzir um laço condicional pré-teste com fluxo verdadeiro use o operador lógico NOT. Para o código anterior bastaria alterar o trecho UNTIL AC-CONT > 5 para UNTIL NOT AC-CONTa apresentação da pergunta solicitando se o usuário deseja ou não continuar. Esta é uma situação em que não se sabe quantas vezes o usuário desejará executar o programa, sendo um exemplo de um laço indeterminado de vezes. Os laços pré-teste possuem como característica validarem a condição antes da execução das instruções internas ao seu bloco, ou seja, BEFORE. Isso é muito útil até que se tenha a necessidade de ter que entrar primeiro no laço para depois verificar a validade da condição. Neste sentido, basta solicitar para que a ação do comando PERFORM seja executada com o uso do trecho WITH TEST AFTER, em que o termo AFTER indica para validar a condição depois de passar pelo bloco. Observe o exemplo seguinte. DATA DIVISION. WORKING-STORAGE SECTION. 77 AC-CONT PIC 9. AÇÃO IN/CONDICIONAL 111 PROCEDURE DIVISION. COMPUTE AC-CONT = 1. PERFORM WITH TEST AFTER UNTIL AC-CONT > 5 DISPLAY AC-CONT COMPUTE AC-CONT = AC-CONT + 1 END-PERFORM. A solicitação WITH TEST AFTER faz com que o comando PERFORM “entenda” que é para deixar o teste condicional para a próxima vez de verificação. Laços pós-teste tem a característica de deixarem as ações passarem dentro do bolo uma vez antes de serem avaliadas. Para verificar essa ocorrência basta alterar o valor 1 da instrução COMPUTE AC- CONT = 1 para 6. Você perceberá que o valor acima da condição será apresentado e em seguida o programa é inter-rompido. Além do trecho WITH TEST AFTER há o trecho WITH TEST BEFORE que diz para que a condição seja imediatamente avaliada antes do processamento entra no bloco do laço. Como o uso desses recursos é opcional a omissão mantém a linguagem no modo WITH TEST BEFORE. Já que anteriormente foi apresentado o comando GO TO cabe neste momento mais um exemplo de uso adequado para este renegado. Algumas poucas linhas de programação possuem uma estrutura de laço que é a das mais versáteis, pois a condição de encerramento pode ser posicionada em qualquer lugar do bloco do laço, trata-se do laço condicional seletivo. 3.5.2 Ciclo iterativo O estilo padrão de laço iterativo usado em COBOL é conseguido de duas formas: forma condicional e forma incondicio-nal. A forma condicional é operada com os comandos PERFORM, VARYING, FROM, BY e UNTIL e a forma incondici-onal é operada com os comandos PERFORM e TIMES. No sentido de exemplificar um trecho de código que apresente no monitor de vídeo os valores de 1 a 5 na forma condi-cional iterativa observe os detalhes seguintes: DATA DIVISION. WORKING-STORAGE SECTION. 77 AC-CONT PIC 9. PROCEDURE DIVISION. PERFORM VARYING AC-CONT FROM 1 BY 1 UNTIL AC-CONT > 5 DISPLAY AC-CONT END-PERFORM. Observe o trecho de código é veja que é solicitado que se faça a variação (VARYING) da variável AC-CONT iniciada em 1 (FROM 1), de 1 em 1 (BY 1) até que (UNTIL) o valor de AC-CONT seja maior que 5. Perceba que está estrutura possui um nível de compactação maior que as formas mostradas anteriormente. O valor de BY pode ser definido com o passo desejado. No sentido de exemplificar um trecho de código que apresente no monitor de vídeo os valores de 1 a 5 na forma iterati-va incondicional observe os detalhes seguintes: DATA DIVISION. WORKING-STORAGE SECTION. 77 AC-CONT PIC 9. PROCEDURE DIVISION. COMPUTE AC-CONT = 1. PERFORM 5 TIMES DISPLAY AC-CONT COMPUTE AC-CONT = AC-CONT + 1 END-PERFORM. 112 PROGRAMAÇÃO COBOL No trecho anterior note a instrução PERFORM 5 TIMES que efetua cinco repetições do bloco interno ao laço. Diferen-temente do PERFORM com VARYING aqui é necessário definir a inicialização da variável e seu incremento de forma semelhante a forma usada na definição do laço condicional iterativo. 3.5.3 Ciclo seletivo Laço seletivo é uma estrutura que não possui indicação direta de finalização nos limites de sua definição. A verificação de interrupção é realiza por uma instrução IF/END-IF que pode ser colocada em qualquer linha dentro dos limites do bloco que o laço executa. Um laço seletivo é escrito como qualquer outro laço, tendo como diferenciação o uso do comando FOREVER ou das palavras UNTIL e EXIT no local que seria a definição da condição de encerramento do laço. Como demonstração da estrutura de operação deste tipo de laço considere como necessidade apresentar os valores inteiros de 1 a 5 utilizando-se um laço condicional seletivo. DATA DIVISION. WORKING-STORAGE SECTION. 77 AC-CONT PIC 9. PROCEDURE DIVISION. COMPUTE AC-CONT = 1. PERFORM FOREVER DISPLAY AC-CONT COMPUTE AC-CONT = AC-CONT + 1 IF AC-CONT > 5 EXIT PERFORM END-IF END-PERFORM. Ao ser executado o trecho anterior os valores de 1 a 5 são apresentados e quando o valor da variável AC-CONT for maior que 6 ocorrerá uma saída do laço conforme a ação definida por FOREVER. Na sequência troque o comando FOREVER por UNTIL EXIT. O trecho dentro do laço representado pelos comandos IF/END_IF podem ser colocados em qualquer posição dentro dos limites de PERFORM e END-PERFORM. Devido a esta possibilidade o laço é chamado de seletivo. Anteriormente foi apresentado com ressalvas o comando GO TO. A título de ilustração veja a estrutura de laço seletivo simulada com o uso do comando GO TO e observe os motivos que levam a solicitar o seu não uso na programação estrutura e orientada a objetos, permitido algumas vezes em raras exceções, quando uma estrutura lógica não existe na linguagem em uso. DATA DIVISION. WORKING-STORAGE SECTION. 77 AC-CONT PIC 9. PROCEDURE DIVISION. COMPUTE AC-CONT = 1. LOOP-PARA. DISPLAY AC-CONT. COMPUTE AC-CONT = AC-CONT + 1. IF AC-CONT > 5 GO TO END-LOOP-PARA END-IF. GO TO LOOP-PARA. END-LOOP-PARA. AÇÃO IN/CONDICIONAL 113 Veja que neste código está se lançando mão do comando GO TO (com os devidos cuidados) para estabelecer os des-vios junto aos parágrafos LOOP-PARA e END-LOOP-PARA para simular a ação de um laço PERFORM/END- PERFORM com FOREVER. O parágrafo LOOP-PARA simula um laço do tipo condicional seletivo, deixando o fluxo de processamento passar direto para a instrução DISPLAY AC-CONT após a variável ser inicializada com COMPUTE AC- CONT = 1. Na sequência é feita a atribuição do valor do contador sobre a variável AC-CONT e na sequência a instru-ção IF AC-CONT > 5 GO TO END-LOOP-PARA END-IF verifica se o valor do contador é maior que 5 e sendo esta condição verdadeira direciona o fluxo para o parágrafo END-LOOP-PARA que dará continuidade e encerramento do programa. Se a condição não é verdadeira a instrução GO TO LOOP-PARA volta o fluxo para o parágrafo LOOP- PARA. A instrução IF AC-CONT > 5 GO TO END-LOOP-PARA END-IF é responsável pela saída do fluxo do laço, podendo ser colocada em qualquer linha do bloco entre LOOP-PARA e END-LOOP-PARA, excetuando-se a linha de código com a instrução GO TO LOOP-PARA que deve ficar na última linha antes de END-LOOP-PARA. Veja que neste exemplo, onde se utiliza novamente o comando GO TO, conseguiu-se uma forma de mais suavizada de representação do que a forma apresentada anteriormente. Neste momento, a estrutura lógica escrita tem uma comple- xidade funcional mais simples que a proposta anteriormente. 3.6 DIVISIBILIDADE Divisibilidade é a qualidade daquilo é divisível. Dois conceitos devem ser entendidos pelos programadores de computa-dor: múltiplos e divisores de números naturais. Múltiplos são os resultados obtidos da multiplicação de dois números naturais, enquanto divisores são números naturais que dividem outros números naturais com o objetivo de gerar um resultado exato de divisão, ou seja, obter resto de divisão sempre zero. Quando o resto de uma divisão de números naturais é igual a zero, tem-se divisibilidade, ou seja, resultado de divisão exata. Pelo fato de todo número natural ser múltiplo de si mesmo, uma forma de trabalhar esses valores é pelas operações de cálculo com divisores.Em uma divisão, existem alguns termos que precisam ser conhecidos: dividendo (valor que será dividido), divisor (valor que divide o dividendo), quociente (resultado da divisão do dividendo pelo divisor) e resto (valor que sobra da divisão). A Figura 3.1 mostra o processo de divisão de dois números naturais. Figura 3.1 - Exemplo de divisão de dois números naturais De acordo com o exposto na Figura 3.1, fica fácil deduzir como obter a divisibilidade de um dividendo (valor 5) por um divisor (valor 2). Considere a expressão matemática Resto = Dividendo – Divisor . Quociente para obter a divisibilidade, na qual as variáveis Dividendo, Divisor e Quociente serão substituídas por valores inteiros positivos. Assim sendo, considere os valores de dividendo 5 e divisor 2 na expres- são matemática Resto = 5 – 2 . 2. Basta, primeiro, multipli- car 2 . 2 para obter o valor 4, que será subtraído do valor 5 e resultará no valor 1 para a variável Resto, ou seja, Resto é diferente de zero. Nesse caso, não ocorreu a divisibilidade do valor 5 pelo valor 2 porque 2 não é múltiplo de 5. A expressão matemática Resto = Dividendo – Divisor . Quociente é obtida da equação matemática: n a nar em que a variável r representa o resto da divisão; a variável a, representa o dividendo; e a variável n, o divisor. Observe o cálculo do quociente com o uso da função parte inteira inferior, que obtém o resultado inteiro da divisão do dividendo a pelo divisor n. A função parte inteira inferior tem o objetivo de retornar a parte inteira de um número decimal. Compu-tacionalmente esta expressão matemática deve ser escrita na forma algébrica como r = a – n * (a / n). 114 PROGRAMAÇÃO COBOL A função parte inteira pode ser representada de duas formas: parte inteira inferior e superior. Na forma inferior retorna a parte inteira do valor, desconsiderando a parte decimal. Já na forma superior retorna o arredondamento do valor inteiro mais próximo para cima. As funções parte inteira inferior e superior são graficamente representadas como: x Parte inteira superior = porção inteira do valor + 1 x Parte inteira inferior = porção inteira do valor A forma algébrica r = a – n * (a / n) é uma operação algorítmica genérica, que pode ser facilmente adaptada a qualquer linguagem de programação. Em COBOL deve ser escrita como r = a – n * FUNCTION INTEGER(a / n). A título de demonstração considere a necessidade de efetuar a entrada de um valor numérico inteiro de máscara 9999 e informar se o valor informado é par ou ímpar. ENVIRONMENT DIVISION. CONFIGURATION SECTION. REPOSITORY. FUNCTION INTEGER INTRINSIC. DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-VAL PIC 9999. 77 WS-RES PIC 9999. PROCEDURE DIVISION. ACCEPT WS-VAL. COMPUTE WS-RES = WS-VAL - 2 * INTEGER(WS-VAL / 2). IF WS-RES = 0 DISPLAY "Valor par." ELSE DISPLAY "Valor Impar." END-IF. Se fornecido valores múltiplos de 2 será mostrada a mensagem "Valor par.", caso contrário será apresentada a men-sagem "Valor impar.". Este efeito é conseguido com COMPUTE WS-RES = WS-VAL - 2 * INTEGER(WS-VAL / 2) que tem por finalidade calcular o resto da divisão do valor informado por 2. Sendo o resto igual a zero o valor fornecido é par. Veja que na expressão para calcular o resto da divisão (variável WS-RES) é omitido a cláusula FUNCTION. Isto é pos-sível quando se utiliza FUNCTION INTEGER INTRINSIC definida no parágrafo REPOSITORY da CONFIGURATION SECTION em ENVIRONMENT DIVISION. O parágrafo REPOSITORY (repositório) permite especificar nomes de protótipos de programas, de funções, de delega- dos, de enumerações, de interfaces e propriedades usadas no escopo da ENVIRONMENT DIVISION. Permite também a declaração de nomes de funções intrínsecas, como foi o caso, para poder inibir o uso da cláusula FUNCTION. Caso queira indicar o uso de todas as funções intrínsecas, use a instrução FUNCTION ALL INTRINSIC. O uso da instrução FUNCTION ALL INTRINSIC faz com que o compilador carregue para a memória, no momento da compilação, a lista completa das funções intrínsecas existentes, simplificando o uso das mesmas. Isto facilita, em muito, o uso de algumas operações, como por exemplo, apresentar o valor inteiro do cálculo da raiz quadrada de 9.75. Sem o uso da instrução FUNCTION ALL INTRINSIC a extração do valor inteiro da raiz quadrada de 9.75 é definida: DISPLAY FUNCTION INTEGER(FUNCTION SQRT(9.75)). Observe que o comando FUNCTION deve ser usado sempre antes do nome da função. Isso é inviável quando há a necessidade de se trabalhar com um conjunto grande de funções dentro de expressões algébricas. Com o uso da ins-trução FUNCTION ALL INTRINSIC a mesma situação fica apenas definida como: DISPLAY INTEGER(SQRT(9.75)). AÇÃO IN/CONDICIONAL 115 Atente para o uso da função intrínseca INTEGER que tem por finalidade extrair de um número decimal qualquer a sua porção inteira. Neste caso, a função INTEGER recebe como argumento a divisão do valor WS-VAL por dois e extrai o valor inteiro da operação. Mesmo trabalhando, com valores inteiros é conveniente fazer uso da função INTEGER para calcular o quociente inteiro de divisão. 3.7 INTERRUPÇÃO DE LAÇOS Os laços são estruturas operacionais que podem ser interrompidas em sua execução caso certa condição ocorra. Esta ocorrência pode ser efetivada com o uso das frases EXIT PERFORM (apresentada no uso de laços seletivos) e EXIT PERFORM CYCLE. O laço que opera com EXIT PERFORM é mais radical uma vez que faz o término abrupto da exe-cução do laço. Já EXIT PERFORM CYCLE faz uma interrupção temporária no laço mantendo o controle operacional dentro do laço em execução. Como exemplo de uso do recurso EXIT PERFORM, considere o trecho de programa seguinte, que visa apresentar uma se- quência de valores numéricos inteiros entre 1 e 10, até o encontro da condição que fará a interrupção brusca do laço quando o valor da contagem estiver em 6. DATA DIVISION. WORKING-STORAGE SECTION. 77 AC-I PIC 99. PROCEDURE DIVISION. COMPUTE AC-I = 1. PERFORM VARYING AC-I FROM 1 BY 1 UNTIL AC-I > 10 IF AC-I = 6 EXIT PERFORM END-IF DISPLAY AC-I END-PERFORM. O trecho anterior faz a apresentação dos valores de 1 a 5. O laço será interrompido e encerrado quando a variável AC-I esti- ver com o valor 6. Neste momento EXIT PERFORM será executado fazendo com que forçosamente o laço seja encerrado não chegando à variável AC-I atingir o valor 10. Como exemplo de uso da frase EXIT PERFORM CYCLE, considere o trecho de código seguinte, que apresenta uma se- quência de valores numéricos ao efetuar a contagem de 1 a 10, até o encontro da condição que fará a interrupção temporária do laço quando o valor da contagem estiver em 6. DATA DIVISION. WORKING-STORAGE SECTION. 77 AC-I PIC 99. PROCEDURE DIVISION. COMPUTE AC-I = 1. PERFORM VARYING AC-I FROM 1 BY 1 UNTIL AC-I > 10 IF AC-I = 6 EXIT PERFORM CYCLE END-IF DISPLAY AC-I END-PERFORM. A execução do trecho anterior apresenta os valores de 1 a 5 e de 7 a 10, sendo o valor 6 omitido da apresentação. A omissão da apresentação do valor 6 decorre da ação da frase EXIT PERFORM CYCLE que faz uma interrupção temporária na ação do programa. Isto posto, quando a variável AC-I está com o valor 6 sua apresentação é omitida, pois o recurso indicado pela frase EXIT PERFORM CYCLE faz com que o laço em execução seja momentaneamente interrompido na iteração atual e passando sua ação para a próxima interação a ser efetivada. 116 PROGRAMAÇÃO COBOL 3.8 HORA DE PROGRAMAR Nesta etapa são colocadas em prática, grande parte do que foi apresentado neste capítulo. Os elementos aqui mostra-dos complementam a parte do estudo da ação sequencial e proporciona maior visão sobre diversos, mesmo que bási-cos, elementos da linguagem de programação COBOL. Atente para cada problema apresentado e respectiva solução.CÁLCULO DE ADIÇÃO COM DESVIO CONDICIONAL SIMPLES Elaborar programa de computador que que leia dois valores numéricos inteiros desconhecidos, some-os e apresente o resultado, caso o valor somado seja maior ou igual a 10. Para o desenvolvimento deste programa é considerada uma máscara de entrada definida com o formato 9(3) e uma máscara definida para a saída do resultado configurada como 9(4). Selecione e defina um projeto do programa vazio com o nome c03ex01.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C03EX01 AS "Capitulo 3 – Exemplo 1". * DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-A PIC 9(3). 77 WS-B PIC 9(3). 77 WS-R PIC 9(4). 77 WS-DSP-R PIC ZZZZ. 77 WS-ENTER PIC X. * PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY "Entre valor : " WITH NO ADVANCING. ACCEPT WS-A. DISPLAY "Entre valor : " WITH NO ADVANCING. ACCEPT WS-B. COMPUTE WS-R = WS-A + WS-B. IF WS-R >= 10 MOVE WS-R TO WS-DSP-R DISPLAY "Resultado = " WS-DSP-R END-IF. DISPLAY X"0D". DISPLAY "Tecle para encerrar... " WITH NO ADVANCING. ACCEPT WS-ENTER. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. Ao ser executado o programa, dependendo das entradas ocorrerá ou não a apresentação do resultado. Aqui é mais um lembrete do que uma novidade, na linha 9 é definida a variável de saída com formatação da máscara editada para a apresentação do valor calculado sem zeros à esquerda. O ponto principal do programa é o uso da tomada de decisão simples definida entre as linhas 19 e 22 que controlam a apresentação do valor do resultado, caso este seja maior ou igual a 10. Observe que a transferência do cálculo com o comando MOVE só é executada caso a condição seja verdadeira. Esta estratégia visa poupar tempo de processamen- AÇÃO IN/CONDICIONAL 117 to, pois somente será apresentado o resultado se a condição for verdadeira. Não há necessidade de realizar esta mo-vimentação de dado se não for para efetuar a apresentação. No mais o programa possui recurso já conhecidos que dispensam explicações. CÁLCULO DE ADIÇÃO COM DESVIO CONDICIONAL COMPOSTO Elaborar programa de computador que que efetue a leitura de dois valores numéricos inteiros positivos e negativos e processe sua adição. Caso o resultado obtido seja maior ou igual a 10, esse valor deve ser apresentado, somando a ele 5. Caso o resultado do valor somado não seja maior ou igual a 10, ele deve ser apresentado subtraindo 7. Para o desenvolvimento deste programa é considerada uma máscara de entrada definida com o formato 9(3) e uma máscara definida para a saída do resultado configurada como 9(4). Selecione e defina um projeto do programa vazio com o nome c03ex02.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C03EX02 AS "Capitulo 3 – Exemplo 2". * DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-A PIC 9(3). 77 WS-B PIC 9(3). 77 WS-R PIC 9(4). 77 WS-DSP-R PIC ZZZZ. 77 WS-ENTER PIC X. * PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY "Entre valor : " WITH NO ADVANCING. ACCEPT WS-A. DISPLAY "Entre valor : " WITH NO ADVANCING. ACCEPT WS-B. COMPUTE WS-R = WS-A + WS-B. IF WS-R >= 10 ADD 5 TO WS-R MOVE WS-R TO WS-DSP-R DISPLAY "Resultado = " WS-DSP-R ELSE SUBTRACT 7 FROM WS-R MOVE WS-R TO WS-DSP-R DISPLAY "Resultado = " WS-DSP-R END-IF. DISPLAY X"0D". DISPLAY "Tecle para encerrar... " WITH NO ADVANCING. ACCEPT WS-ENTER. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. O uso da ação de tomada de decisão composta é definido nas linhas 19 e 27. Veja que nas linhas 20 e 24 estão sendo usados os verbos ADD e SUBTRACT que respectivamente acrescenta 5 e subtraí 7 do resultado somado na linha 18 e validado na linha 19. 118 PROGRAMAÇÃO COBOL Nas linhas 20 e 24 poderiam ter sido usados o comando COMPUTE para somar 5 e subtrair 7 do resultado somado. Apesar de COMPUTE ser preterido sobre os operadores aritméticos descritivos aqui é uma oportunidade em usá-los e mostrar que neste contexto escrevê-los deu mais sentido dentro do que é solicitado. TRIÂNGULO COM DESVIO CONDICIONAL ENCADEADO Elaborar programa de computador que efetue a leitura de três valores decimais positivos para os lados A, B e C de um triângulo. O programa deve verificar se os lados fornecidos formam realmente um triângulo e acusar com mensagem de erro caso esta condição. Se a condição for verdadeira, deve ser indicado o tipo de triângulo formado: isósceles, escale- no ou equilátero. Para o desenvolvimento deste programa é considerada uma máscara de entrada definida com o formato S9(3)V9(2) e é preciso considerar também que triângulo é uma forma geométrica composta de três lados, e cada lado é menor que a soma dos outros dois lados, ou seja, será um triângulo quando A B e B C; e é equilátero quando todos os lados são iguais, sendo A = B e B = C. Selecione e defina um projeto do programa vazio com o nome c03ex03.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C03EX03 AS "Capitulo 3 – Exemplo 3". * DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-A PIC S9(3)V9(2). 77 WS-B PIC S9(3)V9(2). 77 WS-C PIC S9(3)V9(2). 77 WS-ENTER PIC X. * PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY "Entre lado : " WITH NO ADVANCING. ACCEPT WS-A. DISPLAY "Entre lado : " WITH NO ADVANCING. ACCEPT WS-B. DISPLAY "Entre lado : " WITHNO ADVANCING. ACCEPT WS-C. IF WS-A para encerrar... " WITH NO ADVANCING. ACCEPT WS-ENTER. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. O programa mostra o uso dos operadores lógicos AND e OR nas linhas 19 até 21 e 25. O trecho entre as linhas 19 e 21 verifica se a condição WS-A : " WITH NO ADVANCING. ACCEPT WS-A. DISPLAY "Entre o valor : " WITH NO ADVANCING. ACCEPT WS-B. DISPLAY X"0D". DISPLAY "[1] - Adicao" DISPLAY "[2] - Subtracao" DISPLAY "[3] - Multiplicacao" DISPLAY "[4] - Divisao" DISPLAY X"0D". DISPLAY "Escolha uma opcao: " WITH NO ADVANCING. ACCEPT WS-OPCAO. DISPLAY X"0D" IF WS-B = 0 DISPLAY "Erro na divisao." ELSE IF WS-OPCAO >= 1 AND WS-OPCAO para encerrar... " WITH NO ADVANCING. ACCEPT WS-ENTER. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. Execute o programa e faça algumas experiên-cias, por exemplo com os valores 3 e 4. Vale aqui uma atenção a linha 9 onde se define o formato de saída para a indicação de valores negativos, daí o uso do símbolo “menos”. Os dois símbolos “menos” criam a máscara para as posições de centena e dezena. Na posição da unidade encontra 9 que é usado quando se deseja a apresentação de um valor zero na posição. Se for informado os valores 3 e 4 e escolhia a divisão o resultado apresentado como 0.75. A linha 28 verifica se o valor do divisor é zero e se for a mensagem de erro "Erro na divisao" é apresentada. Não sendo o divisor igual a zero ocorre na linha 31 a verificação da validade das opções de menu fornecida. Se a condição é verdadeira os cálculos podem ser realizados, mas se não for será apresentada a mensagem "Opção invalida" na linha 45. O trecho de linhas de 32 a 41 controla o direcionamento do cálculo após as validações de divisor diferente de zero e de valor de opção com o uso da instrução de decisão seletiva. Após a execução dessa instrução ocorre o preparo para apresentação do resultado na linha 42 e a apresentação do resultado na linha 43. AÇÃO IN/CONDICIONAL 121 TABUADA COM LAÇO CONDICIONAL PRÉ-TESTE Elaborar programa de computador que efetue a leitura de um valor numérico inteiro positivo e apresente os resultados da tabuada do valor fornecido entre 1 e 10, respeitando a formatação típica de uma tabuada apresentada no estudo de aritmética. Para o desenvolvimento deste programa é considerada o uso da máscara 9(2) para a entrada do valor de tabuada e para o valor da variável de controle do laço que serão operados com posições de unidade e dezena. Para a variável de resposta considere a máscara 9(3) para acomodar unidade, dezena e centena. Além das variáveis de entrada e pro-cessamento do programa é preciso preparar as variáveis de máscaras editadas para a apresentação dos dados. Neste caso serão usadas Z9 e ZZ9. Selecione e defina um projeto do programa vazio com o nome c03ex05.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C03EX05 AS "Capitulo 3 – Exemplo 5". * DATA DIVISION. WORKING-STORAGE SECTION. * 77 WS-EN PIC 9(2). 77 AC-CI PIC 9(2). 77 WS-CR PIC 9(3). 77 WS-SN PIC Z9. 77 AC-SI PIC Z9. 77 WS-SR PIC ZZ9. 77 WS-ENTER PIC X. * PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY "Entre o valor da tabuada: " WITH NO ADVANCING. ACCEPT WS-EN. COMPUTE AC-CI = 1. PERFORM UNTIL AC-CI > 10 COMPUTE WS-CR = WS-EN * AC-CI MOVE WS-EN TO WS-SN MOVE AC-CI TO AC-SI MOVE WS-CR TO WS-SR DISPLAY WS-SN " X " AC-SI " = " WS-SR COMPUTE AC-CI = AC-CI + 1 END-PERFORM. DISPLAY X"0D". DISPLAY "Tecle para encerrar... " WITH NO ADVANCING. ACCEPT WS-ENTER. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. Execute o programa e forneça para a tabuada valores de 1 a 10. Apesar de ter sido comentado é bom lembra a estratégia e regra de definição de variáveis entre as linhas 7 e 13. O uso da indicação WS é para sinalizar que são variáveis criadas na WORKING-STORAGE SECTION. Neste caso particular, 122 PROGRAMAÇÃO COBOL a variável precedida de E (para EN) é a variável de entrada, as variáveis incidas com C (para CI e CR) são variáveis usadas para a realização de algum cálculo e as variáveis com S (para SN, SI e SR) são variáveis de saída. O laço definido entre as linhas 20 e 27 controla o cálculo e a apresentação dos elementos que compõem o visual de uma tabuada. Na linha 19 é definida a inicialização do contador da tabuada com valor como indica a instrução COMPUTE AC-CI = 1. Na sequência a linha 20 possui a instrução PERFORM UNTIL AC-CI > 10 que verifica a condição estabelecida, encer-rando o laço quando o valor de AC-CI for maior que 10, isto significa dizer que enquanto o valor do contador é menor ou igual a 10 o laço permanece em execução. Dentro do laço entre as linhas 20 e 27 é realizado o cálculo da operação WS-CR = WS-EN * AC-CI com o comando COMPUTE e posterior apresentação de cada valor de forma tabulada na linha 25. Quando o programa encontra a linha com a instrução AC-CI = AC-CI + 1 na linha 26, efetua o acréscimo de uma unidade à variável contador. No primeiro momento de execução a variável AC-CI possui o valor 1 e, somado a mais 1, passa a ter o valor 2. Após a variável AC-CI estar carregada com o valor 2 na execução do programa volta para a instrução da linha 20, que verifica a condição da variável novamente. Sendo a condição verdadeira, o bloco de código existente entre as linhas 21 e 26 será executado, mais uma vez. Quando o processamento do programa chegar em WS-CR = WS-EN * AC-CI, fará com que a variável AC-CI passe a ter valor 3. O programa vai processar novamente a rotina de instruções, passando o contador para 4, e assim por diante até chegar ao valor 11, quando o laço será automaticamente encerrado. FATORIAL COM LAÇO CONDICIONAL PRÉ-TESTE Elaborar programa de computador que efetue os cálculos e apresente os resultados das fatoriais de 0 a 19. Para este programa é usada a máscara 99 para a variável WS-EN (entrada do valor no laço) e WS-CI (contagem do laço, além dessas variáveis a variável WS-CFAT (cálculo da fatorial) usa a opção de compactação COMP ajustada para 18 dígitos. Para a saída dos dados são definidas as variáveis AC-SI com máscara Z9 e WS-SFAT com máscara Z(18). Selecione e defina um projeto do programa vazio com o nome c03ex06.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C03EX06 AS "Capitulo 3 – Exemplo 6". * DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-EN PIC 99. 77 AC-CI PIC 99. 77 AC-CFAT PIC 9(18) COMP. 77 AC-SI PIC Z9. 77 AC-SFAT PIC Z(18). 77 WS-ENTER PIC X. * PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. MOVE 19 TO WS-EN MOVE 1 TO AC-CFAT MOVE 0 TO AC-CI PERFORM UNTIL AC-CI GREATER THAN WS-EN MOVE AC-CI TO AC-SI MOVE AC-CFAT TO AC-SFAT DISPLAY AC-SI "! = " AC-SFAT ADD 1 TO AC-CI ------------------------------------------------------------------------ AÇÃO IN/CONDICIONAL 123 ------ LINHAS ------ 23 24 25 26 27 28 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- COMPUTE AC-CFAT = AC-CFAT * AC-CI END-PERFORM. DISPLAY X"0D". DISPLAY "Tecle para encerrar... " WITH NO ADVANCING. ACCEPT WS-ENTER. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. Note que ao se executado são apresentados os resultados das fatoriais de 0 a 19. O programa não apresenta novidades em relação aos recursos já abordados, mas faz uso de algumas opções interes-santes como a definição da opção de compactação COMP na linha 8 para dar a variável AC-CFAT a capacidade de operar no limite máximo permitido na linguagem. Entre as linhas 15 e 17 são realizadas as inicializações das variáveis a serem usadas no programa, por serem variáveis numéricas todas poderiam ter sido inicializadas com o uso do comando COMPUTE. Outro ponto a ser observado é o uso do operador lógico descritivo GREATER THAN na linha 18 em substituição ao uso do operador relacional maior que e o acréscimo de uma unidade na variável AC-CI com uso do verbo ADD na linha 22. TABUADA COM LAÇO CONDICIONAL PÓS-TESTE Elaborar programa de computador que efetue a leitura de um valor numérico inteiro positivo e apresente os resultados da tabuada do valor fornecido entre 1 e 10, respeitando a formatação típica de uma tabuada apresentada no estudo de aritmética, mas operando com estrutura de laço pós-teste. Para o desenvolvimento deste programa é considerada o uso da máscara 9(2) para a entrada do valor de tabuada e para o valor da variável de controle do laço que serão operados com posições de unidade e dezena. Para a variável de resposta considere a máscara 9(3) para acomodar unidade, dezena e centena. Além das variáveis de entrada e pro-cessamento do programa é preciso preparar as variáveis de máscaras editadas para a apresentação dos dados. Neste caso serão usadas Z9 e ZZ9. Selecione e defina um projeto do programa vazio com o nome c03ex07.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012- Relatório simples no escritor de relatórios .................................................................................................. 371 8.1.5 - Relatório com quebra simples no escritor de relatórios .............................................................................. 375 8.1.6 - Relatório com totalização no escritor de relatórios ..................................................................................... 378 8.2 - Utilização de telas .................................................................................................................................................... 382 8.3 - Utilização de teclas de função e outros atalhos ....................................................................................................... 393 Apêndices – Complementos Operacionais Execução autonoma de programas (A) ............................................................................................................................ 399 Preparação de instalador (B) ........................................................................................................................................... 405 Caracteres EBCDIC (C) ..................................................................................................................................................... 411 Caracteres ASCII (D) ........................................................................................................................................................ 413 Tabela de conversão EBCDIC para ASCII E) ...................................................................................................................... 415 Tabela de conversão ASCII para EBCDIC (F) ..................................................................................................................... 417 Bibliografia (X) ................................................................................................................................................................ 419 PREFÁCIO Este livro foi escrito para pessoas novatas na atividade de programação com a linguagem COBOL, desde que possuam prévios conhecimentos de lógica de programação ou que já tenham domínio de alguma linguagem de programação. Este texto apresenta os primeiros passos na programação COBOL em um contexto extremamente simplifica- do e introdutório, não há a menor pretensão em avançar além disto, sendo apenas este estudo um passapor- te de entrada ao mundo da programação COBOL. O nível de detalhamento técnico apresentado neste livro é básico. Nada intermediário ou avançado sobre COBOL é aqui apresentado. Se você já é coboleiro ou coboleira experientes com certeza este livro não é para você. Caso você seja expe- riente na linguagem é aconselhável realizar estudo de outras obras do assunto e neste sentido deixo como indicação o livro: Programação Estruturada em COBOL, 9a. Edição para o século XXI Autores: Stern & Stern LTC Editora De forma geral, há outros livros que podem auxiliar o estudo da linguagem. Neste sentido, recomendo: COBOL Sem Mistérios Autor: Prof. Joel Saade Editora: Novatec Linguagem de programação COBOL para Mainframes, 2ª. Edição Autor: Prof. Jaime Wojciechowski Editora: Ciência Moderna Mastering COBOL Programming, 2ª. Edição Autores: Roger Hutty e Mary Space Editora: Palgrave Master Series Este livro apresenta a linguagem de maneira gradativa a partir de exemplos simplistas, despretensiosos e até incomuns no mundo COBOL até chegar a exemplos contextualizados e com nível de complexidade maior. Os exemplos utilizados ou desenvolvidos podem não ser as melhores soluções para determinados problemas, mas são as soluções possíveis e estão dentro do contexto básico indicado na obra. Este texto descreve detalhes básicos da linguagem, evitando-se apresentar informações que não são usadas no contexto da obra, salvo raras exceções. Cada capítulo apresenta um tema que abrange recursos, expla- nações, explicações e aplicações, partindo-se como base da escrita de códigos que sejam compatíveis com o padrão 2014 para a linguagem. No entanto, algumas vezes são comentados e usados recursos dos padrões normatizados em 1974 e 1985. Cada capítulo, exceto o primeiro, mostra uma série de recursos da linguagem em trechos de código que de- vem ser codificados para o desenvolvimento da aprendizagem. Ao final de cada capítulo, exceto o sétimo, é definido um tópico chamado “hora de programar” que trás uma série de exemplos de códigos com o uso dos recursos apresentados no próprio capítulo ou em capítulos anteriores, podendo conter detalhes não explana- dos e que são então descritos de forma complementar. No sétimo capítulo devido à complexidade do tema sobre o uso de arquivos nativos é apresentada uma série de programas de aplicação durante as explanações dos detalhes conceituais não tendo o tópico “hora de programar”. Os programas completos apresentados no livro são ofertados prontos para aquisição a partir da plataforma GitHub em https://github.com/J-AugustoManzano/cobol. Para a escrita deste livro não foram usados como referência, em excesso, outros livros da linguagem além dos citados. Foram usados intensamente os manuais técnicos da linguagem publicados por empresas, como: Apple, Computer Associates, Compaq, Bull, Digital, Envyr, Fujtsu, Hewlett Packard, Heirloom, IBM, Micro Fo- cus, Unisys e VMS Software, além da documentação da FSF (Free Software Foundation) para o GnuCOBOL tema deste trabalho. Um registro que se faz necessário é que não respeitei os padrões oficiais de citação de normas bibliográficas. Estou respeitando apenas as regras básicas de codificação de programas na linguagem. No entanto, há deta- lhes usados no contexto de desenvolvimento no universo da alta plataforma que aqui não estão sendo respei- tados. Cabe destacar que este livro é distribuído gratuitamente em formato eletrônico PDF no site do autor ou dispo- nibilizado comercialmente em sua forma impressa a partir das plataformas de publicação Clube de Autores e Agbook para quem desejar ter o material no formato livro. Este livro não passou por revisões de língua portuguesa e está em sua forma bruta em versão pré-alpha. Por isso, poderão ser encontrados erros de escrita, concordância ou outros que passaram desapercebidos, exce- to os códigos de programas os quais foram exaustivamente testados. Auxílios, neste sentido e mesmo na estrutura dos programas, serão sempre bem vindos, desde que sejam realizados sem nenhum interesse fi- nanceiro ou comercial e posicionados de forma repeitosa. Os colaboradores deste trabalho serão menciona- dos sempre nas próximas edições da obra na seção colaboradores com seus nomes completos e por exten- so, dispostos em ordem alfabética após a seção sobre o autor. Ao final deste estudo o leitor estará capacitado a entender e aplicar as técnicas básicas de programação no desenvolvimento de aplicações COBOL. São demonstrados mais de cem exemplos de programas escritos. Este livro apresenta um total de oito capítulos mais alguns apêndices que cobrem diversos aspectos operaci- onais da linguagem. No capítulo 1 é mostrado de forma resumida o histórico de surgimento da linguagem COBOL, a motivação de seu desenvolvimento e sua evolução até os dias atuais, acompanhando as definições e crescimento dos pa- drões ANSI e ISO. Apresenta-se a ferramenta de desenvolvimento OpenCobolIDE, obtenção e instalação, bem como, a definição de algumas configurações. Outro ponto de importante valor apresentado são as regras de codificação da linguagem segundo sua estrutura sintática, os elementos componentes da linguagem e exemplos de aplicação com alguns recursos essenciais. Um destaque deste capítulo é a apresentação de um programa codificado em formulário, cartão perfurado e sua comparação com a forma dos dias atuais. O capítulo 2 mostra de forma básica e inicial o processo de desenvolvimento de programas com estrutura----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C03EX07 AS "Capitulo 3 – Exemplo 7". * DATA DIVISION. WORKING-STORAGE SECTION. * 77 WS-EN PIC 9(2). 77 AC-CI PIC 9(2). 77 WS-CR PIC 9(3). 77 WS-SN PIC Z9. 77 AC-SI PIC Z9. 77 WS-SR PIC ZZ9. 77 WS-ENTER PIC X. * ------------------------------------------------------------------------ 124 PROGRAMAÇÃO COBOL ------ LINHAS ------ 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY "Entre o valor da tabuada: " WITH NO ADVANCING. ACCEPT WS-EN. COMPUTE AC-CI = 1. PERFORM WITH TEST AFTER UNTIL AC-CI > 10 COMPUTE WS-CR = WS-EN * AC-CI MOVE WS-EN TO WS-SN MOVE AC-CI TO AC-SI MOVE WS-CR TO WS-SR DISPLAY WS-SN " X " AC-SI " = " WS-SR COMPUTE AC-CI = AC-CI + 1 END-PERFORM. DISPLAY X"0D". DISPLAY "Tecle para encerrar... " WITH NO ADVANCING. ACCEPT WS-ENTER. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. Execute o programa e forneça para a tabuada valores de 1 a 10. O programa c03ex07 é idêntico ao programa c03ex05, tendo como diferença o trecho WITH TEST AFTER usado na linha 20 junto a instrução PERFORM. TABUADA COM LAÇO ITERATIVO Elaborar programa de computador que efetue a leitura de um valor numérico inteiro positivo e apresente os resultados da tabuada do valor fornecido entre 1 e 10, respeitando a formatação típica de uma tabuada apresentada no estudo de aritmética, mas operando com estrutura de laço iterativo. Para o desenvolvimento deste programa é considerada o uso da máscara 9(2) para a entrada do valor de tabuada e para o valor da variável de controle do laço que serão operados com posições de unidade e dezena. Para a variável de resposta considere a máscara 9(3) para acomodar unidade, dezena e centena. Além das variáveis de entrada e pro-cessamento do programa é preciso preparar as variáveis de máscaras editadas para a apresentação dos dados. Neste caso serão usadas Z9 e ZZ9. Selecione e defina um projeto do programa vazio com o nome c03ex08.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C03EX08 AS "Capitulo 3 – Exemplo 8". * DATA DIVISION. WORKING-STORAGE SECTION. * 77 WS-EN PIC 9(2). 77 AC-CI PIC 9(2). 77 WS-CR PIC 9(3). ------------------------------------------------------------------------ AÇÃO IN/CONDICIONAL 125 ------ LINHAS ------ 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- 77 WS-SN PIC Z9. 77 AC-SI PIC Z9. 77 WS-SR PIC ZZ9. 77 WS-ENTER PIC X. * PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY "Entre o valor da tabuada: " WITH NO ADVANCING. ACCEPT WS-EN. PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10 COMPUTE WS-CR = WS-EN * AC-CI MOVE WS-EN TO WS-SN MOVE AC-CI TO AC-SI MOVE WS-CR TO WS-SR DISPLAY WS-SN " X " AC-SI " = " WS-SR END-PERFORM. DISPLAY X"0D". DISPLAY "Tecle para encerrar... " WITH NO ADVANCING. ACCEPT WS-ENTER. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. Execute o programa e forneça para a tabuada valores de 1 a 10. Este programa é semelhante ao demais que exemplificam o processamento de uma tabuada, tendo como diferencial a definição do laço na linha 19 que conta de 1 até 10 de 1 em 1, a partir da indicação VARYING AC-CI FROM 1 BY 1 na frase do FERMORM e UNTIL. Quando executado o programa, o conjunto de instruções situado dentro do laço delimitado entre as linhas 19 e 25 é executado dez vezes, pois a variável AC-CI (variável de controle) é inicializada com valor 1 na linha 19 com a indicação FROM 1, que é incrementada com 1 quando passa por BY 1 até ultrapassar 10 quando verificado UNTIL AC-CI > 10. DECREMENTO DE VALORES COM LAÇO ITERATIVO Elaborar programa de computador que apresente no monitor de vídeo os valores inteiros de 10 a 1, a partir do uso de laço iterativo. Para o desenvolvimento deste programa é considerada o uso da máscara 99 para a variável que controla a contagem decrescente. Selecione e defina um projeto do programa vazio com o nome c03ex09.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C03EX09 AS "Capitulo 3 – Exemplo 9". * DATA DIVISION. WORKING-STORAGE SECTION. 77 AC-CI PIC 99. ------------------------------------------------------------------------ 126 PROGRAMAÇÃO COBOL ------ LINHAS ------ 7 8 9 10 11 12 13 14 15 16 17 18 19 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- 77 AC-SI PIC Z9. 77 WS-ENTER PIC X. * PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. PERFORM VARYING AC-CI FROM 10 BY -1 UNTIL AC-CI para encerrar... " WITH NO ADVANCING. ACCEPT WS-ENTER. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. Execute o programa e veja a apresentação de valores decrescentes de 10 até 1. Para realizar ações de contagem decrescente basta iniciar a variável contadora com o maior e solicitar a subtração sucessiva do passo sobre o valor até este ser menor que o limite desejado. PORCENTAGEM DE VALORES PARES E IMPARES Elaborar programa de computador que efetue a entrada de dez valores numéricos inteiros e apresente após as entra- das a quantidade de valores pares e impares informados, bem como o percentual de cada categoria numérica. Para o desenvolvimento deste pequeno programa é necessário considerar o uso de certa quantidade de variáveis. A entrada dos valores será processada por uma variávelcom máscara 9(4) para garantir a entrada de valores com o formato de unidade, dezena, centena e unidade de milhar. Para contar a quantidade de pares e impares suas variáveis terão a máscara 9(2) uma vez que são contadas apenas dez entradas. A detecção de pares e impares é realizada pelo resto da divisão de um valor por 2, neste caso esta variável terá a máscara 99 (mas poderia ser sem problemas usada a máscara 9). Para medir o percentual de valores fornecidos usar-se-á a máscara 9(3)V99. Para auxiliar a apresentação dos dados do programa são definidas variáveis como campos de edição compatíveis com as formatações das variáveis usadas para a entrada dos dados. Selecione e defina um projeto do programa vazio com o nome c03ex10.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C03EX10 AS "Capitulo 3 – Exemplo 10". * ENVIRONMENT DIVISION. CONFIGURATION SECTION. REPOSITORY. FUNCTION ALL INTRINSIC. * DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-VALOR PIC 9(4). ------------------------------------------------------------------------ AÇÃO IN/CONDICIONAL 127 ------ LINHAS ------ 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 32 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- 77 WS-PARES PIC 9(2). 77 WS-IMPARES PIC 9(2). 77 WS-RESTO PIC 99. 77 WS-PERCT-P PIC 9(3)V99 VALUE ZERO. 77 WS-PERCT-I PIC 9(3)V99 VALUE ZERO. 77 AC-CI PIC 99. 77 WS-SPAR PIC Z9. 77 AC-SIMP PIC Z9. 77 AC-SI PIC Z9. 77 WS-PORCENT PIC ZZ9.99. 77 WS-ENTER PIC X. * PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10 MOVE AC-CI TO AC-SI DISPLAY "Entre o " AC-SI "o. valor: " WITH NO ADVANCING ACCEPT WS-VALOR COMPUTE WS-RESTO = WS-VALOR - 2 * INTEGER(WS-VALOR / 2) IF WS-RESTO = 0 ADD 1 TO WS-PARES ELSE ADD 1 TO WS-IMPARES END-IF END-PERFORM. COMPUTE WS-PERCT-P = (WS-PARES / (AC-CI - 1)) * 100. COMPUTE WS-PERCT-I = (WS-IMPARES / (AC-CI - 1)) * 100. DISPLAY X"0D". MOVE WS-PARES TO WS-SPAR. DISPLAY "Quantidade de valores pares .....: " WS-SPAR. MOVE WS-IMPARES TO AC-SIMP. DISPLAY "Quantidade de valores impares ...: " AC-SIMP. DISPLAY X"0D". MOVE WS-PERCT-P TO WS-PORCENT. DISPLAY "Valores pares ...................: " WS-PORCENT "%". MOVE WS-PERCT-I TO WS-PORCENT. DISPLAY "Valores impares .................: " WS-PORCENT "%". DISPLAY X"0D". DISPLAY "Tecle para encerrar... " WITH NO ADVANCING. ACCEPT WS-ENTER. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. Execute o programa e forneça os 10 valores solicitados e acompanhe os resultados apresentados. Este programa apresenta uma série de recursos integrando-os de forma mais expressiva em relçao aos programas os anteriores. Observe, principalmente, a lista de definições de variáveis entre as linhas 11 e 22. Veja os detalhes apresen- tados. As variáveis que auxiliam a entrada de dados e os processamentos estão entre as linhas 11 e 17; as variáveis de saída estão entre as linhas 18 e 21. Na linha 28 está sendo usado um estilo de tela que apresenta os valores de entrada na forma ordinal para indicar a entrada da linha 29. A cada valor estrado a linha 30 calcula o resto da divisão do valor fornecido por 2 e se o resto da divisão for igual a zero, como mostra a linha 31 será adicionada uma unidade para a contagem de valores pares infor- 128 PROGRAMAÇÃO COBOL mados como mostra a linha 33, sendo a condição da linha 31 falsa o processamento passa para a linha 33 que adiciona uma unidade ao contador de impares informados. Completado o ciclo de dez entradas o programa calcula nas linhas 37 e 38 os percentuais de valores informados. Ob- serve junto as fórmulas a indicação AC-CI – 1 que tem por finalidade dizer a quantidade total de valores informados. A variável AC-CI quando sai do laço possui um valor maior que a quantidade de vezes que executou o laço de acordo com a ocorrência do valor de passo, estabelecido com BY na linha 26. Usar AC-CI – 1 é vantajoso no sentido de tornar mais fácil aumentar o número de entradas no laço da linha 26. As linhas de 39 a 48 são usadas pelo programa para efetivar a apresentação dos dados do programa. TABUADA ITERATIVA EM LAÇO INTERATIVO INDETERMINADO Elaborar programa de computador que efetue e apresente a tabuada de um valor numérico inteiro qualquer entre 1 e 10 baseando-se na forma tradicional de apresentação de uma tabuada. O programa deve após a entrada de algum valor verificar se o conteúdo fornecido é numérico e caso não seja um número deve apresentar mensagem informando para que seja fornecido apenas valores numéricos. Se o valor fornecido for numérico o programa deve verificar se é um valor entre a faixa de 1 a 10 e não sendo deve apresentar mensagem informando para respeitar a faixa de trabalho do pro- grama. Estando a entrada adequada ao contexto do programa a tabuada deverá ser apresentada. Após a apresentação da tabuada o programa deve perguntar ao usuário se deseja novo cálculo, o qual poderá responder “S” para sim ou “N” para não. Qualquer resposta diferente de “S” ou “N” deve ser recusada e deve ser apresentada mensagem informando para responder apenas “S” ou “N”. Para o desenvolvimento deste programa é usado grande parte dos recursos apresentados. São usadas decisões (sim-ples e compostas) e laços (iterativo, seletivo, interativo pré-teste e interativo pós-pós-teste) definidos de forma encade-ada e sequencial. São aplicados os usados dos operadores lógicos e relacionais. Comentários em vermelho. Selecione e defina um projeto do programa vazio com o nome c03ex11.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C03EX11 AS "Capitulo 3 – Exemplo 11". * ENVIRONMENT DIVISION. CONFIGURATION SECTION. REPOSITORY. FUNCTION ALL INTRINSIC. * DATA DIVISION. WORKING-STORAGE SECTION. * Variaveis de entrada e processamento de dados. 77 WS-EN-TEXTO PIC XX. 77 WS-EN-NUMER PIC 9(2). 77 AC-CI PIC 99. 77 WS-CR PIC 9(3). * Variaveis de saida de dados. 77 WS-SN PIC Z9. 77 AC-SI PIC Z9. 77 WS-SR PIC ZZ9. * Variaveis de interacao. 77 WS-RESP PIC A. 77 WS-ENTERPIC X. * Definicao de constante para salto de linha. 78 CR VALUE X"0D". ------------------------------------------------------------------------ AÇÃO IN/CONDICIONAL 129 ------ LINHAS ------ 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- * PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY "==============================" DISPLAY "| PROGRAMA TABUADA |" DISPLAY "| Entre valores entre 1 e 10 |" DISPLAY "==============================" DISPLAY CR. MOVE "S" TO WS-RESP. PERFORM UNTIL UPPER-CASE(WS-RESP) NOT = "S" PERFORM UNTIL EXIT DISPLAY "Entre valor: " WITH NO ADVANCING ACCEPT WS-EN-TEXTO IF WS-EN-TEXTO IS ALPHABETIC DISPLAY "Por favor, entre valor numerico." ELSE MOVE WS-EN-TEXTO TO WS-EN-NUMER IF WS-EN-NUMER >= 1 AND WS-EN-NUMER 10 DISPLAY "Por favor, valores entre 1 e 10." END-IF END-IF DISPLAY CR END-PERFORM DISPLAY CR PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10 COMPUTE WS-CR = WS-EN-NUMER * AC-CI MOVE WS-EN-NUMER TO WS-SN MOVE AC-CI TO AC-SI MOVE WS-CR TO WS-SR DISPLAY WS-SN " X " AC-SI " = " WS-SR END-PERFORM DISPLAY CR PERFORM WITH TEST AFTER UNTIL UPPER-CASE(WS-RESP) = "S" OR UPPER-CASE(WS-RESP) = "N" DISPLAY "Continua (S/N): " WITH NO ADVANCING ACCEPT WS-RESP IF UPPER-CASE(WS-RESP) NOT = "S" AND UPPER-CASE(WS-RESP) NOT = "N" DISPLAY 'Entrada invalida! Entre apenas "S" ou "N".' END-IF DISPLAY CR END-PERFORM END-PERFORM. DISPLAY "Tecle para encerrar... " WITH NO ADVANCING. ACCEPT WS-ENTER. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. Execute o programa forneça inicialmente uma letra e veja o que acontece. Depois forneça valores maiores que 10 e menores que 1 e veja o que acontece. Após a apresentação da tabuada responda algo diferente de “S” ou “N” e veja o que acontece. 130 PROGRAMAÇÃO COBOL O programa possui quatro áreas bem distintas, sendo: definição de variáveis e constante entre as linhas 11 e 24; trecho de entrada de dados e validação entre as linhas 35 e 50; o trecho de processamento da tabuada e sua apresentação entre as linhas 52 e 58 e por último o trecho de continuidade ou não do programa entre as linhas 60 e 69. Das quatro áreas, três são controladas pelo laço definido entre a linhas 33 e 60. Entre as linhas 12 e 15 são definidas as variáveis de entrada e processamento de dado do programa. As variáveis para a saída são definidas entre as linhas 17 e 19. Nas linhas 21 e 22 são definidas as variáveis de interação do programa. Na linha 24 é definida a constante usada para pular linhas em branco ao longo do programa. Nas linhas 28 a 32 é definido um pequeno rótulo de título avisando ao usuário do que se trata o programa (linha 29) e a regra de operação do programa (linha 30). Este é um efeito decorativo e informativo do programa. A linha 33 atribuí o valor “S” para inicialização da variável WS-RESP usada no laço pré-teste com fluxo verdadeiro defi-nido na linha 34 e encerrado na linha 70. Este laço diz ao programa que executará seu bloco de instruções enquanto a resposta do usuário seja sim (S) indicada entre as linhas 60 e 69. No momento em que o usuário responder não (N) o fluxo de execução do programa é desviado para a linha 71 que faz a apresentação da mensagem de saída do progra-ma antes de seu encerramento. O controle e validação da entrada do valor para o cálculo da tabuada é realizado nos trechos entre as linhas 35 e 50 a partir de um laço do tipo seletivo, cujo controle de saída encontra-se definido nas linhas de 42 a 44, a qual verifica se o valor fornecido está na faixa de aceitação. Após a entrada de dados realizada a partir das linhas 36 e 37, a linha 38 verifica se ocorreu a entrada de algum carac-tere alfabético e se isso ocorreu a mensagem de erro da linha 39 é apresentada informando que deve ser fornecido um valor numérico. Se a entrada ocorreu de forma adequada o fluxo de execução do programa é desviado para a linha 41 que movimenta o dado entrado como alfanumérico (variável WS-EN-TEXTO) para o campo numérico (variável WS-EN- NUMER). Observe que o trecho das 38 a 48 utilizam a técnica de tomada de decisão encadeada com decisões se-quenciais após a linha 40. Entre as linhas 42 e 44 é verificado se o valor numérico validado está na faixa de aceitação, sem sim a linha 43 é exe-cutada e o processamento do programa é retirado do laço seletivo definido entre as linhas de 35 a 50. No entanto, se esta condição for falsa o processamento continuará no laço e solicitará a repetição da entrada de um novo valor, mas antes confirmará se o valor é fora da faixa como indicado na linha 45 e sendo apresenta a mensagem da linha 46, re-tornando a ação para a linha 36. Este laço permanece4rá indeterminadamente em execução até que o usuário entre um valor que seja válido. Após o controle de aceitação de um valor correto o programa executa entre as linhas 52 e 58 o cálculo da tabuada e sua apresentação dentro do estilo tradicional efetuado pela linha 57. A linha 53 efetiva o cálculo da tabuada e as linhas de 54 a 56 preparam as variáveis de saída como campos de edição para a apresentação realizada na linha 57. Neste trecho é usado um laço iterativo. Concluída a apresentação da tabuada é realizado o tratamento das opções de continuidade ou não do programa usan-do um laço pós-teste com fluxo verdadeiro entre as linhas 60 e 69. A resposta fornecida a partir da linha 63 é validada com a tomada de decisão definida entre as linhas 64 e 67 quando verifica se a resposta fornecida é diferente de “S” ou de “N”. Qualquer resposta diferente das possíveis de aceitação faz com que o fluxo de processamento do programa seja retornado a linha 62 para que nova tentativa seja executada. Nesta etapa se a resposta fornecida como “S” faz com que o fluxo de processamento seja retornado a linha 35, mantendo-se o fluxo de nova apresentação de tabuada. Há um detalhe na linha 66 que é o uso de aspas simples para a apresentação da mensagem 'Entrada invalida! Entre apenas "S" ou "N".'. A linguagem COBOL aceita as duas formas de definição de cadeias de caracteres aspas simples e aspas inglesas. Normalmente aspas inglesas é a forma oficialmente usada e neste exemplo foi usada as aspas sim-ples por se desejar escrever na tela as sinalizações de sim (S) e não (N) entre aspas inglesas. Apesar de conhecida, vale lembrar o uso da instrução DISPLAY CR nas linhas 32, 49, 51, 59 e 68 que efetuam o avan-ço de uma linha em branco na tela. Para este efeito é usada a constante definida na linha 25 que determina o uso códi-go ASCII da tecla com o valor numérico hexadecimal 0D, ou seja,o valor decimal 13. Outro ponto a ser observado é que se ocorrer a entrada de algum valor numérico decimal para a variável WS-EN- TEXTO utilizando-se ponto não há com que se preocupar, pois o símbolo ponto e o restante do valor é automaticamen-te eliminado sendo considerada apenas a parte inteira do valor fornecido. O que comanda o estilo numérico da entrada AÇÃO IN/CONDICIONAL 131 é o formato estabelecido para a variável WS-EN-TEXTO no comando PICTURE da linha 13 sinalizado como 9(2) que determina a aceitação apenas de valores inteiros. Em linhas gerais o programa utilizou quase todos os recursos apresentados neste capítulo, demonstrando algumas técnicas de programação importantes como a validação da entrada de dados de um usuário impedindo que o programa avance com a ocorrência de erro. FATORIAL DE UM VALOR NUMÉRICO INTEIRO QUALQUER Elaborar programa de computador que efetue a entrada de um valor numérico inteiro entre 1 e 19 e apresente o resul- tado da fatorial do número fornecido. Para o desenvolvimento deste programa são usados recursos diferentes do anterior. Neste programa a multiplicação é realizada de forma descritiva utilizando um recurso do verbo MULTIPLY ainda não apresentado. Veja então o programa e seus detalhes. Selecione e defina um projeto do programa vazio com o nome c03ex12.cob na pasta COBOL da pasta Documentos. ------ LINHAS ------ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ------ -------A---B------------------------------------------------------------ 123456789012345678901234567890123456789012345678901234567890123456789012 ----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- IDENTIFICATION DIVISION. PROGRAM-ID. C03EX06 AS "Capitulo 3 – Exemplo 12". * DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-EN PIC 99. 77 AC-CI PIC 99. 77 AC-CFAT PIC 9(18) COMP. 77 AC-SI PIC Z9. 77 AC-SFAT PIC Z(18). 77 WS-ENTER PIC X. * PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. MOVE 1 TO AC-CFAT DISPLAY "Entre valor entre 1 e 19: " WITH NO ADVANCING. ACCEPT WS-EN. PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > WS-EN MULTIPLY AC-CI BY AC-CFAT ON SIZE ERROR DISPLAY "Erro, o valor informado e' muito grande - " WITH NO ADVANCING END-PERFORM. SUBTRACT 1 FROM AC-CI. MOVE AC-CI TO AC-SI. MOVE AC-CFAT TO AC-SFAT. DISPLAY FUNCTION TRIM(AC-SI) "! = " FUNCTION TRIM(AC-SFAT) DISPLAY X"0D". DISPLAY "Tecle para encerrar... " WITH NO ADVANCING. ACCEPT WS-ENTER. STOP RUN. ------------------------------------------------------------------------ Observe atentamente cada linha do código do programa apresentado. Execute o programa e forneça de imediato um valor maior que 19 e veja a mensagem de erro apresentada indicando o estouro do cálculo. 132 PROGRAMAÇÃO COBOL Neste programa há dois novos detalhes, não apresentados anteriormente: um é a frase ON SIZE ERROR definida na linha 19 e a função TRIM indicada na linha 26. A frase ON SIZE ERROR é encontrada junto aos recursos ADD, SUBTRACT, MULTIPLY, DIVIDE e COMPUTE, tendo por finalidade habilitar a emissão de mensagem quando ocorre estouro na capacidade numérica de valores decimais, de ponto flutuante e binários. Quando ON SIZE ERROR é omitido as mensagens de estouro para valores binários e decimais não são emitidas e as mensagens de estouro de ponto flutuante são ignoradas. A função TRIM tem a capacidade de retornar uma nova sequência de caracteres com base no conteúdo passado, re-movendo os espaços em branco existentes nas extremidades da cadeia. A função TRIM pode ser usada a partir das formas: DISPLAY "|" ' X ' "|". – mostra: | X | - com espaços DISPLAY "|" FUNCTION TRIM(' X ') "|". – mostra: |X| - sem espaços DISPLAY "|" FUNCTION TRIM(' X ' LEADING) "|". – mostra: |X | - sem espaços (esq.) DISPLAY "|" FUNCTION TRIM(' X ' TRAILING) "|". – mostra: | X| - sem espaços (dir.) Para auxiliar as ações da função TRIM é possível fazer uso dos modificadores LEADING (remoção de espaços à es- querda) e TRAILING (remoção de espaços à direita). O uso da função sem os modificadores remove os espaços exis-tentes tanto do lado esquerdo quanto do lado Direito. PROCESSAMENTO COM COLEÇÕES DE DADOS 133 Uma variável simples de certo tipo ocupa um bloco de memória onde seu valor será armazenado, enquanto uma variável composta ocupa um conjunto de blocos do tipo definido. Neste capítulo são apresentados o uso de agrupamento de dados em forma de coleções de dados, na forma de lista e tabelas a partir de estruturas de dados estáticas e dinâmicas. 4.1 COLEÇÃO DE DADOS Nos capítulos anteriores foram desenvolvidos programas que utilizaram variáveis simples. Uma variável simples arma-zena um só valor em seu escopo. No entanto, há situações em que é necessário armazenar mais de um valor de forma contígua na memória principal, sendo esta coleção de valores representada por uma mesma variável, neste caso, com- posta. Uma variável composta caracteriza- se por ser uma coleção de dados que tem por finalidade armazenar em seu escopo certa quantidade de elementos dispostos contiguamente na memória. A coleção é uma estrutura de dados que possui certa dimensão para armazenar em seus slots (posição de armazenamento) os valores a ela atribuído. Normalmente se chama de elemento o conteúdo de uma variável composta e de valor o conteúdo de uma variável simples. A dimensão máxima permitida em COBOL é sete. Na prática cotidiana é muito raro ter que trabalhar acima de três dimensões, existindo outras técnicas de programação para acomodar necessidades acima disto. As coleções de dados são por vezes referenciadas como: matrizes, arranjos (arrays), tabelas, vetores, listas, variáveis indexadas, variáveis dimensionadas ou como já indicado variáveis compostas. Nesta obra serão usados os termos lista para as coleções de dados de uma dimensão e tabela para as coleções de dados que usarem mais de uma dimensão, apesar dessas estru-turas serem chamada genericamente, em COBOL, de tabelas. A definição de coleções de dados é realizada na DATA DIVISION dentro de um item de grupo (código de item 01) que determina o nome da coleção. Dentro do item de grupo deve ser definido um item elementar numerado entre 02 e 49 que será a primeira dimensão da coleção. A partir da primeira dimensão pode-se abaixo dela definir um subitem para criar a segunda dimensão e assim sucessivamente até atingir a quantidade permitida de dimensões. De forma geral, não importando o tipo de coleção de dados em uso, seja uma lista ou uma tabela, sua definição pode ser realizada no GnuCOBOL em todas as seções pertencentes a DATA DIVISION. No entanto, pode ocorrer de certa forma escrita em uma determinada seção ser um pouco diferente da forma escrita para outra seção. Para a definição de uma coleção de dados usa-se a cláusula OCCURS e seus complementos, desde que não se use em conjunto na mes-ma variável a cláusula VALUES. A cláusula OCCURS possui, como forma geral, a estrutura sintática: OCCURS [TO ] [TIMES] [DEPENDING [ON] ] [ASCENDING | DESCENDING [KEY] [IS] ...] ... [INDEXED [BY] ...] PROCESSAMENTO COM COLEÇÕES DE DA- DOS 4 134 PROGRAMAÇÃO COBOL As palavras chave BY da frase INDEXED BY, IS, KEY, ON e TIMES são opcionais e podem ser a critério do profissio-nal de desenvolvimento omitidas. No entanto, por questões de legibilidade é adequado mantê-las. Mas é uma decisão de cunho pessoal. O parâmetro número1 é usado para definir otamanho de elementos que a tabela terá ou especificar o valor do primeiro elemento da tabela quando o parâmetro número2 é usado após TO e com. DEPENDING ON Na especificação de uma coleção de dados cada elemento ocupará na memória uma quantidade fixa de bytes, a menos quando se usa DEPENDING ON que permite criar áreas de armazenamento (slots) com tamanho variável. Quando usado ASCENDING KEY IS e DESCENDING KEY IS tem-se a capacidade de definir a ordem de organização interna dos elementos nas tabelas para uso exclusivo do comando SEARCH ALL. Quando usado INDEXED BY permite que se possa acessar aos elementos de uma tabela via índice especificado na forma de variáveis especiais definidas junto ao parâmetro identificador3. Um índice é uma forma de deslocamento de elementos a partir do início da tabela. Esta cláusula é indicada para uso com o comando SEARCH 4.2 ESTRUTURAS DE DADOS Uma estrutura de dados se caracteriza por ser uma coleção finita de dados, onde se conhece de antemão o número de elementos que a estrutura terá. Assim sendo, é possível criar coleções fechadas (internas) e/ou abertas (externas) de dados. São estruturas fechadas quando se define internamente no código os valores que a coleção conterá na forma de constantes e abertas quando o usuário de forma interativa fornece os valores de preenchimento da estrutura em uso. 4.2.1 Manipulação de listas Esse tipo de estrutura de dados é conhecido tipicamente como tabela de uma dimensão (lista) usada comumente na criação de lista simples de dados. A lista usa uma variável como referência, tendo a ela associado determinado tama- nho e pode armazenar mais de um elemento dentro do tamanho definido. O tamanho de uma lista é conhecido como dimensão, constituída por constantes inteiras e positivas. A definição de uma matriz unidimensional (lista) é declarada a partir da estrutura sintática: 01 . 02 PIC[TURE] OCCURS TIMES. Onde, lista é o nome de identificação da estrutura na memória definido como item de grupo; LIN é um nome de refe-rência genérico de acesso a posição do dado armazenado em cada linha da lista (as posições de armazenamento de uma coleção de dados chamam-se slots), sendo definido como item elementar (podendo-se usar valores de 02 até 49); formato é a definição do layout do dado a ser armazenado e número1 é a quantidade ordinal de elementos armazena-dos na lista. Os elementos de uma lista serão sempre do mesmo tipo de dados de forma homogênea. O qualificador TB e LIN indicados nos formatos TB- e - são, como comentado, opcionais e servem para auxiliar a referência interna, como documentação, de acesso aos dados da estrutura dentro do código de progra-ma. Considere, como exemplo a definição de uma lista de valores numéricos inteiros chamada “A” com a capacidade de armazenar cinco elementos numéricos, a partir do formato numérico unidade, dezena e centena, na qual devem ser informados pelo usuário os valores esperados. Na sequência os valores fornecidos devem ser apresentados. DATA DIVISION. WORKING-STORAGE SECTION. * Definicao da tabela A de inteiros 01 TB-A. * Definicao do slot (posicao na linha) de armazenamento de dados 02 A-LIN PIC 9(3) OCCURS 5 TIMES. PROCESSAMENTO COM COLEÇÕES DE DADOS 135 * Variáveis de apoio 77 AC-LIN PIC 9. 77 WS-S-TB-A PIC Z(3). PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. * Trecho de entrada de dados PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 5 DISPLAY "Entre " AC-LIN "o. elemento: " WITH NO ADVANCING ACCEPT A-LIN(AC-LIN) END-PERFORM. DISPLAY X"0D". * Trecho de saida de dados PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 5 MOVE A-LIN(AC-LIN) TO WS-S-TB-A DISPLAY "Elemento [" AC-LIN "] = " WS-S-TB-A END-PERFORM. Observe no trecho anterior a definição da tabela A com uma dimensão, tendo como nome de referência o rótulo TB-A e a definição dos campos para acesso aos dados A-LIN configurado para 5 posições de armazenamento. Para a leitura é estabelecido um laço iterativo controlado pela variável AC-LIN de 1 até 5. Nesta etapa, a ação executa- da pelo comando ACCEPT que faz com que cada entrada controlada por AC-LIN seja colocada na lista TB-A por meio da referência de A-LIN; para a saída é usado um laço nas mesmas definições do laço de entrada. Nesta etapa, cada valor existente na tabela TB-A é movimentado do slot (A-LIN) para o campo editado WS-S-TB-A que é apresentado na mesma ordem em que foram fornecidos. O acesso individualizado realizado sobre uma tabela por meio de parênteses nas operações de entrada e saída, bem como nas ações de processamento chama-se subscrição. Os valores subscritos podem variar de 1 até o limite estabe- lecido na cláusula OCCURS. Atente para o fato de ter sido definido um laço na entrada e outro laço completo na saída. Evite realizar as ações de entrada e saída em só laço, a menos que seja essa a real intenção. A figura 4.1 mostra a estrutura de uma lista. Tabela: TB-A TB-A-LIN Slot 1 TB-A-LIN Slot 2 TB-A-LIN Slot 3 TB-A-LIN Slot 4 TB-A-LIN Slot 5 Figura 4.1 – Estrutura de uma lista Considere, como exemplo a definição de uma lista de valores alfabéticos chamada “NOME” com a capacidade de ar-mazenar cinco nomes de pessoas, na qual devem ser informados pelo usuário os valores esperados. Na sequência os valores fornecidos devem ser apresentados. DATA DIVISION. WORKING-STORAGE SECTION. 136 PROGRAMAÇÃO COBOL 01 TB-NOME. 02 NOME-LIN PIC A(50) OCCURS 5 TIMES. 77 AC-LIN PIC 9. 77 WS-S-TB-NOME-LIN PIC Z(3). PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 5 DISPLAY "Entre " AC-LIN "o. nome: " WITH NO ADVANCING ACCEPT NOME-LIN(AC-LIN) END-PERFORM. DISPLAY X"0D". PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 5 DISPLAY "Elemento [" AC-LIN "] = " NOME-LIN(AC-LIN) END-PERFORM. O trecho de código anterior efetua a leitura de cinco nomes e os apresenta. Comparando-se os dois últimos trechos vê-se que são muito parecidos na ação lógica, mas possuem pequenos detalhes que fazem alguma diferença. Note que para o uso de entradas alfabéticas o código é mais suave que o trecho usado para a entrada de dados numéricos, que exigem certo grau de tratamento quando precisam ser apresentados. 4.2.2 Manipulação de tabelas Esse tipo de estrutura de dados é usado comumente na criação de tabela simples de dados. Uma tabela simples carac- teriza-se em ser uma estrutura de dados que distribui seus elementos na forma de linhas e colunas (isso quando for bidimensional). A tabela usa uma variável como referência, tendo a ela associado as posições de linhas e colunas, podendo armazenar mais de um elemento dentro do tamanho definido. No entanto, as tabelas podem ser expressas com mais de duas dimensões, estendendo-se até sete dimensões. A definição de uma matriz multidimensional (tabela) de duas dimensões é declarada a partir da estrutura sintática: 01 . 02 OCCURS TIMES 03 PIC[TURE] OCCURS TIMES. Onde, tabela é o nome de identificação da estrutura na memória definido como item de grupo; COL (colunas) e LIN (linhas) são referências genéricas de acesso ao dado armazenado em certa posição da tabela referenciando as posi- ções de linha e coluna; formato é a definição do layout do dado a ser armazenado e as indicações número1 são a quantidade ordinal de elementos armazenados na tabela a partir da quantidade estabelecida tanto para linhas, como para colunas. A primeira dimensão poderá ser numerada com qualquer valor entre 02 e 49, a segunda dimensão pode-rá usar qualquer valor entre 02 e 49, exceto o valor já usado na definição da primeira dimensão e assim por diante. Os elementos de uma tabela poderão ser formados pordados de tipos diversos (heterogêneos). Considere, como exemplo a definição de uma tabela de valores numéricos inteiros chamada “A” com a capacidade de armazenar seis elementos numéricos disposto em três linhas e duas colunas, a partir do formato numérico unidade, dezena e centena, na qual devem ser informados pelo usuário os valores esperados. Na sequência os valores forneci-dos devem ser apresentados. DATA DIVISION. WORKING-STORAGE SECTION. * Definicao da tabela A de inteiros 01 TB-A. PROCESSAMENTO COM COLEÇÕES DE DADOS 137 * Definicao das colunas da tabela 02 A-COL OCCURS 3 TIMES. * Definicao das linhas da tabela 03 A-LIN PIC 9(3) OCCURS 2 TIMES. * Variáveis de apoio as operacoes do programa 77 AC-COL PIC 9. 77 AC-LIN PIC 9. 77 WS-S-TB-A PIC Z(3). PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. PERFORM VARYING AC-COL FROM 1 BY 1 UNTIL AC-COL > 3 PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 2 DISPLAY "Entre o elemento [" AC-COL "," AC-LIN "] = " WITH NO ADVANCING ACCEPT A-LIN(AC-COL, AC-LIN) END-PERFORM END-PERFORM. DISPLAY X"0D". PERFORM VARYING AC-COL FROM 1 BY 1 UNTIL AC-COL > 3 PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 2 MOVE A-LIN(AC-COL, AC-LIN) TO WS-S-TB-A DISPLAY "Elemento [" AC-COL "," AC-LIN "] = " WS-S-TB-A END-PERFORM END-PERFORM. Observe no trecho anterior a definição da tabela A com duas dimensões, tendo como nome de referência o rótulo TB-A e a definição dos slots para acesso aos dados na coluna A-COL e na linha A-LIN configurados, respectivamente para 3 e 2 como posições de armazenamento. Atente para o fato de ter sido definido dois laços laço na entrada e saída de dados. O laço que usa AC-COL controla o posicionamento nas colunas e o laço que usa AC-LIN controla o posicionamento nas linhas. A figura 4.2 mostra a estru-tura da tabela bidimensional TB-A. Tabela: TB-A A-COL A-COL A-COL A-LIN Slot 1,1 Slot 2,1 Slot 3,1 A-LIN Slot 1,2 Slot 2,2 Slot 3,2 Figura 4.2 – Estrutura de uma tabela Tabelas de duas dimensões podem ser usadas na representação de dados heterogêneos onde cada coluna poderá ser formada por um conjunto de dados diferentes entre si. Considere como exemplo a definição de uma tabela que armazene os meses anuais na sua forma numérica e também por extenso. O trecho de programa a seguir gera automaticamente o número do mês na tabela, mas o valor por extenso deve ser fornecido pelo usuário. Observe os detalhes de definição da tabela. 138 PROGRAMAÇÃO COBOL DATA DIVISION. WORKING-STORAGE SECTION. 01 TB-MESES. 02 MESES-CONTEUDO OCCURS 12 TIMES. 03 MESES-NUM PIC 9(2). 03 MESES-EXT PIC A(9). 77 AC-LIN PIC 9(2). 77 WS-S-MES-NUM PIC Z(3). 77 WS-S-MES-EXT PIC A(9). PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 12 COMPUTE MESES-NUM(AC-LIN) = AC-LIN MOVE MESES-NUM(AC-LIN) TO WS-S-MES-NUM DISPLAY "Entre extenso do mes " WS-S-MES-NUM ": " WITH NO ADVANCING ACCEPT MESES-EXT(AC-LIN) END-PERFORM. DISPLAY X"0D". PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 12 MOVE MESES-NUM(AC-LIN) TO WS-S-MES-NUM MOVE MESES-EXT(AC-LIN) TO WS-S-MES-EXT DISPLAY WS-S-MES-NUM " - " FUNCTION UPPER-CASE(WS-S-MES-EXT) END-PERFORM. Observe que na tabela TB-MESES é definida sua primeira dimensão como TB-MESES-CONTEUDO e dentro da pri-meira dimensão são definidas duas colunas chamadas TB-MESES-NUM e TB-MESES-EXT que forma a segunda di-mensão. Veja que cada coluna pode armazenar apenas os dados de seu tipo, ou seja, cada coluna é em si homogê-nea, mas é possível combinar colunas de tipos de dados diferentes dentro de certa dimensão, tendo-se uma coleção de dados heterogêneos. A proposta define que as informações da coluna TB-MESES-NUM sejam geradas automaticamente. Neste sentido é que ocorre o uso da instrução COMPUTE TB-MESES-NUM(AC-LIN) = AC-LIN, aproveitando o próprio valor da conta-gem da variável AC-LIN como elemento de inserção do valor na posição da tabela. Os demais detalhes usados são já conhecidos. Para a definição de mais dimensões é necessário considerar sempre o uso de um laço a mais a cada dimensão dese- jada. A título de ilustração considere a definição de uma coleção de dados que represente uma tabela multidimensional com três dimensões a partir da sintaxe: 01 . 02 OCCURS TIMES 03 OCCURS TIMES 04 PIC[TURE] OCCURS TIMES. Uma tabela de três dimensões pode ser entendida como um conjunto de páginas (PAG), onde cada página possui uma tabela de duas dimensões (colunas, COL e linhas, LIN). Para exemplificar considere situação semelhante exposta no sítio http://www.pgrocer.net/Cis12/note23dm.html, aqui adaptada, em que haja uma tabela indicando os custos de tarifas telefônicas de quatro cidades a partir de uma cidade qualquer específica para as localidades de São Paulo, Rio de Janeiro, Minas Gerais e Goiás. A tabela em questão pre-cisa informar os custos diferenciados da manhã, da tarde e da noite para ligações de telefone móvel para telefone mó- vel (M >> M) ou fixo (M >> F) e de ligações de telefone fixo para telefone fixou (F >> F) ou móvel (F >> M). A figura 4.3 mostra a estrutura da tabela para as tarifas telefônicas. PROCESSAMENTO COM COLEÇÕES DE DADOS 139 TB-TARIFA Período: Manha Período: Tarde Período: Noite M >> M M >> F F >> F F >> M M >> M M >> F F >> F F >> M M >> M M >> F F >> F F >> M São Paulo 2,18 2,10 3,20 3,15 1,67 1,55 Rio de Janeiro 3,25 2,18 3,35 3,20 1,80 2,00 Minas Gerais 2,15 2,20 3,15 3,45 1,15 1,67 Goiás 2,20 2,30 3,25 3,28 1,20 1,98 Figura 4.3 – Tarifas telefônica com matriz tridimensional A partir da estrutura tridimensional da tabela indicada na figura 4.3, considere como página o período manhã, tarde e noite, como coluna a forma (status) de ligação M >> M / M >> F e F >> F / F >> M e linhas a indicação dos preços para cada cidade. A partir dessa consideração basta considerar a sintaxe: 01 TB-TARIFA. 02 TARIFA-PERIODO-PAG OCCURS 3 TIMES 03 TARIFA-STATUS-COL OCCURS 2 TIMES 04 TARIFA-PRECO-LIN PIC 9V99 OCCURS 4 TIMES. Para as operações de entrada, saída e eventualmente processamento para uso do estilo indicado na figura 1.3 serão necessários três laços, seguindo a sintaxe: PERFORM VARYING AC-PAG FROM 1 BY 1 UNTIL AC-PAG > 3 PERFORM VARYING AC-COL FROM 1 BY 1 UNTIL AC-COL > 2 PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 4 END-PERFORM END-PERFORM END-PERFORM. Observe que na definição das coleções de dados a cláusula PICTURE é apenas indicada na definição das linhas de qualquer tamanho de tabelas. 4.2.3 Listas e tabelas internas Nos dois subtópicos anteriores foram representados o uso de coleções de dados externas, ou seja, listas e tabelas que para serem usadas necessitam ser previamente preenchidas na etapa de entrada de dados, sendo uma ação útil no uso de coleções de dados imediatas. No entanto, há situações em que as coleções de dados devem estar prontas em memória na forma de estruturas fixas por serem definidas a partir de valores constantes e não necessitam, em absoluto, serem previamente informados para uso dentro do programa. A definição de coleções de dados internas é realizada em duas etapas. A primeira etapa refere-se à definição da rela-ção dos dados constantes que na segunda etapa são vinculados a coleção de dados estabelecidos. O vinculo entre a relação de dados constantes e a coleção de dados pode definido com a cláusulaREDEFINES, dependendo do padrão da linguagem COBOL em uso. A cláusula REDEFINES é usada quando há a necessidade de representar certa variável, seja um item de grupo ou item elementar, com dois ou mais layouts diferentes na DATA DIVISION. Este recurso não define uma nova área de memó-ria e sim faz uso da área de memória já definida, auxiliando no controle do consumo de espaço interno das memórias primária e secundária. No entanto, é fundamental atentar que quando se faz a redefinição de uma variável, não há entre a variável original e a variável redefinida nenhuma relação de equivalência, elas apenas usam a mesma área de memó-ria e neste sentido tanto o espaço original e redefinido devem possuir o mesmo layout de definição para seus tipos de dados. 140 PROGRAMAÇÃO COBOL Por exemplo, imagine um registro que armazene a data de calendário no formato 99/99/99, onde dia, mês e ano usam dois dígitos. O padrão usado no Brasil para datas é DD/MM/AA, onde DD é o dia, MM é o mês e AA é o ano, mas há no programa a necessidade de trabalhar a data no formato ANSI a partir da máscara AA/MM/DD. Observe no exemplo de redefinição de datas os pontos colorizados: DATA DIVISION. WORKING-STORAGE SECTION. 01 WS-DATA-BRA. 02 DIA-BRA PIC 99. 02 MES-BRA PIC 99. 02 ANO-BRA PIC 99. 01 WS-DATA-ANS REDEFINES WS-DATA-BRA. 02 ANO-ANS PIC 99. 02 MES-ANS PIC 99. 02 DIA-ANS PIC 99. Como comentado a redefinição de variáveis usa o mesmo espaço de memória. Desta forma, o registro WS-DATA-ANS tem seu primeiro campo definido como WS-ANO-ANS e estando este redefinido a partir do registro WS-DATA-BRA usa o mesmo espaço de memória destinado ao campo WS-DIA-BRA e por esta razão os campos redefinidos precisam possui os mesmo formatos, sob risco de usarem os dados de forma inconsistente. Veja uma situação de inconsistência. DATA DIVISION. WORKING-STORAGE SECTION. 01 WS-DATA-BRA. 02 DIA-BRA PIC 99. 02 MES-BRA PIC 99. 02 ANO-BRA PIC 9999. 01 WS-DATA-ANS REDEFINES WS-DATA-BRA. 02 ANO-ANS PIC 9999. 02 MES-ANS PIC 99. 02 DIA-ANS PIC 99. Observe que no caso anterior ocorrerá perda de dados entre o campo WS-ANO-BRA de WS-DATA-BRA em relação ao campo WS-DIA-ANS de WS-DATA-ANS pelo fato de usarem a mesma área de memória. A partir da visão de uso da cláusula REDEFINES e orientações sobre suas restrições fica fácil criar coleções de dados baseada em listas ou tabelas internas. Há duas formas básicas de definição de coleções de dados internas, uma clássi- ca com uso da cláusula REDEFINES de forma explícita usada até o COBOL-74 e outra moderna, pós COBOL-74 sem o uso da cláusula REDEFNIES de forma implícita, seguem como exemplos ambas as formas. No formato clássico a definição de coleções internas de dados segue o estilo de codificação: 01 TB-. 02 PIC VALUE . 02 REDEFINES OCCURS TIMES PIC . Onde, tab-interna é o nome de identificação da tabela interna na memória, lista-constante é o nome de referência para a lista de valores definidos, formato é a definição dos formatos dos tipos de dados listados, valores é a relação de valores constantes, campo é a definição da variável vinculada a tab-interna a ser usada para acessar os valores cons-tantes indicados em valores redefinida explicitamente a partir da lista-constante e número se refere a quantidade de valores existente na lista-constante. Como exemplo de forma clássica com o uso de REDEFINES, considere uma tabela interna com os nomes abreviados dos meses de calendário com uso explícito de redefinição de variáveis. PROCESSAMENTO COM COLEÇÕES DE DADOS 141 DATA DIVISION. WORKING-STORAGE SECTION. 01 TB-MES-EXTENSO. 05 MESES-ABRV PIC X(36) VALUE "JANFEVMARABRMAIJUNJULAGOSETOUTNOVDEZ". 05 MES REDEFINES MESES-ABRV OCCURS 12 TIMES PIC X(3). 77 AC-CI PIC 99. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 12 DISPLAY MES(AC-CI) END-PERFORM. Observe a definição da tabela interna TB-MÊS-EXTENSO contendo como coleção de dados os nomes abreviados dos meses "JANFEVMARABRMAIJUNJULAGOSETOUTNOVDEZ " associados ao campo MESES-ABRV redefinido expli-citamente com MES REDEFINES MESES-ABRV a partir da máscara X(3) que dá acesso a cada três caracteres dentro da lista de valores constantes definida com tamanho 13. Se multiplicar o valor 12 pelo valor de três caracteres da más-cara da variável MES ter-se-á resultado 36 que corresponde a máscara X(36) definida para o campo MESES-ABRV. Ao ser executado um programa com o trecho anterior os nomes dos meses abreviados serão apresentados de três em três caracteres. No formato moderno a definição de coleções internas de dados segue o estilo de codificação: 01 TB- VALUE . 02 OCCURS TIMES PIC . Como exemplo de forma moderna sem o uso de REDEFINES, considere uma tabela interna com os nomes abreviados dos meses de calendário com uso explícito de redefinição de variáveis. DATA DIVISION. WORKING-STORAGE SECTION. 01 TB-MES-EXTENSO VALUE "JANFEVMARABRMAIJUNJULAGOSETOUTNOVDEZ". 05 MES OCCURS 12 TIMES PIC X(3). 77 AC-CI PIC 99. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 12 DISPLAY MES(AC-CI) END-PERFORM. Apesar da forma moderna ser popular é muito comum encontrar programas escritos ao estilo clássico. Um profissional de desenvolvimento COBOL deve saber e dominar todas as formas existentes, pois a quantidade de programas escri-tos na linguagem é expressiva. Nos modelos anteriores de definição de coleção de dados internos foi usado um estilo em que todas as referências dos nomes abreviados dos meses estão contidas em uma só cadeia de caracteres. Apesar de ser uma forma prática ela pode tornar-se confusa se a coleção de dados interna for grande ou necessitar de definições de valores mais extensos e de tamanhos variados. Neste sentido, pode-se definir coleções de dados descritivas. A definição descritiva de dados é feita em uma tabela exclusiva separada da tabela que fará o acesso. Assim sendo, serão duas tabelas a serem vinculadas, e neste caso o uso da cláusula REDEFINES é obrigatório. 142 PROGRAMAÇÃO COBOL Para a definição de uma coleção de dados descritiva será usada a palavra FILLER que é uma forma de se fazer refe-rência a determinado campo da coleção de forma anônima, uma vez que nomes particularizados não são necessários. Como exemplo de definição de coleção descritiva, considere uma tabela interna com os nomes abreviados dos meses de calendário com uso explícito de redefinição de variáveis. DATA DIVISION. WORKING-STORAGE SECTION. 01 TB-MES-EXTENSO. 02 FILLER PIC X(3) VALUE "JAN". 02 FILLER PIC X(3) VALUE "FEV". 02 FILLER PIC X(3) VALUE "MAR". 02 FILLER PIC X(3) VALUE "ABR". 02 FILLER PIC X(3) VALUE "MAI". 02 FILLER PIC X(3) VALUE "JUN". 02 FILLER PIC X(3) VALUE "JUL". 02 FILLER PIC X(3) VALUE "AGO". 02 FILLER PIC X(3) VALUE "SET". 02 FILLER PIC X(3) VALUE "OUT". 02 FILLER PIC X(3) VALUE "NOV". 02 FILLER PIC X(3) VALUE "DEZ". 01 MESES-ABRV REDEFINES TB-MES-EXTENSO. 02 MES OCCURS 12 TIMES PIC X(3). 77 AC-CI PIC 99. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 12 DISPLAY MES(AC-CI) END-PERFORM. O resultado apresentado dos dois últimos trechos são os mesmos. A diferença fica a cargo da forma utilizada para a apresentação da coleção de dados com os valores constantes. As tabelas internas também podem ser referenciadas com elementos para multe dimensões. Considere tabela interna com as indicações dos valores numéricos dos meses de calendário eseus respectivos nomes abreviados. DATA DIVISION. WORKING-STORAGE SECTION. 01 TB-MES-EXTENSO. 02 FILLER PIC X(5) VALUE "01JAN". 02 FILLER PIC X(5) VALUE "02FEV". 02 FILLER PIC X(5) VALUE "03MAR". 02 FILLER PIC X(5) VALUE "04ABR". 02 FILLER PIC X(5) VALUE "05MAI". 02 FILLER PIC X(5) VALUE "06JUN". 02 FILLER PIC X(5) VALUE "07JUL". 02 FILLER PIC X(5) VALUE "08AGO". 02 FILLER PIC X(5) VALUE "09SET". 02 FILLER PIC X(5) VALUE "10OUT". 02 FILLER PIC X(5) VALUE "11NOV". 02 FILLER PIC X(5) VALUE "12DEZ". 01 MESES-ABRV REDEFINES TB-MES-EXTENSO. 02 CONTEUDO OCCURS 12 TIMES. PROCESSAMENTO COM COLEÇÕES DE DADOS 143 03 NUM PIC 9(2). 03 MES PIC A(3). 77 AC-CI PIC 99. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 12 DISPLAY NUM(AC-CI) " - " MES(AC-CI) END-PERFORM. Observe que no exemplo anterior os números dos meses e seus respetivos nomes abreviados são definidos dentro de uma mesma cadeia. A separação dos conteúdos de cada elemento é realizada após a redefinição da tabela desmem-brando os campos NUM com dois caracteres e MES com três caracteres. Como exemplo de definição de coleção de dados constantes na forma multidimensional considere o último exemplo do subtópico anterior em relação as definições das tarifas telefônicas e seus períodos de uso. Considere que cada valor da tabela é um fator multiplicativo que pode ser usado para calcular o valor de referência a ser pago. DATA DIVISION. WORKING-STORAGE SECTION. 01 TB-VALORES. 02 TARIFA-MANHA. 03 MANHA-MM-E-MF. 04 PARA-SP PIC S9V99 VALUE 2.18. 04 PARA-RJ PIC S9V99 VALUE 3.25. 04 PARA-MG PIC S9V99 VALUE 2.15. 04 PARA-GO PIC S9V99 VALUE 2.20. 03 MANHA-FF-E-FM. 04 PARA-SP PIC S9V99 VALUE 2.10. 04 PARA-RJ PIC S9V99 VALUE 2.18. 04 PARA-MG PIC S9V99 VALUE 2.20. 04 PARA-GO PIC S9V99 VALUE 2.20. 02 TARIFA-TARDE. 03 TARDE-MM-E-MF. 04 PARA-SP PIC S9V99 VALUE 3.20. 04 PARA-RJ PIC S9V99 VALUE 3.35. 04 PARA-MG PIC S9V99 VALUE 3.15. 04 PARA-GO PIC S9V99 VALUE 3.25. 03 TARDE-FF-E-FM. 04 PARA-SP PIC S9V99 VALUE 3.15. 04 PARA-RJ PIC S9V99 VALUE 3.20. 04 PARA-MG PIC S9V99 VALUE 3.45. 04 PARA-GO PIC S9V99 VALUE 3.28. 02 TARIFA-NOITE. 03 NOITE-MM-E-MF. 04 PARA-SP PIC S9V99 VALUE 1.67. 04 PARA-RJ PIC S9V99 VALUE 1.80. 04 PARA-MG PIC S9V99 VALUE 1.15. 04 PARA-GO PIC S9V99 VALUE 1.20. 03 NOITE-FF-E-FM. 04 PARA-SP PIC S9V99 VALUE 1.55. 04 PARA-RJ PIC S9V99 VALUE 2.00. 04 PARA-MG PIC S9V99 VALUE 1.67. 04 PARA-GO PIC S9V99 VALUE 1.98. 144 PROGRAMAÇÃO COBOL 01 TB-TARIFA REDEFINES TB-VALORES. 02 PERIODO OCCURS 3 TIMES. 03 TIPO-LIGACAO OCCURS 2 TIMES. 04 COEFICIENTE-MULT PIC S9V99 OCCURS 4 TIMES. 77 AC-PAG PIC 9. 77 AC-COL PIC 9. 77 AC-LIN PIC 9. 77 WS-S-VALOR PIC 9.99. Observe os detalhes usados na definição da coleção interna de valores com base na figura 1.3. Veja a seguir um trecho de código apenas para apresentação dos dados definidos na coleção de dados como tabela interna de três dimensões. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. PERFORM VARYING AC-PAG FROM 1 BY 1 UNTIL AC-PAG > 3 EVALUATE AC-PAG WHEN 1 DISPLAY "Periodo: Manha" WHEN 2 DISPLAY "Periodo: Tarde" WHEN 3 DISPLAY "Periodo: Noite" END-EVALUATE PERFORM VARYING AC-COL FROM 1 BY 1 UNTIL AC-COL > 2 EVALUATE AC-COL WHEN 1 DISPLAY "Movel para Movel ou para Fixo" WHEN 2 DISPLAY "Fixo para Fixo ou Movel" END-EVALUATE PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 4 EVALUATE AC-LIN WHEN 1 DISPLAY "SP = " WITH NO ADVANCING WHEN 2 DISPLAY "RJ = " WITH NO ADVANCING WHEN 3 DISPLAY "MG = " WITH NO ADVANCING WHEN 4 DISPLAY "GO = " WITH NO ADVANCING END-EVALUATE MOVE COEFICIENTE-MULT(AC-PAG, AC-COL, AC-LIN) TO WS-S-VALOR DISPLAY "Valor: " WS-S-VALOR END-PERFORM END-PERFORM DISPLAY X"0D" END-PERFORM. O uso de listas e/ou tabelas internas é uma forma interessante de estabelecer em um programa valores que ficam dis-poníveis para uso imediato. Um cuidado a ser tomado é com a definição de tabelas muito grandes, pois podem com- prometer o desempenho de um programa. Para esses casos é melhor trabalhar com dados gravados em memória se-cundária na forma de arquivos (tema que será apresentado mais adiante nesta obra). 4.3 AÇÕES COMPLEMENTARES A partir de uma visão geral sobre a concepção e uso básico de coleções de dados na forma de listas e tabelas, é inte- ressante ver algumas operações que podem ser realizadas com esses tipos de variáveis. Neste sentido, são apresen-tados recursos que facilitam o uso dessas estruturas de dados como ações de: inicialização, pesquisa, classificação e aplicação com campos variáveis. PROCESSAMENTO COM COLEÇÕES DE DADOS 145 4.3.1 Inicialização de variáveis As variáveis simples (itens elementares) ou compostas (itens de grupos na forma de tabelas ou registros) usadas nos programas podem ser inicializadas manualmente ou automaticamente com o uso de INITIALIZE. Quando se inicializa um item de grupo todos os seus itens subordinados serão também inicializados. O comando INITIALIZE inicializa variá-veis de acordo com a estrutura de dados que cada variável possui, tendo como estrutura sintática: INITIALIZE ... [[WITH] FILLER] [[ALL ] [TO] VALUE] [[THEN] REPLACING [ [DATA] BY [LENGTH [OF]] ] ... ] [[THEN TO] DEFAULT] As palavras chave WITH, TO, THEN, THEN TO, DATA e OF são opcionais e podem ser a critério do profissional de desenvolvimento omitidas, mas por questões de legibilidade é adequado mantê-las. O uso do comando INITIALIZE sem as cláusulas VALUE e REPLACING com ou sem a cláusula DEFAULT executa sua ação em modo padrão, em que as posições numéricas são inicializadas com zero e as posições alfabéticas e alfa-numéricas são inicializadas com espaços em branco. Se usada as cláusulas VALUE e REPLACING com a frase ALL TO VALUE todos os itens de dados na lista de campos com uma cláusula VALUE explícita definida em sua descrição ou implícita herdada de um item do grupo será inicializa-da em tempo de compilação. Caso haja a indicação ALL TO VALUE todos os itens de dados na lista de campos que se enquadram na categoria indicada e que tenham a cláusula VALUE explícita definida em sua descrição ou implícita herdada de um item do grupo será inicializada em tempo de compilação. Se usada apenas a cláusula RE- PLACING todos os itens de dados da lista de campos não inicializados como descrito anteriormente e que se enqua-dram na categoria indicada (NUMERIC, ALPHABETIC, ALPHANUMERIC, NUMERIC-EDITED ou ALPHANUMERIC- EDITED) serão inicializados com o valor indicado em identificador2. Quaisquer itens de dados inicializados por esta regra serão excluídos das demais regras. Se houver algum item não inicializado com as cláusulas VALUE e/ou RE- PLACING, e havendo a cláusula DEFAULT as posições numéricas serão inicializadas com zero e as posições alfabéti-cas e alfanuméricas com espaços em branco. Há três exceções em que não ocorre inicialização: itens contendo a cláusula REDEFINES, indexadores e campo anô-nimo FILLER. No caso de campos FILLER se estiver em uso a cláusula WITH FILLER ocorrerá ainclusão deste campo na ação de inicialização. Como ilustração considere a definição de duas variáveis como itens elementares e uma variável como item de grupo contendo três campos como itens elementares subordinados, todos inicializados com valores padrão. DATA DIVISION. WORKING-STORAGE SECTION. 77 WS-VALOR1 PIC 9 VALUE 1. 77 WS-VALOR2 PIC 9 VALUE 2. 01 WS-GRUPO. 02 WS-GRUPO-VALOR1 PIC A VALUE "A". 02 WS-GRUPO-VALOR2 PIC 9 VALUE 3. 02 WS-GRUPO-VALOR3 PIC 9 VALUE 4. Ao ser executada a apresentação das variáveis indicadas com o comando DISPLAY os valores 1, 2, A, 3 e 4 são apre-sentados como descrito em seguida. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY WS-VALOR1. DISPLAY WS-VALOR2. DISPLAY WS-GRUPO-VALOR1. DISPLAY WS-GRUPO-VALOR2. DISPLAY WS-GRUPO-VALOR3. 146 PROGRAMAÇÃO COBOL Agora se após a apresentação dos valores anteriores for definido o uso do comando INITIALIZE como indicado, ocorre-rá a destruição dos valores definidos. INITIALIZE WS-VALOR1, WS-VALOR2. INITIALIZE WS-GRUPO. DISPLAY WS-VALOR1. DISPLAY WS-VALOR2. DISPLAY WS-GRUPO-VALOR1. DISPLAY WS-GRUPO-VALOR2. DISPLAY WS-GRUPO-VALOR3. Ao ser executada a apresentação das variáveis indicadas com o comando DISPLAY os valores 0, 0, espaço em bran- co, 0 e 0 são apresentados como descrito em seguida. Outra maneira de inicializar variáveis é com o estabelecimento de valores predeterminados de inicialização. Observe os próximos detalhes. INITIALIZE WS-VALOR1 REPLACING NUMERIC DATA BY 9. INITIALIZE WS-VALOR2 REPLACING NUMERIC BY 8. INITIALIZE WS-GRUPO-VALOR1 REPLACING ALPHABETIC BY "X". INITIALIZE WS-GRUPO-VALOR2, WS-GRUPO-VALOR3 REPLACING NUMERIC BY 7. DISPLAY WS-VALOR1. DISPLAY WS-VALOR2. DISPLAY WS-GRUPO-VALOR1. DISPLAY WS-GRUPO-VALOR2. DISPLAY WS-GRUPO-VALOR3. Ao ser executada a apresentação das variáveis indicadas com o comando DISPLAY os valores 9, 8, X, 7 e 7 são apre- sentados como descrito em seguida. Além das formas apresentadas que podem ser usadas para inicializar variáveis de itens elementares e/ou de itens de grupo, tanto como variáveis simples como variáveis compostas é possível, também, fazer a inicialização de conteúdo a partir do uso da cláusula VALUE no momento da declaração da variável, sendo muito útil principalmente para a iniciali-zação de listas/tabelas. Observe em seguida definição de uma lista alfanumérica inicializada com o conteúdo "Teste 1" e alterada para o conte-údo "Teste 2". DATA DIVISION. WORKING-STORAGE SECTION. 01 TB-TEXTO. 02 WS-A PIC X(8) VALUE "Teste 1" OCCURS 3 TIMES. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. DISPLAY "Conteudo total: " TB-TEXTO. DISPLAY WS-A(1). DISPLAY WS-A(2). DISPLAY WS-A(3). INITIALIZE TB-TEXTO REPLACING ALPHANUMERIC BY "Teste 2". DISPLAY "Conteudo total: " TB-TEXTO. DISPLAY WS-A(1). DISPLAY WS-A(2). DISPLAY WS-A(3). PROCESSAMENTO COM COLEÇÕES DE DADOS 147 O trecho anterior mostra a definição da lista TB-TEXTO com o campo WS-A inicializado com o valor "Teste 1" em todos os slots no momento da definição da variável composta. Mas mostra a alteração de todas as suas posições com o uso do comando INITIALIZE. Um detalhe adicional é que este trecho mostra duas formas de exibir o conteúdo de uma cole- ção de dados: total a partir do nome da coleção, neste caso TB-TEXTO e isoladamente a partir do campo WS-A. 4.3.2 Classificação de dados Uma das ações mais requisitas em programação é a classificação de elementos em listas, tabelas e arquivos. Existem diversos algoritmos para a realização deste tipo de operação. No entanto, COBOL possui o comando SORT para efeti-var classificações. O comando SORT pode ser usado tanto em operações com arquivos como com tabelas. Neste mo-mento, será usado apenas na manipulação dos elementos de tabelas. O comando SORT possui de forma simplificada a estrutura sintática. SORT [[ON] [AS/DE|SCENDING] KEY ] A palavra-chave ON é opcional e pode ser a critério do profissional de desenvolvimento omitida, mas por questões de legibilidade é adequado mantê-las. O parâmetro campo deve possuir a cláusula OCCURS para que o comando SORT consiga operar sobre a estrutura de dados definida. O parâmetro campo-chave, se em uso faz referência ao campo de item elementar subordinado ao item de grupo que será usado para determinar por qual elemento a classificação será realizada. É possível fazer o uso de vários campos como campo-chave, bastando separá-los por vírgulas. Os dados do campo em uso serão classificados em memória a partir do campo-chave informado após KEY, podendo-se escolher a ordem de classificação ASCENDING (do menor para o maior) ou DESCENDING (do maior para o menor). No sentido de exemplificar o uso de classificação de dados numéricos inteiros considere um trecho de código que apre-sente uma sequência de dez valores numéricos com unidade, dezena e centena sorteados “automaticamente” entre 1 e 100 em uma tabela de uma dimensão (lista). O trecho de código indica a apresentação dos valores antes e depois da classificação. DATA DIVISION. WORKING-STORAGE SECTION. 01 TB-VALORES-NUMERICOS. 02 WS-NUMERO PIC 9(3) VALUE ZERO OCCURS 10 TIMES. 77 AC-CI PIC 99. 77 WS-S-NUMERO PIC ZZ9. 77 WS-S-CI PIC Z9. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10 COMPUTE WS-NUMERO(AC-CI) = (FUNCTION RANDOM * 100) + 1 END-PERFORM. PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10 MOVE WS-NUMERO(AC-CI) TO WS-S-NUMERO MOVE AC-CI TO WS-S-CI DISPLAY "NUMERO[" WS-S-CI "] = " WS-S-NUMERO END-PERFORM. DISPLAY X"0D". SORT WS-NUMERO ON ASCENDING. 148 PROGRAMAÇÃO COBOL PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10 MOVE WS-NUMERO(AC-CI) TO WS-S-NUMERO MOVE AC-CI TO WS-S-CI DISPLAY "NUMERO[" WS-S-CI "] = " WS-S-NUMERO END-PERFORM. Na PROCEDURE DIVISION é colocado em uso, logo no primeiro laço, a função RANDOM que tem por finalidade gerar valores pseudoaleatórios entre 0 e 1. Como se deseja obter valores entre 1 e 100 faz-se para o cálculo uso da expres-são aritmética COMPUTE WS-NUMERO(AC-CI) = (FUNCTION RANDOM * 100) + 1 que calcula um valor sorteado e armazena-o no campo WS-NUMERO da tabela TB-VALORES-NUMERICOS. O trecho apresentado quando executado sorteará sempre a mesma sequência de valores. Isto ocorre devido o fato da função RANDOM gerar valores pseudoaleatórios. Há uma forma de fazer com que os valores sorteados a cada execu-ção sejam diferentes, bastando associar a função RANDOM o timer do relógio interno da máquina. Este assunto será visto um pouco mais adiante neste capítulo. Assim que os valores são sorteados o segundo laço apresenta esses valo-res na ordem em que são estabelecidos para a coleção de dados. Antes do terceiro laço encontra-se a instrução SORT WS-NUMERO ON ASCENDING que efetua a classificação dos valores do campo WS-NUMERO na ordem ascendente (ASCENDING). O quarto laço apresenta então os valores organizados dentro da tabela. Como exemplo de classificação em tabelas com mais de uma dimensão, considere trecho de programa que a partir de uma tabela de duas dimensões contendo nomes, idades e as alturas de cinco pessoas apresente a tabela por ordem de nome. DATA DIVISION. WORKING-STORAGE SECTION. 01 TB-DADOS. 02 TB-PESSOAS OCCURS 5 TIMES. 03 NOME PIC A(40). 03 IDADE PIC 9(3). 03 ALTURA PIC 9V99. 77 AC-CI PIC 99. 77 WS-S-NOME PIC A(40). 77 WS-S-IDADE PIC ZZ9. 77 WS-S-ALTURA PIC 9.99. 77 WS-S-CI PIC Z9. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 5 MOVE AC-CITO WS-S-CI DISPLAY "Entre registro: " WS-S-CI DISPLAY X"0D" DISPLAY "Nome .....: " WITH NO ADVANCING ACCEPT NOME(AC-CI) DISPLAY "Idade ....: " WITH NO ADVANCING ACCEPT IDADE(AC-CI) DISPLAY "Altura ...: " WITH NO ADVANCING ACCEPT ALTURA(AC-CI) DISPLAY X"0D" END-PERFORM. DISPLAY X"0D". SORT TB-PESSOAS ON ASCENDING KEY NOME. DISPLAY "Listagem de dados" DISPLAY X"0D" PROCESSAMENTO COM COLEÇÕES DE DADOS 149 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 5 MOVE AC-CI TO WS-S-CI MOVE NOME(AC-CI) TO WS-S-NOME MOVE IDADE(AC-CI) TO WS-S-IDADE MOVE ALTURA(AC-CI) TO WS-S-ALTURA DISPLAY WS-S-CI " - " WS-S-NOME " | " WITH NO ADVANCING DISPLAY WS-S-IDADE " | " WS-S-ALTURA END-PERFORM. Ao ser executado o trecho anterior e após fornecer os dados solicitados será apresentada uma listagem com os nomes em ordem ascendente a partir do uso da instrução SORT TB-PESSOAS ON ASCENDING KEY NOME em que a tabela TB-PESSOAS é classificada a partir do campo NOME. Como experiência outras ações de classificação podem ser realizadas: SORT TB-PESSOAS ON ASCENDING KEY IDADE SORT TB-PESSOAS ON ASCENDING KEY IDADE, NOME A primeira forma anterior classifica os dados por ordem de idade e a segunda forma classifica os dados em ordem de idade e em idade em ordem de nome. Agora veja este efeito. SORT WS-PESSOAS ON ASCENDING KEY IDADE, DESCENDING KEY NOME Serão apresentados os dados classificados por idade em ordem crescente e os nomes em ordem descendente. 4.3.3 Pesquisas de dados Outra ação muito requisitada no desenvolvimento de programas é a possibilidade de realização de pesquisas em listas e tabelas. Neste sentido, COBOL disponibiliza o verbo SEARCH para buscas sequenciais (também referenciada como busca serial) ou verbo SEARCH ALL para buscas binárias. A busca sequencial para ser operacionalizada necessita de que se faça o posicionamento do ponteiro da coleção de dados no início da estrutura com o comando SET para que seja possível percorrer a coleção slot por slot até atingir o final da estrutura. A pesquisa binária não necessita do co-mando SET mas exige que a coleção esteja classificada. Os verbos SEARCH e SEARCH ALL possuem, de forma simplificada, a estrutura sintática. SEARCH | SEARCH ALL [AT] END WHEN ] ... [END SEARCH]. Um detalhe complementar é que as palavras-chave AT e END-SEARCHO são opcionais e podem a critério do profissi-onal de desenvolvimento serem omitidas, mas por questões de legibilidade, como orientado, é adequado mantê-las. O uso de SEARCH ou SEARCH ALL determina o modo de ação da pesquisa junto a coleção de dados em uso, sendo forma serial (sequencial) (serial) ou forma binária. Independentemente da forma sintática usada o resultado apresenta-do de SEARCH ou SEARCH ALL é semelhante. Ambos os comandos efetuam a pesquisa em um array (lista) ou tabela a partir do estabelecimento de certa condição citada após a cláusula WHEN (podendo-se utilizar várias cláusulas WHEN) e sendo a condição verdadeira, executa as instruções indicadas a partir de instrução-quando-verdadeira. Caso a condição seja falsa é executado o que estiver definido após AT END sinalizado como instrução-quando-falsa. Os comandos SEARCH e SEARCH ALL possuem como característica operacional serem definidos para a realização de ações de busca em campos de chaves primárias (campos em uma estrutura de dados que não possuam interna-mente dados que sejam repetidos). Caso existam campos com conteúdo semelhante a busca apresentada estará rela-cionada apenas a primeira ocorrência. 150 PROGRAMAÇÃO COBOL Para utilizar os comandos SEARCH e SEARCH ALL é necessário considerar o uso da cláusula INDEXED BY. No caso, do comando SEARCH ALL é necessário considera as cláusulas ASCENDING ou DESCENDING. Como exemplo de pesquisa sequencial com busca serial considere um trecho de programa que gerencie os dados de uma frutaria. A tabela interna do sistema deve considerar três campos: código da fruta, descrição da fruta e preço de venda para seis registros. Observe em seguida o trecho de código e principalmente as partes colorizadas. DATA DIVISION. WORKING-STORAGE SECTION. 01 TB-FRUTAS. 02 TB-FTS-REGISTRO OCCURS 6 TIMES INDEXED BY IX-DADOS. 03 TB-CODIGO PIC X(3). 03 TB-DESCRICAO PIC A(10). 03 TB-PRECO PIC 99V99. 77 WS-E-CODIGO PIC X(3). 77 WS-E-PRECO PIC Z9.99. 77 WS-S-IDX PIC 9. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. MOVE "505" TO TB-CODIGO (1). MOVE "Banana" TO TB-DESCRICAO (1). MOVE 3.45 TO TB-PRECO (1). MOVE "450" TO TB-CODIGO (2). MOVE "Mamao" TO TB-DESCRICAO (2). MOVE 2.12 TO TB-PRECO (2). MOVE "209" TO TB-CODIGO (3). MOVE "Maca" TO TB-DESCRICAO (3). MOVE 1.68 TO TB-PRECO (3). MOVE "150" TO TB-CODIGO (4). MOVE "Pera" TO TB-DESCRICAO (4). MOVE 1.33 TO TB-PRECO (4). MOVE "320" TO TB-CODIGO (5). MOVE "Ameixa" TO TB-DESCRICAO (5). MOVE 1.95 TO TB-PRECO (5). MOVE "420" TO TB-CODIGO (6). MOVE "Figo" TO TB-DESCRICAO (6). MOVE 10.95 TO TB-PRECO (6). DISPLAY "Entre o codigo: " WITH NO ADVANCING. ACCEPT WS-E-CODIGO. SET IX-DADOS TO 1. SEARCH TB-FTS-REGISTRO AT END DISPLAY "Codigo inexistente" WHEN WS-E-CODIGO = TB-CODIGO(IX-DADOS) MOVE TB-PRECO(IX-DADOS) TO WS-E-PRECO MOVE IX-DADOS TO WS-S-IDX PROCESSAMENTO COM COLEÇÕES DE DADOS 151 DISPLAY "Cod Descricao Preco - #" DISPLAY "----------------------------" DISPLAY "------------------------" DISPLAY TB-CODIGO (IX-DADOS) " - " TB-DESCRICAO (IX-DADOS) " - " WS-E-PRECO " - " WS-S-IDX END-SEARCH. Observe no trecho anterior o uso da cláusula INDEXED BY com a definição do índice IX-DADOS a ser usado na pes-quisa, sendo esta ação necessária para uso do comando SEARCH. O índice criado é uma tabela interna que permite o acesso direto aos registros da tabela de dados, tanto que a primeira ação antes de executar a pesquisa é garantir o posicionamento no primeiro registro dessa tabela com a instrução SET IX-DADOS TO 1, onde o comando SET é usado para colocar a partir do índice referenciado (IX-DADOS) o ponteiro (TO), neste caso, na posição 1. Vale salientar que é possível usar com SET qualquer valor de posicionamento entre o primeiro e último registros existentes. Ao fazer uma busca que seja localizada o trecho descreve a apresentação dos dados de código, descrição, preço e o número do registro que o dado apresentado se encontra dentro da tabela TB-FTS-REGISTRO. A partir de situação semelhante considere trecho de programa que efetua a pesquisa sob a ótica binária. Atente para os pontos colorizados indicando os detalhes a serem seguidos para este estilo de pesquisa. Para que a pesquisa binária seja possível é necessário tomar dois cuidados: primeiro que a tabela esteja previamente classificada; segundo que a ordem de busca da tabela seja a mesma ordem da classificação. Observe os detalhes colorizados DATA DIVISION. WORKING-STORAGE SECTION. 01 TB-FRUTAS. 02 TB-FTS-REGISTRO OCCURS 6 TIMES ASCENDING KEY TB-CODIGO INDEXED BY IX-DADOS. 03 TB-CODIGO PIC X(3). 03 TB-DESCRICAO PIC A(10). 03 TB-PRECO PIC 99V99. 77 WS-E-CODIGO PIC X(3). 77 WS-E-PRECO PIC Z9.99. 77 WS-S-IDX PIC 9.operacional sequencial com a efetivação das ações de entrada, processamento e saída. São estudados tipos de dados e seus comportamentos em memória, variáveis, constantes, operadores aritméticos, expressões aritméticas, uso de funções, tratamento das ações de entrada e saída, formatação de valores numéricos, regras sobre documentação interna de código e estruturação da tabulação e quebra de linhas. No capítulo 3 são apresentados os recursos de operação com ações condicionais e incondicionais, decisão, operadores relacionais, operadores lógicos, ações com detecção se sinal, reconhecimento de formato de caracteres, execução de laços condicional e incondicional, uso de desvio incondicional e divisibilidade, além de fornecer outros detalhes relacionados as operações de controle da linguagem como validação da entrada de dados. O capítulo 4 apresenta o uso de agrupamento de valores na forma de coleções de dados em estilo lista e tabelas a partir de estruturas de dados estáticas e dinâmicas (internas e externas). Este capítulo apresenta um estilo de trabalho onde os dados são manipulados na memória principal do computador. No capítulo 5 aborda-se o tratamento da organização interna do código, baseando-se o trabalho operacional na filosofia da programação estruturada. São apresentados neste capítulo assuntos relacionados a divisões em seções; uso de sub-rotinas internas e externas; reutilização de código; passagem de parâmetro por con- teúdo e referência; copybook; recursividade simples e recursividade em cauda. O capítulo 6 dá atenção a uso dos caracteres delimitados entre aspas simples ou aspas inglesas, chamados de cadeias de caracteres (strings). São apresentados os recursos que possibilitam executar a manipulação de concatenação, decomposição e inspeção de caracteres em variáveis alfabéticas e alfanuméricas. Apresenta- se neste capítulo definições para geração de dígitos verificadores, manipulação de datas e melhora na ação de validação de entrada de dados. No capítulo 7, o mais longo de todo o trabalho, é dado ênfase ao tratamento e armazenamento de dados em memória secundária: arquivos nativos. São apresentados o máximo de detalhamento possível sobre o tema, normalmente passado de forma superficial em vários livros de programação para a linguagem COBOL. Neste sentido são apresentados o uso de arquivos com organização sequencial, relativo e indexado com o uso dos modos de acesso sequencial, randômico e dinâmico. O último capítulo, número 8, aborda o tema relacionado a forma de comunicação que um programa tem com seu usuário. São abordados os modos de uso de relatórios escritos manualmente e por meio do modo escri- tor de relatórios criando-se relatórios simples, com quebras e com totalizações. O capítulo aborda os recursos para tratamento da disposição de elementos em tela. Antes de encerrar quero dizer que este foi um trabalho realizado desde o início, em seu rascunho, com a in- tenção de ser distribuído gratuitamente e eletronicamente (a menos que se queira adquiri-lo na forma impres- sa), diferentemente de outros livros que deixo a disposição no meu sítio pessoal (www.manzano.pro.br). Em- penhei o mesmo esforço e carinho em seu desenvolvimento como se estivesse sendo escrito para ser distri- buído comercialmente por qualquer editora especializada da área. Espero sinceramente ter conseguido for- necer um livro que venha auxiliar adequadamente sua aprendizagem. Quero manifestar que foram grandes os esforços empregados para escrever este material de forma independente. Foram muitas as horas de tra- balho. A todos um grande abraço e um excelente aprendizado! Augusto Manzano "Ignorar o COBOL é ignorar, entre outras coisas, a arte de programar computadores!" - Joel Saade (Maio de 1997) SOBRE O AUTOR José Augusto Navarro Garcia Manzano é brasileiro, nascido em São Paulo, capital em 26 de abril de 1965, possui formação acadêmica em Análise e Desenvolvimento de Sistemas, Ciências Econômicas e Licenciatura em Matemática. Atua na área de Tecnologia da Informação, Computação e Informática (desenvolvimento de software, ensino e treinamento) desde 1986. Participou do desenvolvimento de aplicações computacionais para áreas de telecomunicações e comércio. Na carreira de professor iniciou sua atividade docente primeira- mente em cursos livres, trabalhando posteriormente em empresas de treinamento e atuando desde então nos ensinos técnico e superior. Atualmente é professor com dedicação exclusiva no IFSP (Instituto Federal de Educação, Ciência e Tecnolo- gia de São Paulo, antiga Escola Técnica Federal). Em sua carreira desenvolveu competências e habilidades para ministrar componentes curriculares de Lógica de Programação (Algoritmos), Estrutura de Dados, Mi- croinformática, Informática, Linguagens de Programação Estruturada, Linguagens de Programação Orientada a Objetos, Engenharia de Software, Sistemas de Informação, Engenharia da Informação, Arquitetura de Computadores e Tecnologias Web. Possui conhecimento de uso de diversas linguagens de programação imperativas, descritivas e de marcação, tais como: BASIC (clássico e estruturado), COBOL, COMAL, Logo, Scratch, Assembly, Pascal, FORTRAN (77 e 90), C, C++, D, Java, F#, Modula-2, C#, Lua, HTML, XHTML, CSS, Javascript, VBA, Ada, Rust, Python, LISP, Haskell, Standard ML, OCaml, Miranda, Hope, Groovy, Julia e Elixir. Possui mais de cento e vinte obras publicadas, além de artigos no Brasil e exterior. COLABORADORES INTRODUÇÃO COM T-REX COBOL 23 Neste capítulo é apresentado de forma resumida o histórico de surgimento da linguagem COBOL, a motiva- ção de sua criação e evolução até os dias atuais, acompanhando as definições e crescimento dos padrões ANSI e ISO. Apresenta-se a ferramenta de desenvolvimento OpenCobolIDE, obtenção e instalação, bem como, a definição de algumas configurações mais importantes. Outro ponto importante é a apresentação das regras básicas de codificação da linguagem segundo sua estrutura sintática, os elementos componentes da linguagem e exemplos de aplicação com o uso de alguns recursos essenciais. 1.1 A LINGUAGEM A linguagem de programação para computadores COBOL (COmmon Business-Oriented Language) é uma linguagem de programação orientada a negócios comuns. Foi lançada no ano de 1961, tendo sido idealizada a partir de 1959 com o objetivo de ser uma linguagem voltada ao desenvolvimento de aplicações comerciais, principalmente para o gerenci-amento de aplicações financeiras. O principal objetivo de seu desenvolvimento foi ser uma linguagem única para ser usada em qualquer tipo de computador, pois as poucas linguagens de programação existentes, na época, eram direcio-nadas exclusivamente ao uso científico e matemático e muitas estavam associadas a um computador em específico. A linguagem caracteriza-se por pertencer ao paradigma imperativo: inicialmente dando suporte apenas a programação procedimental baseada no uso de sub-rotinas, mas desde o ano de 2002 dá suporte a programação orientada a obje-tos. Muitos gurus da tecnologia computacional previram seu desaparecimento, mas contínua em pleno uso, principal-mente em computadores de grande porte. COBOL é parcialmente baseada na linguagem de programação FLOW-MATIC projetada pela cientista da computação, professora do Vassar College e contra-almirante da Marinha dos Estados Unidos da América, Grace Hopper. A propósi-to a professora Hopper teve grande influência no desenvolvimento da linguagem COBOL. Durante a primavera de 1959 em uma conferência de dois dias chamada CODASYL (COnference on DAta Systems Languages - conferência sobre linguagens de sistemas de dados), a qual teve a participação da professora Hopper foi discutido o desenvolvimento de uma linguagem de programação que pudesse vir a ser utilizada como padrão em diver-sos computadores: desse esforço surgiu a linguagem COBOL, chamada posteriormente de COBOL-60. A professoraPROCEDURE DIVISION. PROG-PRINCIPAL-PARA. MOVE "505" TO TB-CODIGO (1). MOVE "Banana" TO TB-DESCRICAO (1). MOVE 3.45 TO TB-PRECO (1). MOVE "450" TO TB-CODIGO (2). MOVE "Mamao" TO TB-DESCRICAO (2). MOVE 2.12 TO TB-PRECO (2). MOVE "209" TO TB-CODIGO (3). MOVE "Maca" TO TB-DESCRICAO (3). MOVE 1.68 TO TB-PRECO (3). MOVE "150" TO TB-CODIGO (4). MOVE "Pera" TO TB-DESCRICAO (4). MOVE 1.33 TO TB-PRECO (4). MOVE "320" TO TB-CODIGO (5). MOVE "Ameixa" TO TB-DESCRICAO (5). MOVE 1.95 TO TB-PRECO (5). MOVE "420" TO TB-CODIGO (6). 152 PROGRAMAÇÃO COBOL MOVE "Figo" TO TB-DESCRICAO (6). MOVE 10.95 TO TB-PRECO (6). SORT TB-FTS-REGISTRO ON ASCENDING KEY TB-CODIGO. DISPLAY "Entre o codigo: " WITH NO ADVANCING. ACCEPT WS-E-CODIGO. SEARCH ALL TB-FTS-REGISTRO AT END DISPLAY "Codigo inexistente" WHEN WS-E-CODIGO = TB-CODIGO(IX-DADOS) MOVE TB-PRECO(IX-DADOS) TO WS-E-PRECO MOVE IX-DADOS TO WS-S-IDX DISPLAY "Cod Descricao Preco - #" DISPLAY "----------------------------" DISPLAY TB-CODIGO (IX-DADOS) " - " TB-DESCRICAO (IX-DADOS) " - " WS-E-PRECO " - " WS-S-IDX END-SEARCH. Observe inicialmente a definição da ordem de classificação ASCENDIG KEY para o comando SORT e para a definição da tabela após o a cláusula OCCURS. Caso deseje uma tabela com busca binária no sentido ascendente é necessário ajustar, não só a tabela, como também sua ordem de classificação. Veja que para utilizar o verbo SEARCH ALL não é necessário fazer uso da instrução SET IX-DADOS TO 1 como reali-zado com SEARCH, pois automaticamente SEARCH ALL coloca o ponteiro do índice no meio da tabela, seguindo o acesso de busca para frente ou para trás dependendo do dado pesquisado sempre dividindo ao meio o espaço restante na medida em que o dado desejado não é encontrado. O uso de SEARCH e SEARCH ALL requer atenção em um pequeno, mas importante detalhe. A condição usada após a cláusula WHEN, seja com SEARCH, SEARCH ALL ou EVALUATE somente pode ser operada com o uso do operador relacional de igualdade. Não é permitido fazer uso dos demais operadores relacionais. 4.3.4 Campos variáveis A definição de variáveis como formas de campos para acesso aos dados de entrada, processamento e saída são esta-belecidos com o uso do comando PICTURE que tem por finalidade definir o tipo de dado a ser usado e consequente- mente seu consumo de espaço em memória. No entanto, há ocasiões onde se é necessário definir um dado que se sabe seu tipo (numérico, alfabético ou alfanumérico), mas não se sabe ao certo quanto de espaço deve este dado ocu-par memória. Neste sentido, pode-se fazer uso da definição de campos em tabelas dinâmicas cujo tamanho do campo é por sua natureza variável. A definição de campos variáveis em tabelas dinâmicas é realizada com o uso das cláusulas TO e DEPENDIG ON. Para exemplificar este uso considere o trecho de código seguinte que visa apresentar um gráfico de barras formado por asteriscos a partir da quantidade de itens vendidos, até o máximo de dez unidades permitidas por clientes. Atente para as partes colorizadas DATA DIVISION. WORKING-STORAGE SECTION. 01 TB-FRUTAS. 02 TB-FTS-REGISTRO OCCURS 6 TIMES. 03 TB-CODIGO PIC X(3). 03 TB-DESCRICAO PIC A(10). 03 TB-QUANT PIC 9(2). PROCESSAMENTO COM COLEÇÕES DE DADOS 153 01 TB-GRAF 02 FILLER OCCURS 1 TO 10 TIMES DEPENDING ON WS-E-QUANT. 03 FILLER PIC X VALUE "*". 77 WS-E-QUANT Z(4)9. 77 WS-S-IDX PIC 9. 77 AC-CI PIC 9. PROCEDURE DIVISION. PROG-PRINCIPAL-PARA. MOVE "505" TO TB-CODIGO (1). MOVE "Banana" TO TB-DESCRICAO (1). MOVE 3 TO TB-QUANT (1). MOVE "450" TO TB-CODIGO (2). MOVE "Mamao" TO TB-DESCRICAO (2). MOVE 9 TO TB-QUANT (2). MOVE "209" TO TB-CODIGO (3). MOVE "Maca" TO TB-DESCRICAO (3). MOVE 5 TO TB-QUANT (3). MOVE "150" TO TB-CODIGO (4). MOVE "Pera" TO TB-DESCRICAO (4). MOVE 7 TO TB-QUANT (4). MOVE "320" TO TB-CODIGO (5). MOVE "Ameixa" TO TB-DESCRICAO (5). MOVE 10 TO TB-QUANT (5). MOVE "420" TO TB-CODIGO (6). MOVE "Figo" TO TB-DESCRICAO (6). MOVE 6 TO TB-QUANT (6). SORT TB-FTS-REGISTRO ON ASCENDING KEY TB-CODIGO. DISPLAY "Cod Descricao Quant Grafico" DISPLAY " -------------------------------------" PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 6 MOVE TB-QUANT(AC-CI) TO WS-E-QUANT DISPLAY TB-CODIGO (AC-CI) " | " TB-DESCRICAO (AC-CI) " | " WS-E-QUANT " | " TB-GRAF END-PERFORM. DISPLAY "-------------------------------------" O primeiro detalhe a ser observado no trecho de código é a definição da tabela dinâmica TB-GRAF que possui a defini-ção de uma coluna anônima FILLER OCCURS 1 TO 10 TIMES DEPENDING ON WS-E-QUANT com a capacidade de armazenar de 1 até 10 caracteres alfanuméricos dependendo do valor indicado para a variável WS-E-QUANT. A coluna anônima por sua vez possui um campo anônimo FILLER PIC X VALUE "*" que determina o espaço de um byte (carac-tere) alfanumérico inicializado com o símbolo de asterisco. O valor da variável WS-E-QUANT determinará a quantidade de bytes a ser alocado na memória, não podendo exceder 10. Um detalhe importante, a cláusula TO é usada obrigatoriamente em conjunto com a frase DEPENDING ON para deter-minar a quantidade mínima e máxima de memória a ser usada. O número de ocorrências de uso de memória será con-trolado dinamicamente quando o programa estiver em execução. No trecho que efetua a apresentação dos dados há a indicação de uso da tabela TB-GRAF que possui internamente a definição do símbolo de asterisco que está vinculado ao valor estabelecido na variável WS-E-QUANT. É por esta razão que se faz uso da instrução MOVE TB-QUANT(AC-CI) TO WS-E-QUANT que carrega a variável WS-E-QUANT com os 154 PROGRAMAÇÃO COBOL valores de quantidades vendidas de cada produto gerando a quantidade equivalente de asteriscos para composição do gráfico de barras. Além do efeito dinâmico apresentado a variável WS-E-QUANT da tabela TB-GRAF está sendo usada para definir um vínculo com a tabela TB-FRUTAS a partir da sua relação com o campo TB-QUANT. 4.3.5 Aleatoriedade variável É patente a necessidade de se fazer uso de valores aleatórios em programação, muitas vezes relacionados a efetiva- ção de ações de simulação. O grande problema neste sentido, como já deve ter sido observado neste capítulo é apre-sentação de valores aleatórios “viciados”, ou seja, valores que se repetem sempre mesmo quando se executa o pro-grama em momentos diferentes. Esse efeito ocorre devido ao fato de os computadores por nós usados não operam com valores verdadeiramente aleatórios. A geração de valores aleatórios, precisamente pseudoaleatórios, é conseguido com o uso de funções internas disponi- bilizadas normalmente pela linguagem em uso. Por melhor que seja os algoritmos matemáticos usados para gerar valo-res pseudoaleatórios sempre ocorrerá a geração dos mesmos valores, mesmo que o algoritmo seja executado em mo-mento distintos. Isso pode ser facilmente contatado, basta colocar em execução o trecho de código descrito no subtópi-co 4.3.2. No entanto, há uma forma de aumentar a variedade de geração de valores pseudoaleatórios em COBOL, bastado fazer uso da função intrínseca RANDOM() antes de usar a função RANDOM. A função RANDOM com parênteses necessita para ser usada da definição de um valor numérico, sua semente, como parâmetro.Hopper sempre acreditou que as linguagens usadas na programação de computadores deveriam ser se-melhantes e o mais próximo possível do idioma inglês, sendo COBOL o grande exemplar da crença de Hopper tendo-a como grande influenciadora em seu desenvolvimento. Desde seu lançamento a linguagem passou por diversas revisões e mudanças, buscando corrigir bugs ou ampliar fun-cionalidades operacionais. Uma linguagem de programação não tem tanta atenção se não mostrar um mínimo de inte- resse da comunidade computacional. Entre os anos de 1961 e 1965 ocorreram três revisões da linguagem. A edição COBOL-60 foi substituída em 1961 pela edição COBOL-61, em 1963 surge a edição COBOL-61 Extended, que posteriormente em 1965 é substituída pela edi-ção COBOL-65. Nesse interim já existiam alguns dialetos da linguagem sendo utilizados, o que começou a dificultar seu 1 COBOL 24 PROGRAMAÇÃO COBOL uso e manutenção nas organizações, pois cada fabricante de computador colocava na linguagem o que julgava neces-sário ela ter, descaracterizando por completo seu objetivo inicial. No início de 1968 são iniciados os esforços de padronização da linguagem para mitigar os problemas de incompatibili-dade entre as diversas versões COBOL que estavam em uso nos diferentes fabricantes de computadores. Foi neste período que o instituto ANSI (American National Standards Institute - instituto nacional americano de padrões) produziu a primeira norma da linguagem referenciada como USA COBOL X3.23 em agosto de 1968 (ANSI COBOL 68). No ano de 1970 a linguagem COBOL tornou-se a linguagem de programação mais usada em todo o mundo o que levou a ampliação de seus recursos culminando em 1974 no surgimento do padrão COBOL-74 - ANSI COBOL 74 X 3.23 (ou COBOL ANSI-74). Em meados de 1978 são iniciados os trabalhos de revisão do padrão COBOL-74 que resultou na definição do padrão COBOL-85 (ISO 1989:1985) publicado no final de 1985, posteriormente revisado e retificado em 1989 e 1993. No início de 1990 foram iniciados os trabalhos de inclusão de orientação a objetos. Os recursos incluídos foram basea-dos a partir dos recursos encontrados nas linguagens de programação C++, Eiffel e Smalltalk. Este trabalho foi concluí-do em 20 de novembro de 2002 sendo referenciado como COBOL-2002 (ISO/IEC 1989:2002). O padrão COBOL-2002 não foi muito bem sucedido passando por três revisões, sendo duas no ano de 2006 e outra no ano de 2009. Nenhum dos compiladores existentes suportava completamente este padrão, o que culminou em outras mudanças que levaram ao surgimento do padrão COBOL-2014 (ISO/IEC 1989:2014) lançado em 26 de abril de 2014 estando este atualmente em vigor. COBOL foi desenvolvida para gerenciar operações em grandes computadores, mas com o surgimento dos microcompu-tadores durante os anos 1970 acabou sendo portada para este tipo de máquina. Na ocasião esses pequenos computa-dores de 8 bits rodavam alguma versão da linguagem COBOL implementada pela empresa Micro Focus e distribuída pela empresa Microsoft sob o sistema operacional CP/M. Com o lançamento dos microcomputadores IBM, padrão PC (Personal Computer – computador pessoal) de 16 bits em 1980 não demorou para que a linguagem COBOL fosse por-tada para esta plataforma sob o sistema operacional MS-DOS. Com a evolução dos microcomputadores para 32 bits e posteriormente para 64 bits surgiram diversos outros fornecedo-res para a linguagem COBOL, pois a empresa Microsoft deixou de fornecer esta opção ao mercado em 1992. Um com- pilador COBOL comercial, muito popular, é o Visual COBOL da empresa Micro Focus (https://www.microfocus.com). Já no mundo open source há como opção o compilador GnuCOBOL que pode ser usado, por exemplo, a partir do ambien-te integrado de desenvolvimento OpenColbolIDE (https://pypi.org/project/OpenCobolIDE). 1.2 FERRAMENTAS DE TRABALHO O programa GnuCOBOL é uma implementação livre da linguagem COBOL com suporte seletivo aos padrões COBOL 85, COBOL 2002, COBOL 2014, IBM COBOL, MVS/VM COBOL, BS2000 COBOL, Micro Focus COBOL, ACULCOBOL-GT, além de seu próprio modo padrão de operação, não dando suporte a POO até o momento de publicação deste trabalho. Foi inicialmente escrito por Keisuke Nishida em linguagem de programação C e lançado em 20 de janeiro de 2002 com o nome de OpenCOBOL. É mantido, atualmente, por Bernard Giroud, Brian Tiffin e Simon Sobisch, tendo tido a colaboração de Roger While (1950-2015). O programa OpenCobolIDE é um ambiente de desenvolvimento integrado, escrito em Python com Qt totalmente direci-onado ao uso do compilador GnuCOBOL, produzido por Céline Thiry, Colin Duquesnoy, Gatien Bovyn, Simon Sobisch e Vlinhart e mantido pela Python Software Foundation. Os programas GnuCOBOL e OpenCobolIDE podem ser executados nos sistemas operacionais Linux, Windows e mac OS. A maneira mais fácil de obtê-los para o sistema operacional Windows é a partir de um único pacote instalável for- necido na plataforma Launchpad. Acesse o endereço https://launchpad.net/cobcide e observe junto a figura 1.1 a página apresentada. Para uso no sistema operacional mac OS há disponível a versão 4.7.4 a partir do endereço Web https://launchpad.net/cobcide/4.0/4.7.6. Ao lado direito da página indicada na figura 1.1, na seção Downloads junto a área Latest version is 4.7.6 há a indica-ção de quatro pacotes de instalação, sendo um para o sistema operacional Windows, dois para o sistema operacional Linux (em formato deb para Ubuntu e rpm para Fedora) e um pacote contendo o código fonte. Como o objetivo deste livro é o uso do sistema operacional Windows, selecione o pacote: OpenCobolID...6_Setup.exe. COBOL 25 Assim que o programa de instalação for copiado. Vá até a pasta em que o programa está e selecione com um duplo clique do ponteiro do mouse o arquivo OpenCobolIDE-4.7.6_Setup.exe para que o programa de instalação seja inicia-do. A figura 1.2 mostra a imagem do modo de ação de segurança (se esta estiver configurada) solicitando autorização de execução. Neste momento acione o botão Executar Figura 1.1 – Plataforma Launchpad Figura 1.2 – Aviso de segurança Será apresentada a caixa de diálogo de controle de aces-so a conta de usuário, acione o botão Sim. Na sequência surge a caixa de diálogo Setup - OpenCobolIDE (Li- cense Agreement) com os termos da licença de uso do programa como indica a figura 1.3. Ao concordar com os termos da licença acesse a opção I accept the agrément e acione em seguida o botão Next. A caixa de diálogo Setup - OpenCobolIDE (Select Des- tination Location) apresenta o local onde a instalação será realizada como mostra a figura 1.4. Não há necessi-dade de alterar o local de instalação do programa, a me- nos que se queira. Assim sendo, acione o botão Next. A caixa de diálogo Setup - OpenCobolIDE (Select Start Menu Folder) apresenta junto a figura 1.5 a referência de acesso pela qual o programa será relacionado ao menu de seleção do ambiente operacional Windows. Não é necessá-rio produzir alteração alguma. Basta então acionar o botão Next. Ao ser apresentada a caixa de diálogo Setup - OpenCobolIDE (Select Additional Tasks) como mostra a figura 1.6, marque a caixa de seleção Create a desktop shortcut para que um ícone de acionamento do programa seja criado na área de trabalho do sistema operacional e na sequência acione o botão Next. Será indicada a caixa de diálogo Setup - OpenCobolIDE (Ready to Install) como mostra a figura 1.7 contendo o resu-mo das opções anteriormente ajustadas e selecionadas. Se desejar alterar alguma opção basta acionar o botão Back e refazer as opções já selecionadas ou se estiverem em ordem basta acionar o botão Next para que o processo de insta- lação seja iniciado. 26 PROGRAMAÇÃO COBOL Figura 1.3 – Licence Agreement Figura 1.4 – Select Destination Location Figura 1.5 – Select Start Menu Folder Figura 1.6 – Select Additional Tasks Aguarde a conclusão do processo completo de instalação indicado junto a figura 1.8 a partir da apresentação da caixa de diálogo Setup -OpenCobolIDE (Installing). Esta é uma operação que poderá, dependendo do computador em uso, demorar um pouco, até ser concluída. Figura 1.7 – Ready to Install Figura 1.8 – Installing Terminada a instalação será apresenta a caixa de diálogo Setup - OpenCobolIDE (Completing the OpenCobolIDE Setup Wizard) como mostra a figura 1.9. Neste momento desmarque a seleção Launch OpenCobolIDE e em seguida acione o botão Finish. COBOL 27 Figura 1.9 – Completing the OpenCobolIDE Setup Wizard A partir deste instante o programa OpenCobolIDE está instalado em seu sistema e pronto para uso. O uso do progra-ma será efetuado com o acionamento do ícone definido junto a área de trabalho do ambiente operacional, mas antes de proceder qualquer ação crie na pasta Documentos do seu usuário a pasta COBOL. Esta pasta será usada para arma-zenar os códigos criados neste livro. 1.3 OPENCOBOLIDE Como comentado, o programa OpenCobolIDE é um ambiente integrado de desenvolvimento básico para uso da lin-guagem COBOL. Apesar de simples, este ambiente possui os recursos necessários para operar a linguagem a partir do compilador GnuCOBOL com bastante comodidade tanto no modo formulário fixo como formulário livre. Neste trabalho será considerado apenas o uso de códigos escritos no modo formulário fixo. Para acessar e usar o ambiente, selecione na área de trabalho do sistema operacional Windows com um duplo clique do ponteiro do mouse o ícone OpenCobolIDE. Será então apresentada a tela de splash do programa como mostra a figura 1.10. Figura 1.10 – Tela inicial do programa OpenCobolIDE Para iniciar o uso do ambiente pode-se selecionar o botão New file para criar um novo programa ou usar o botão Open file para carregar um programa já existente. A área Recent files mostra os últimos programas editados, o botão Pref- erences abre a caixa de diálogo de configuração e o botão About apresenta a janela de créditos. Inicialmente acione o botão New file e será apresentada a caixa de diálogo New file como indica a figura 1.11. Nesta caixa de diálogo é possível definir o Template de uso de um programa (Program, Module ou Empty), o nome do pro-grama definido junto ao campo Name e selecionar extensões válidas de identificação de programa COBOL (CBL, COB, LST, PCO, SCB ou SQB). É possível definir no campo Directory a pasta onde os programas editados serão gravados. 28 PROGRAMAÇÃO COBOL Para um teste operacional selecione no campo Template a opção Empty (vazio). No campo Name escreva a identifica-ção c01ex01 (capítulo 1, exemplo 1) e selecione a extensão cob. No campo Directory selecione a pasta COBOL defi-nida anteriormente dentro da pasta Documentos. Sua caixa de diálogo New file deverá ficar idêntica a figura 1.12. Ao final acione o botão OK. Figura 1.11 – Caixa de diálogo New file – modo padrão Figura 1.12 – Caixa de diálogo New file – modo editado Assim que o botão OK da caixa de diálogo New file é acionado é apresentada a tela de operação e edição do progra-ma como mostra a figura 1.13. Figura 1.13 – Tela de edição do ambiente OpenCobolIDE. A tela do programa é dividida em algumas áreas a serem conhecidas. No topo da janela encontra-se a barra de título identificada com o texto c01ex01.cob [C:\Users\Manzano\Documents\COBOL\c01ex01.cob]- OpenCobolIDE 4.7.6. Abaixo da barra de título encontra-se a barra de menu (File, Edit, View, COBOL e ?) e a barra de ferramentas com os ícones de ação para oito botões dispostos da esquerda para a direita: New file (primeiro botão) – usado para criar um novo arquivo de programa a partir da caixa de diálogo New file. Esta ação pode ser produzida com o comando de menu File/New (ou pelo atalho: CTRL + N); Open a file (segundo botão) – usado para carregar um arquivo de programa existente a partir da caixa de diálogo Open a file. Esta ação pode ser produzida com o comando de menu File/Open (ou pelo atalho: CTRL + O); Save the current editor (terceiro botão) – usado para gravar o programa atual com o mesmo nome definido para a edição. Esta ação pode ser produzida com o comando de menu File/Save (ou pelo atalho: CTRL + S); Save the current editor as (quarto botão) – usado para gravar o programa atual com um novo nome de identifica-ção. Esta ação pode ser produzida com o comando de menu File/Save as (ou pelo atalho: CTRL + SHIFT + S); Compile the current editor (quinto botão) – usado para realizar a compilação de um programa permitindo a sele- ção das opções Executable para compilar um programa executável ou Module para compilar um módulo de biblio-teca. Esta ação pode ser produzida com o comando de menu COBOL/Program type para selecionar o modo de compilação e produzida com o comando de menu COBOL/Compile (ou pelo atalho: F8); COBOL 29 Clean (sexto botão) – usado para limpar o estado de compilação e reabilitar a operação do quinto botão. Esta ação pode ser produzida com o comando de menu COBOL/Clean (ou pelo atalho: CTRL + ALT * C); Rebuid (sétimo botão) – usado para recompilar o programa em edição. Esta ação pode ser produzida com o co- mando de menu COBOL/Rebuild (ou pelo atalho: SHIFT + F8); Run the current editor program (oitavo botão) – usado para executar um programa em edição que fora compila-do. Esta ação pode ser produzida com o comando de menu COBOL/Run (ou pelo atalho: F5). Abaixo da barra de ferramentas estão as áreas de operação do programa: à esquerda está a janela File system, ao centro está a janela do formulário com as barras vermelhas e ao lado direito está a janela Navigation. As janelas File system e Navigation podem ser removidas ou reapresentadas no programa com o acionamento do botão X em suas respectivas barras de título ou a partir do uso da opção Windows do menu View. Abaixo das áreas de operação do programa encontra-se a barra de status indicando ao lado esquerdo o local e pro-grama em uso C:\Users\Manzano\Documents\COBOL\c01ex01.cob, do lado direito indicando o acionamento ou não do botão Enable/disable linter (backgroud check) usado para fixar ou não o caminho de acesso ao compilador (dei-xe-o ativado), o campo Free format que permite definir o modo de edição em estilo fixo ou estilo livre para a codificação COBOL, a indicação 1:1 referente a linha e coluna em que o cursor esteja e o padrão de codificação de caracteres em uso cp1252 para o modo Windows-1252 (Western) que pode ser alterado com Edit/Active Editor/Encodings. A fim de conhecer a opção program na definição de um programa execute o comando de menu File/New ou acione o botão da barra de ferramentas New file. Man-tenha o campo Template com a opção Program ativa-da, no campo Name defina c01ex02, selecione a exten-são cob e escolha em Directory a pasta COBOL da pasta Documentos. Deixe essas opções idênticas a imagem da figura 1.14 e acione o botão OK. Assim que o botão OK é acionado o ambiente do pro-grama mostra para o modo Program um programa que tem por finalidade apresentar “Hello world”, codificado no modo formulário fixo, como mostra a figura 1.15. Figura 1.14 – Caixa de diálogo New file – template program Observe atentamente, neste momento, a janela File system contendo a indicação dos programas codificados e a jane-la Navigation indicando os pontos de definição do programa, separando esses pontos em áreas de acesso. O estilo de codificação fixa é a forma tradicional de se escrever códigos de programas COBOL. Neste estilo, as instru-ções do programa são escritas a partir da oitava coluna e podem ser definidas até a septuagésima segunda coluna. Nenhuma instrução COBOL poderá ser escrita após a septuagésima segunda coluna, pois o compilador simplesmente as ignora. Da primeira a sexta coluna o que for escrito é ignorado pelo compilador e servirá apenas para referência (mais adiante esses detalhes são apresentados em maiores detalhes). A sétima coluna do formulário é usada para o estabelecimento de alguns caracteres especiais, destacando-se o uso do asterisco para a definição de linha de comentários (detalhessobre estas características são apresentados mais adiante). Não se preocupe em entender o código apresentado. Isso será providenciado durante todo o texto deste trabalho. Para experimentar a ação de compilação do programa, acione a partir da barra de ferramentas o botão Compile de current editor e será apresentada a janela Logs no meio da tela abaixo da janela de edição como mostra a figura 1.16. Veja que na figura 1.16 a janela Logs possui três guias de informação. A guia ativa é a Issues contendo a apresenta-ção do resultado da compilação que neste caso foi bem sucedida. Se nesta etapa ocorresse algum erro o código do erro e local de ocorrência estaria indicado neste guia. 30 PROGRAMAÇÃO COBOL Figura 1.15 – Programa Hello world gerado automaticamente Figura 1.16 – Apresentação da janela Logs após compilação do programa A guia Output da janela Logs é usada para a apresentação da saída do programa. Para ver seu uso acione na barra de ferramentas o botão Run the current editor program e observe a ocorrência apresentada de acordo com a figura 1.17. Figura 1.17 – Apresentação da janela Logs após execução do programa A guia Compiler da janela Logs apresenta informações diferentes dependendo da ação executada quando da compila-ção ou execução de um programa. A figura 1.18 mostra as mensagens apresentadas respectivamente após a realiza-ção da compilação e da execução de um programa. Figura 1.18 – Apresentação da janela Logs com mensagens de operação COBOL 31 Observe na parte superior da figura 1.18 que para compilar o programa COBOL é usada a instrução: cobc.exe -x -o bin\c01ex02.exe -std=default -Wall -debug c01ex02.cob Onde cobc.exe é a chamada do compilador COBOL, -x é a chave de criação do programa executável, -o é a chave que direciona a saída da compilação para o local indicado a sua frente, bin\ a indicação do local dentro da pasta usada para a criação da versão executável do programa, neste caso c01c02.exe, o indicador -std=default orienta o compila-dor a usar o modo padrão de ação de compilação (podendo ser indicado outros dialetos de compilação), a chave -Wall orienta o compilador a apresentar mensagens de advertência com a finalidade de orientar o programador a melhorar o código escrito, a chave -debug é usada para ativar o modo de verificação de erros durante o tempo de compilação e por fim o nome c01ex02.cob refere-se ao programa fonte COBOL a ser compilado. A mensagem de compilação apresentada na guia Compiler da janela Logs pode ser escrita manualmente na janela de console (modo terminal), desde que os caminhos da instalação do compilador estejam devidamente configurados juntos as variáveis de ambiente. Essa ação, se desejada, deverá ser efetuada manualmente, pois a instalação do programa OpenCobolIDE não as realiza. Você deve ter notado que a aparência do ambiente de programação OpenCobolIDE pode ser melhorada. Assim sendo, execute o comando de menu Edit/Preferences (figura 1.19) para que seja apresentada a caixa de diálogo Preferences como indica a figura 1.20 (que poderá estar um pouco diferente em seu sistema, mas não se preocupe). Figura 1.19 – Acesso a caixa de diálogo Preferences Figura 1.20 – Caixa de diálogo Preferences A caixa de diálogo Preferences é usada para definir e alterar diversas configurações junto ao ambiente de desenvolvi- mento. Esta caixa possui as guias Editor, Style, Compiler, Run e SQL COBOL. Na guia Style pode-se selecionar em Editor color scheme diversos esquemas de cores para formatação do ambiente, pode-se estabelecer o tipo de fonte de texto usada em Editor font e mudar o tamanho da fonte em Font size. Assim sendo, para melhorar a visualização selecione a partir da guia Style em Application style a opção Dark, depois em Editor color scheme selecione a opção native e acione OK. Veja se esse visual atende. Caso não goste repita a ação até encontrar o que melhor atende. Depois na guia Editor da caixa de diálogo Preferences na área Margins pode-se mudar a cor das linhas verticais ver-melhas. Por exemplo, alterar a cor vermelha para amarelo, e altera a posição da coluna 80 para 7. Deste modo a sétima coluna ficara bem destacada. 32 PROGRAMAÇÃO COBOL Outra alteração importante é desviar a saída do programa da guia Output da janela Logs para a tela do modo console. Para tanto, a partir da caixa de diálogo Preferences selecione a guia Run e habilite com um clique do ponteiro do mouse a opção Run in external terminal. O uso da guia Output na janela Logs para a apresentação e indicação das saídas dos programas não é muito conveniente. Observe os detalhes de apontamento indicados junto a figura 1.21. Note os pontos de seleção a serem configurados para a caixa de diálogo Prefer- ences. Figura 1.21 – Habilitação Run in external terminal A figura 1.22 apresenta a imagem do programa OpenCobolIDE após a execução das mudanças indicadas. Figura 1.22 – Tela do programa OpenCobolIDE configurada Para ver a saída produzida no modo console (janela do terminal) execute o programa a partir do botão Run the current editor program e a saída será produzida em modo terminal como mostra a figura 1.23. Figura 1.23 – Saída em modo terminal O objetivo deste livro é apresentar a linguagem COBOL e não o ambiente OpenCobolIDE. Por esta razão são apenas usados os recursos do ambiente que sejam necessários ao uso da linguagem em certo momento. Outro ajuste importante para este estudo é a definição da versão da norma a ser usada no desenvolvimento dos pro-gramas. Assim sendo, vá até o menu Edit e escolha a opção Preferences. Selecione a guia Compiler e na página apresentada, em Standard escolha a opção cobol2014 e acione o botão OK. Pronto o compilador GnuCOBOL está configurado para compilar os programas de acordo com a norma ISO/IEC 1989:2014. COBOL 33 1.4 ESTRUTURA SINTÁTICA Os comandos e instruções da linguagem COBOL têm grande semelhança com a forma escrita do idioma inglês. A lin-guagem foi projetada para ser auto documentada como se fosse a descrição textual de um algoritmo computacional proporcionando alto grau de legibilidade. Das linguagens de programação existentes duas destacam-se nesses objeti-vos COBOL e SQL. Mas, este grau de semelhança com o idioma inglês faz com que COBOL seja altamente detalhada ao ponto de possuir mais de 300 palavras reservadas em contraste com outras linguagens de programação mais mo-dernas e sucintas que possuem quantidades menores de comandos. Apesar desses detalhes COBOL é efetivamente mais fácil de usar que outras linguagens de programação existentes. Um código escrito em linguagem COBOL é orga-nizado em áreas chamadas divisões, as quais são formadas por seções. As seções, por sua vez, são formadas por parágrafos e os parágrafos são formados por uma ou mais sentenças que expressam ações representadas a partir da definição de instruções (comandos e cláusulas). As instruções por sua vez são a junção de um conjunto de verbos, cláusulas e operadores que dão sentido a uma ou mais ações computacionais. Há duas formas de se efetuar a codificação de programas em COBOL: uma com formulário fixo e outra com formulário livre. Na forma fixa é necessário seguir uma estrutura rígida de escrita, diferentemente da forma livre onde essa rigidez não é aplicada. Apesar da forma livre ser muito atraente é comum encontrar códigos COBOL escritos de forma fixa, talvez devido a tradição da programação COBOL e a quantidade de código legado existente em uso. A forma fixa é tão importante e popular que o próprio ambiente de programação OpenCobolIDE utiliza-o como forma padrão de codifica-ção inicial. Os comandos da linguagem serão os mesmos entre as formas fixa e livre. No entanto, existirão detalhes estéticos a serem considerados entre esses formatos. A título de ilustração despretensiosa considere a seguir um códi-go escrito ao estilo COBOL-68 (mas não propriamente o padrão COBOL-68) que apresenta no monitor de vídeo a men- sagem “ALO, MUNDO!”. O formato fixo está sendodefinido a partir da forma mais rígida utilizada considerado elemen-tos textuais que na atualidade não são mais usados. Já o formato livre utiliza uma forma de escrita mais despojada por não fazer referência a nenhum outro elemento que não sejam apenas as instruções da linguagem. Observe, então, os exemplos da codificação em formato fixo e livre como se estivesse impresso em papel zebrado. Exemplo de codificação em formato fixo 001010*PROGRAMA EXEMPLO PROG_ALO 001020 PROG_ALO 001030 IDENTIFICATION DIVISION. PROG_ALO 001040 PROGRAM-ID. PROG_ALO. PROG_ALO 001050 AUTHOR. AUGUSTO MANZANO. PROG_ALO 001060 INSTALLATION. COMPUTADOR PADRAO IBM-PC, GNUCOBOL EM WINDOWS. PROG_ALO 001070 DATE-WRITTEN. 10 DE MARCO DE 2020. PROG_ALO 001080 DATE-COMPILED. 10 DE MARCO DE 2020. PROG_ALO 001090 SECURITY. SEM RESTRICAO DE USO E ACESSO. PROG_ALO 001100 REMARKS. PROGRAMA EXEMPLO AO ESTILO ANSI COBOL-68. PROG_ALO 001110 PROG_ALO 001120 ENVIRONMENT DIVISION. PROG_ALO 001130 CONFIGURATION SECTION. PROG_ALO 001140 SOURCE-COMPUTER. IBM-PC COMPATIVEL. PROG_ALO 001150 OBJECT-COMPUTER. IBM-PC COMPATIVEL. PROG_ALO 001160 SPECIAL-NAMES. CONSOLE IS MEU_TERMINAL. PROG_ALO 001170 PROG_ALO 001180 DATA DIVISION. PROG_ALO 001190 PROG_ALO 001200 PROCEDURE DIVISION. PROG_ALO 001210 DISPLAY "ALO, MUNDO!" UPON MEU_TERMINAL. PROG_ALO 001220 STOP RUN. PROG_ALO 001230 END PROGRAM PROG_ALO. PROG_ALO Para a codificação de programas em formato fixo se utilizavam formulários padronizados que indicavam o local correto e as posições de definição das partes do código. Note junto a figura 1.24 a imagem de um formulário padrão IBM pa-dronizado para codificação COBOL disponível em http://aandds.com/blog/lang-cobol.html. 34 PROGRAMAÇÃO COBOL Figura 1.24 – Formulário padronizado IBM para codificação COBOL A primeira área do formulário é chamada SEQUENCE (colunas de 1 a 6). É usada para indicar o número de sequência da página, subárea PAGE (colunas de 1 a 3) e o número de sequência da linha em edição, subárea SERIAL (colunas de 4 a 6). Daí o código apresentado possuir linhas numeradas como 001010 (página 1 linha 10), 001020 (página 1 linha 20), etc. Nesta área pode-se usar caracteres alfabéticos pois a numeração é apenas referencial e o compilador não a utiliza para a geração do programa. Normalmente as linhas são dispostas de 10 em 10 para se ter eventualmente espa- ços disponíveis de inserção de alguma instrução caso esta fosse esquecida ou a ser colocada. A segunda área do formulário é chamada CONT (coluna 7) disponível para indicar o uso de um caractere de continui-dade, podendo ser: um caractere asterisco (*) para indicar linha de comentário ou linha em branco, um caractere hífen (-) para indicar a continuação da escrita de uma linha literal anterior e o caractere barra (/) para gerar linha de comen-tário iniciada em nova página no arquivo de listagem quando o código enviado a uma impressora. A terceira área do formulário é chamada A (colunas de 8 a 11) sendo usada para a definição das divisões, seções e parágrafos que formam a estrutura de um programa. A quarta área do formulário é chamada B (colunas de 12 a 72) sendo usada para o estabelecimento das instruções a serem executadas pelo programa. As instruções de um programa em formato fixo não podem ultrapassar a coluna 72. Isso garante a codificação de instruções simples e de fácil manutenção. Há ainda a quinta área do formulário chamada IDENTIFICATION (colunas 73 a 80) que poderá estar definida logo após a coluna 72 ou definida junto ao cabeçalho do formulário ao lado direito. Esta área é usada para identificar o programa com até oito caracteres. A informação desta área não é processada, podendo ser omitida. O formulário padronizado é usado pelo programador na codificação de um programa escrito manualmente. Posterior-mente este formulário era passado a um operador (ou mesmo um programador) que perfurava um conjunto de cartões de cartolina em um equipamento de perfuração seguindo as orientações escritas no formulário, idênticos a imagem da figura 1.25 gerada pelo programa The Virtual Keypunch (https://www.masswerk.at/keypunch). COBOL 35 Figura 1.25 – Cartão padrão para codificação COBOL Após a perfuração, os cartões eram colocados em um equipamento de leitura que permitia passar as informações do cartão para um computador que após a leitura de cada cartão, montava o programa na memória e podia ser compilado, deixando-o pronto para o uso. Observe que as marcações definidas junto ao cartão para codificação COBOL da figura 1.25 conjuminam com a estru-tura do formulário padronizado indicado na figura 1.24. Os computadores da época dos cartões perfurados operavam uma quantidade menor de caracteres que os atualmente em uso. Cada um dos caracteres ocupava uma posição na coluna do carão. Para dar uma ideia de como isso ocorria, observe a figura 1.26 com a indicação dos caracteres suportados nos computadores da época, gerados com o progra-ma The Virtual Keypunch. Note que cada posição marcada com um ou mais furos determinam o caractere a ser consi-derado. Figura 1.26 – Cartão padrão para codificação COBOL Cada cartão perfurado correspondia a uma única linha de instrução do código de um programa. Assim, se o programa tivesse 1000 linhas seriam gerados 1000 cartões que deveriam sempre estar em ordem sequencial para serem proces-sados adequadamente. Era aí que as informações da primeira e quarta áreas do formulário padronizado eram úteis, pois a partir delas era mais fácil saber a que programa o cartão pertencia e qual sua posição na sequência de cartões do programa. A partir do código exemplo do programa PROG_ALO que tem por finalidade apresentar a mensagem “ALO, MUNDO!”, considere a codificação de um programa muito simples em formulário padronizado como indicado na figura 1.27 e seu código equivalente demostrado nas imagens de cartões perfurados das figuras de 1.28 até 1.50. 36 PROGRAMAÇÃO COBOL Figura 1.27 – Exemplo de codificação COBOL em formulário padronizado Figura 1.28 – Perfuração da instrução: PROGRAMA EXEMPLO Figura 1.29 – Perfuração da instrução: LINHA EM BRANCO COBOL 37 Figura 1.30 – Perfuração da instrução: IDENTIFICATION DIVISION Figura 1.31 – Perfuração da instrução: PROGRAM-ID. PROG_ALO Figura 1.32 – Perfuração da instrução: AUTHOR. AUGUSTO MANZANO 38 PROGRAMAÇÃO COBOL Figura 1.33 – Perfuração da instrução: INSTALLATION. COMPUTADOR PADRAO IBM-PC, GNUCOBOL EM WINDOWS Figura 1.34 – Perfuração da instrução: DATE-WRITTEN. 10 DE MARCO DE 2020 Figura 1.35 – Perfuração da instrução: DATE-COMPILED. 10 DE MARCO DE 2020 COBOL 39 Figura 1.36 – Perfuração da instrução: SECURITY. SEM RESTRICAO DE USO E ACESSO Figura 1.37 – Perfuração da instrução: REMARKS. PROGRAMA EXEMPLO AO ESTILO ANSI COBOL-68 Figura 1.38 – Perfuração da instrução: LINHA EM BRANCO 40 PROGRAMAÇÃO COBOL Figura 1.39 – Perfuração da instrução: ENVIRONMENT DIVISION Figura 1.40 – Perfuração da instrução: CONFIGURATION SECTION Figura 1.41 – Perfuração da instrução: SOURCE-COMPUTER.