Aula 6 Subprogramas Programação em Java 2006-2007 Introdução Java é uma linguagem de programação orientada a objectos (POO). O objectivo desta aula é escrever programas em Java organizando o código em subprogramas sem nos preocupar ainda em explorar os recursos do paradigma de POO. nível Programação Orientada a Objectos Programação Estruturada Programação Procedural paradigma de programação estilo de programação Programação em Java 2006-2007 Encapsula dados (atributos) e subprogramas (métodos) em componentes (classes) Organiza código (em subprogramas) e dados (algoritmo = programa + estruturas de dados). Organiza o código em subprogramas (funções). Também conhecida como programação imperativa. 2 Subprogramas Em Java existe um subprograma principal chamado main que marca o início da execução do programa Em aulas anteriores dentro do subprograma main chamamos a diferentes subprogramas (funções) pré-definidos ex: as funções do pacote java.lang ou do pacote p1 do DETI Exemplo: o seguinte programa usa a função abs da classe Math do pacote java.lang para calcular o valor absoluto de um número. import p1.*; class ValorAbsoluto extends P1App { public static void main(String args[]) { println("abs(-30) = " + Math.abs(-30) ); } } Programação em Java 2006-2007 3 Subprogramas definidos pelo programador Exemplo 1: Função que calcula o valor absoluto Podemos também definir os nossos próprios subprogramas e usá-los tal como usamos a função Math.abs. import p1.*; class Ex_6_1_abs extends P1App { public static void main(String args[]) { println("abs(-30): " + abs(-30) ); Por exemplo, podemos escrever a nossa própria função abs para calcular o valor absoluto de um número real. } static double abs( double x ) { if ( x < 0 ) return -x; else return x; } } Programação em Java 2006-2007 Aqui usamos a nossa própria função abs. 4 Subprogramas (funções) em Java static tipo_valor_retorno nome_da_função (parâmetros) { instruções; // corpo da função } nome da função tipo do valor de retorno static double abs ( double x ) { if ( x < 0 ) parâmetro return -x; else return x; valor de retorno } corpo da função A instrução return provoca o fim imediato da execução da função, devolvendo o valor de retorno Programação em Java 2006-2007 5 Exemplo 2: Função que calcula o factorial de um número nome da função tipo do valor de retorno O corpo da função é uma espécie de mini-programa onde podemos declarar variáveis e usar quaisquer instrução elementar como instruções de atribuição, decisão e repetição . static int factorial(int n ) { int i,p; p = 1; for ( i=2; i<=n; i++ ) p = p * i; return p; } parâmetro valor de retorno Um subprograma é comparável a uma caixa preta que recebe dados e produz resultados. A função factorial recebe um valor inteiro n e devolve um outro valor inteiro que é o factorial de n. Entrada n Factorial Programação em Java 2006-2007 Saída n! 6 Exemplo 3: Funções que calculam o máximo de 2 e 3 números static double max( double x, double y ) { if ( x > y ) return x; else return y; } os parâmetros estão separados por vírgula e precedidos pelo tipo. Se não existirem parâmetros de entrada usamos apenas () static double max3 ( double x, double y, double z ) { return max( x, max(y,z) ); } A função max3 usa a função max para determinar o máximo entre dois números Programação em Java 2006-2007 7 Exemplo 4 Passagem de Parâmetros Se o tipo é primário (int, float, boolean, etc.) então a passagem é feita por valor se o parâmetro é uma variável o seu valor nunca muda depois da execução do subprograma Este programa imprime x = 70. Apesar de durante a execução, o subprograma muda alterar o valor do parâmetro para 20, o valor de x mantêm-se inalterável pois é o valor de x que é passado ao subprograma e não a própria variável x, pelo que a instrução println provoca a escrita de 70 e não de 20. import p1.*; class Ex_6_4_par extends P1App { public static void main(String args[]) { int x = 70; muda(x); println(“x = " + x ); } static void muda( int valor) { valor = 20; } } Programação em Java 2006-2007 8 Funções que não retornam nenhum valor. A palavra reservada void O conceito de função em Java é mais geral que as funções matemáticas. Em Java podemos definir funções que não retornam nenhum valor. Para isto usamos a palavra reservada void como tipo do valor de retorno Esta função não retorna nenhum valor. Simplesmente executa uma instrução de atribuição import p1; class Ex_6_4_par extends P1App { public static void main(String args[]) { int x = 70; muda(x); println(“x = " + x ); } static void muda( int valor) { valor = 20; } } Programação em Java 2006-2007 9 Organização de um Programa em Java Um programa é constituído por uma classe e contêm: Declarações de variáveis (globais) Um subprograma principal chamado main() Um conjunto de subprogramas definidos pelo programador Cada subprograma contem: Declarações de variáveis (locais) Instruções elementares (atribuição, selecção, repetição , etc.) Chamadas de subprogramas pré-definidos ou criados pelo programador Programação em Java 2006-2007 10 Exemplo 5: Um programa dividido em subprogramas Este programa escreve no ecrã os números inteiros entre 1 e um número n fornecido pelo utilizador. O subprograma principal main chama dois funções: a função lerTotalNumeros e a função escreverNumeros A palavra reservada void indica que esta função não retorna nenhum valor. import p1.*; class Ex_6_5_imprimirNumeros extends P1App { public static void main(String args[]) { int n = lerTotalNumeros(); escreverNumeros(n); } static int lerTotalNumeros() { int n; do n = readInt(“Quantos números vai imprimir? "); while (n <=0); return n; } static void escreverNumeros (int n){ for (int i=1; i<=n; i++) printf(4, i); } } Programação em Java 2006-2007 11 Exemplo 5: Variáveis Locais As variáveis declaradas dentro de uma função são chamadas variáveis locais e só existem enquanto essa função estiver a ser executada. Esta variável n é uma variável local ao subprograma main e apesar de ter o mesmo nome, não tem nada que ver com a variável n declarada em lerTotalNumeros Esta variável n é uma variável local ao subprograma lerTotalNumeros import p1; class Ex_6_5_imprimirNúmeros extends P1App { public static void main(String args[]) { int n = lerTotalNumeros(); } static int lerTotalNumeros() { int n; do n = readInt(“Quantos números vai imprimir? "); while (n <=0); return n; } Programação em Java 2006-2007 12 Exemplo 6: Variáveis Locais O resultado da execução é o seguinte: n = 5 antes da chamada n =10 dentro de muda n=5 depois da chamada import p1.*; class Ex_6_6_variaveisLocais extends P1App { public static void main(String args[]) { int n = 5; // variável local ao subprograma main println(“n=“ + n +” antes da chamada”); muda( ); println(“n=“ + n +” depois da chamada”); } } static void muda() { int n = 10; // variável local ao subprograma muda println(“n=“ + n +” dentro de muda”); } Programação em Java 2006-2007 13 Exemplo 7: Variáveis Globais As variáveis declaradas fora de qualquer subprograma são chamadas variáveis globais. São criadas no início da execução do programa, só sendo destruídas quando o programa termina. Esta variável global aqui declarada é visível a partir de qualquer subprograma O resultado da execução é o seguinte: n = 5 antes da chamada n =10 dentro de muda n=10 depois da chamada import p1.*; class Ex_6_7_variaveisGlobais extends P1App { static int n // variável global declarada no inicio public static void main(String args[]) { n = 5; println(“n=“ + n +” antes da chamada”); muda( ); println(“n=“ + n +” depois da chamada”); } static void muda() { n =10; println(“n=“ + n +” dentro de muda”); } } Programação em Java 2006-2007 14 Esqueleto de um programa dividido em subprogramas class Exemplo { // declaração de variáveis globais public static void main(String args[]) { // declaração de variáveis locais // instruções elementares e/ou chamadas de subprogramas } // fecha subprograma main static tipo_valor_retorno_ou_void nome-da-função_1 (parametros) { // declaração de variáveis locais; // instruções elementares e/ou chamadas de subprogramas incluindo // o comando return se tipo_valor_retorno não é void } // fecha subprograma nome_da_função_1 ……. static tipo_valor_retorno_ou_void nome-da-função_n (parametros) { // declaração de variáveis locais; // instruções elementares e/ou chamadas de subprogramas incluindo // o comando return se tipo_valor_do_retorno não é void } // fecha subprograma nome_da_função_n } // fecha programa Programação em Java 2006-2007 15 Decomposição de um Programa em Subprogramas Em aulas anteriores foram desenvolvidos programas com um estilo de programação “receita de bolo”. Os programas estavam compostos por um único subprograma – o subprograma “main” que podia ser executado passo a passo. A partir de agora vamos a decompor um programa em subprogramas segundo a seguinte metodologia: utilizar as especificações completas e os algoritmos desenvolvidos nas aulas anteriores. cada operação do algoritmo de primeiro nível deve ser implementada com um subprograma, sendo depois o programa principal constituído pela invocação dos subprogramas. Programação em Java 2006-2007 16 Vantagens da Utilização de Subprogramas Os programas ficam mais legíveis e claros Os programas ficam mais fácies de modificar e depurar Os programas não repetem instruções que fazem basicamente a mesma coisa Programação em Java 2006-2007 17 Problema 1: Conversão de distâncias (milhas para quilómetros) Formulação do problema: ler uma distância expressa em milhas a partir do teclado, convertê-la para quilómetros e apresentar o resultado no ecrã. Variável de entrada: MILHAS (distância expressa em milhas) valor numérico positivo ou nulo Variável de saída: KM (distância expressa em quilómetros) valor numérico positivo ou nulo Solução: KM = 1.6093 x MILHAS Programação em Java 2006-2007 18 Problema 1: Conversão de distâncias Algoritmo (decomposição ao nível 1) Nome: Conversão de distâncias em milhas para km subprogramas { lerMilhas Leitura e validação de uma distância em milhas (MILHAS); converter Conversão da distância de milhas para km (MILHAS, imprimir Impressão no ecrã da distância em km (KM); KM); } Nome da Função Parâmetros (entrada) Tipo do valor de retorno lerMilhas nenhum double converter double milhas double imprimir double km void (nenhum) Programação em Java 2006-2007 19 Problema 1: Conversão de distâncias Algoritmo lerMilhas (decomposição ao nível 2) Nome: Leitura e validação de uma distância em milhas (MILHAS) { } repetir { impressão no ecrã da mensagem “Distância em milhas?”; leitura do valor a partir do teclado (MILHAS); } enquanto MILHAS < 0; Nome: Conversão da distância de milhas para km (MILHAS, KM) converter { } KM = 1.6093 x MILHAS; Nome: Impressão no ecrã da distância em kms (KM) imprimir { } escrita no ecrã da mensagem “Distância em kms= “; escrita no ecrã do valor de KM; mudança de linha Programação em Java 2006-2007 20 Problema 1: Conversão de distâncias Programa dividido em subprogramas (I) main import p1.*; class Pr_6_1_MilhasAkm extends P1App { public static void main(String args[]) { double milhas, km; milhas = lerMilhas(); km = converter(milhas); imprimir(km); } leitura static double lerMilhas() { double milhas; do milhas = readInt(“Distância em milhas? "); while (milhas <=0); return milhas; } Programação em Java 2006-2007 21 Problema 1: Conversão de distâncias Programa dividido em subprogramas (II) converter static double converter(double milhas) { double km; km = 1.6093 * milhas; return(km); } imprimir static void imprimir(double km) { println(“Distância em kms= “ + km ); } } Programação em Java 2006-2007 22 Problema 2 (Aula 3) Escrever um programa que lê do teclado uma data composta pelo nº de mês e ano, calcula e imprime no ecrã o nº de dias desse mês. Implemente um procedimento para a leitura e validação da data do teclado e um procedimento para a escrita do resultado Implemente uma função booleana para determinar se um ano é ou não bissexto e uma função interna para calcular o número de dias do mês Ano bissexto: de 4 em 4 anos, com excepção dos finais de século, que são bissextos de 4 em 4 séculos. Por exemplo, os anos 1600, 1996, 2000, 2004 são bissextos, mas os anos 1700, 1800 ou 1900 não o são. Programação em Java 2006-2007 23 Problema 2. Especificação Variável de entrada: mes (número do mês) valor numérico inteiro entre 1 e 12 ano (ano) valor numérico positivo Variável de saída: dias (nº de dias desse mês) valor numérico positivo ou nulo Solução: # Mes # dias 1, 3, 5, 7, 8, 10, 12 31 4, 6, 9, 11 30 2 SE (ano bissexto) dias = 29 caso contrario dias = 28 Programação em Java 2006-2007 24 Problema 2: Dias de um mês Algoritmo (decomposição ao nível 1) Nome: Dias de um mês { Leitura e validação da data (mes, ano ); leitura Calcular nº de dias (mes, ano, dias ); processamento Impressão no ecrã do número de dias (dias); escrita } Programação em Java 2006-2007 25 Problema 2: Dias de um mês Algoritmo (decomposição ao nível 2) Nome: Dias de um mês { subprogramas Leitura e validação da data (mes, ano); lerMes Leitura e validação do mes (mes); lerAno Leitura e validação do ano (ano); diasMes Calcular nº de dias (mes, ano, dias ); SE (mes ==4) ou (mes == 6) ou (mes == 9) ou (mes == 11) dias = 30 SENÃO SE (mes ==2) anoBissexto Determinar se ano é bissexto (bissexto) SE (bissexto) dias = 29 CASO CONTRARIO dias = 28 SENÃO // mes em {1, 3, 5, 7, 8, 10 e 12} dias = 31 imprimir Impressão no ecrã do número de dias (dias); } Programação em Java 2006-2007 26 Problema 2: Dias de um mês Subprogramas Nome da Função Parâmetros (entrada) Tipo do valor de retorno lerMes nenhum int lerAno nenhum int diasMes int mes, int ano, int anoBissexto int ano boolean imprimir int dias void nenhum Programação em Java 2006-2007 27 Problema 3 (Aula 3) Escrever um programa que permita ao utilizador seleccionar de um menu uma operação aritmética (soma, resta, multiplicação ou divisão), introduzir dois valores para os operandos, e que calcule e mostre o resultado da operação seleccionada. As diferentes operações deverão ser implementadas à custa de procedimentos e funções. Programação em Java 2006-2007 28 Bibliografia António José Mendes, Maria José Marcelino. Fundamentos de programação em JAVA 2.FCA – Editora de informática, 2003. Aulas de Programação Imperativa. Funções Prof. Fernando Lobos http://www.deei.fct.ualg.pt/PI_flobo/ Programação em Java 2006-2007 29