Revisões de programação imperativa Transição para o Javatl.di.fc.ul.pt/s/pco_ppo_t2.pdf · PCO...

34
PCO / PPO Departamento de Informática Faculdade de Ciências da Universidade de Lisboa Revisões de programação imperativa Transição para o Java

Transcript of Revisões de programação imperativa Transição para o Javatl.di.fc.ul.pt/s/pco_ppo_t2.pdf · PCO...

PCO / PPODepartamento de Informática

Faculdade de Ciências da Universidade de Lisboa

Revisões de programação imperativa Transição para o Java

Resumo

➡ Revisões de programação imperativa e transição para o Java

➡ aspectos básicos de sintaxe

➡ pacotes e classes

➡ o método main

➡ métodos: assinatura e corpo

➡ variáveis: declaração, atribuição e uso

➡ tipos primitivos e operadores

➡ instruções condicionais: if-then-else, switch-case

➡ iteração: while, do-while, for

➡ recursão2

“Hello world!” em Java

3

package pco;

/* * This program simply prints "Hello world!" */public class HelloWorld {

public static void main(String[] args) { // Print "Hello world!" System.out.println("Hello World!"); }

}

➡ Ao nível mais básico há bastantes semelhanças com a sintaxe de C / C++ / C#, por exemplo na forma de comentários, uso de ‘;’ e chavetas, palavras-chave, operadores, etc

➡ Comecemos por examinar esses aspectos …

Comentários

4

package pco;

/* * This program simply prints "Hello world!" */public class HelloWorld {

public static void main(String[] args) { // Print "Hello world!" System.out.println("Hello World!"); }

}

➡ Comentários em código fonte.➡ multi-linha: entre /* e */➡ até ao fim da linha: iniciados com //

Classes e pacotes

5

package pco;

/* * This program simply prints "Hello world!" */public class HelloWorld {

public static void main(String[] args) { // Print "Hello world!" System.out.println("Hello World!"); }

}

➡ Código organizado em pacotes (“packages”), do qual podem fazer parte várias classes.

➡ A classe HelloWorld faz parte do pacote pco.

➡ Em associação à classe, definimos um programa cujo ponto de entrada é o método main.

Instruções

6

package pco;

/** * This program simply prints "Hello world!" */public class HelloWorld {

public static void main(String[] args) { // Print "Hello world!" System.out.println("Hello World!"); }

}

➡ Instruções ➡ uma instrução simples (comando) é terminada com ‘;’ ➡ um bloco de instruções é agrupado com chavetas (entre { e })

Em mais detalhe …

7

public static void main(String[] args) { // Print "Hello world!" System.out.println("Hello World!");}

➡ Alguns conceitos que iremos desenvolver a seguir …➡ Assinatura de um método ➡ o nome é main ➡ o tipo de retorno é void, significando que o método não retorna nenhum

valor;➡ o método tem apenas um parâmetro: args com tipo String[], um vector

de strings (passados externamente ao programa e ignorados neste caso)➡ dois modificadores, de que não falaremos por agora: public e static

➡ Corpo de um método ➡ bloco de instruções agrupadas em bloco (entre chavetas) a seguir à assinatura➡ main contém apenas uma instrução, que trata de chamar o método println

sobre o objecto System.out passando como argumento a string “Hello World!”

Exemplo 2 (max)

8

package pco;public class MaxExample { public static int max(int a, int b) { int r; if (a > b) { r = a; } else { r = b; } return r; } public static void main(String[] args) { System.out.println( max(100, 200) ); }}

➡ Exemplo simples que ilustra: ➡ uso de tipos primitivos (int) e operadores ( < , = )➡ declaração e uso de parâmetros e variáveis locais (a, b, r) ➡ fluxo de controlo: bloco condicional if-else, retorno de

valores com return, chamada a max a partir de main

public static int max(int a, int b) { int r; if (a > b) { r = a; } else { r = b; } return r; }

Declaração de variavéis

➡ A declaração de uma variável compreende o seu tipo e o seu nome. O compilador de Java valida que:

➡ a declaração antecede sempre qualquer uso da variável;

➡ em cada âmbito de declarações, não há 2 variáveis com o mesmo nome;

➡ uma variável tem sempre um valor definido antes de ser lida;

➡ No exemplo o tipo da variável é int e o nome é r.➡ Podemos remover a declaração de r? Declará-la apenas após o if-else ou

várias vezes ? Mudar o nome de r para a? Remover uma das atribuições a r ? NÃO!

9

Tipos primitivos

10

Tipo Descrição

boolean valor booleano

char caracter Unicode de 16-bits

byte inteiro de 8 bits

short inteiro de 16 bits

int inteiro de 32 bits

long inteiro de 64 bits

float número de vírgula flutuante de 32 bits

double número de vírgula flutuante de 64 bits

➡ A um tipo primitivo associam-se valores elementares com determinado âmbito (ex. -2^31 a 2^31-1 para int) .

➡ Veja: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html para uma descrição dos tipos primitivos em Java.

Operadores

11➡ Consulte https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

Sobrecarga de métodos public static int max(int a, int b) { . . . // código anterior } public static double max(double a, double b) { double r; if (a > b) { r = a; } else { r = b; } return r; } public static void main(String[] args) { System.out.println( max(1, 3) ); System.out.println( max(1.5, 3.4) ); }}

12

➡ Sobrecarga de métodos ➡ podemos definir métodos diferentes com o mesmo nome desde que

não haja ambiguidade entre as respectivas assinaturas➡ no exemplo main invoca a variante de max para valores de tipo int e

depois a variante para valores de tipo double

Fluxo de controlo

➡ Condicionais➡ if - else

➡ uso de operadores && e ||

➡ switch - case

➡ Iteração (ciclo)➡ for

➡ while

➡ do-while

➡ Retorno de método➡ return

13

If, else if

14

public static boolean isHexDigit(char c) { boolean r; if (c >= '0' && c <= '9') { r = true; } else if (c >= 'a' && c <= 'f') { r = true; } else if (c >= 'A' && c <= 'F') { r = true; } else { r = false; } return r; }

➡ Exemplo testa se um caracter corresponde a um dígito hexadecimal.

➡ Consulte valores numéricos para os caracteres em https://en.wikipedia.org/wiki/List_of_Unicode_characters#Basic_Latin

Codificação alternativa do exemplo anterior

15

public static boolean isHexDigit(char c) { return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); }

➡ Fluxo condicional implícito no uso de && e ||.

➡ Em a && b a expressão b só é avaliada se a avaliação (prévia) de a der true

➡ Em a || b a expressão b só é avaliada se a avaliação (prévia) de a der false

public static boolean isHexDigit(char c) { boolean r; if (c >= '0' && c <= '9') { r = true; } else if (c >= 'a' && c <= 'f') { r = true; } else if (c >= 'A' && c <= 'F') { r = true; } else { r = false; } return r; }

public static String monthString(int month) { String str; switch (month) { case 1: str = "January"; break; case 2: str = "February"; break; case 3: str = "March"; break; case 4: str = "April"; break; case 5: str = "May"; break; case 6: str = "June"; break; case 7: str = "July"; break; case 8: str = "August"; break; case 9: str = "September";break; case 10: str = "October"; break; case 11: str = "November"; break; case 12: str = "December"; break; default: str = "Invalid"; break; } return str; }

Switch-case

16➡ Bloco switch-case

public static int someFunc(int n) { int r = 0; switch (n) { case 0: r = 1; case 1: r = r + n + 1; break; case 2: case 3: r = n+1; break; default: r = n; } return r; }

Switch-case

17

➡ Note-se a ausência de break em case 0 e o tratamento conjunto dos casos em que n é 2 ou 3.

➡ Qual será o resultado do método para n entre 0 e 5 ?

Exemplo - factorial

➡ 4 ! = 4 x 3 x 2 x 1➡ Qual o valor impresso pelo programa? ➡ Como se desenrola a execução do ciclo while ?

18

package pco;public class FactorialExample { public static int factorial(int n) { int r = 1; int i = 1; while (i <= n) { r = r * i; i = i + 1; } return r; } public static void main(String[] args) { int f4_plus_1 = factorial(4) + 1; System.out.println( f4_plus_1 ); }}

Factorial - codificações alternativas

➡ Implementação usando ciclo for.

➡ Equivalente em termos de execução à anterior.

19

public static int factorial(int n) { int r = 1; for (int i = 1; i <= n; i++) { r = r * i; } return r; }

Factorial - codificações alternativas

➡ Iteração usando ciclo do-while.

➡ Embora o resultado seja o mesmo, qual é a diferença na execução em relação às alternativas anteriores?

20

public static int factorial(int n) { int r = 1; int i = 1; do { r = r * i; i = i + 1; } while (i <= n); return r; }

Factorial - codificações alternativas

➡ Iteração usando recursão.➡ Qual é a diferença na execução em relação às alternativas anteriores?

21

public static int factorial(int n) { if (n == 1) return 1; else return n * factorial(n - 1); }

Vectores (“arrays”)

➡ Um vector (“array”) é um objecto especial que contém um numero fixo de elementos de determinado tipo.

➡ No exemplo: o programa imprime todos os argumentos que lhe são fornecidos em args, um vector de strings.

➡ o tamanho é dado por args.length e não pode ser alterado➡ o acesso a cada posição é definido por args[i]

22

package pco;

public class PrintProgramArguments {

public static void main(String[] args) { for (int i=0; i < args.length; i++) { System.out.println(args[i]); }

}}

Vectores (“arrays”)

23

AnaBertoCarlos No Eclipse configure os argumentos no

menu “Run As > Run Configurations”.

“Ana”•args “Carlos”“Beto”

0 1 2

args.length = 3

package pco;

public class PrintProgramArguments {

public static void main(String[] args) { for (int i=0; i < args.length; i++) { System.out.println(args[i]); }

}}

➡ Com i <= args.length o programa irá aceder à posição 3, que é inválida.➡ Erro de execução (excepção): ArrayIndexOutOfBoundsException

Validação de acessos

24

AnaBetoCarlosException in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3

at pco.PrintProgramArguments.main(PrintProgramArguments.java:6)

for (int i=0; i <= args.length; i++) { System.out.println(args[i]);

}

i < args.length i <= args.lengthvs.

“Ana”•args “Carlos”“Beto”

0 1 2 3?

Vectores (“arrays”)- validação de acessos -

25

➡ O acesso a uma posição de um vector é sempre validado pela máquina virtual Java.

➡ N o c a s o d e a c e s s o i n v á l i d o , a e x c e p ç ã o ArrayIndexOutOfBoundsException é l a n ç a d a automaticamente, causando no exemplo anterior a terminação abrupta do programa.

➡ De forma geral, excepções assinalam eventos anómalos de vária ordem, eventualmente tratáveis pelo programa. Iremos ver depois como funciona o mecanismo em detalhe.

Vectores e ciclos “for-each”

➡ Programa equivalente ao original.➡ É usado um ciclo “for-each” (“para-cada”)➡ Forma geral: for (tipo nomeVar : vector)  { ... } ➡ Permite código menos verboso / mais simples.➡ Conveniente em muitos casos: quando o índice do vector é

irrelevante na iteração e não queremos modificar o vector. 26

public class PrintProgramArgumentsUsingForeachLoop { public static void main(String[] args) {

for (String s : args) { System.out.println(s); }

}}

Ciclos “for-each”- segundo exemplo -

27

public static int sumElements1(int[] array) { int sum = 0; for (int i = 0; i < array.length; i++) { sum += array[i]; } return sum; }

public static int sumElements2(int[] array) { int sum = 0; for (int value : array) { sum += value; } return sum; }

ciclofor

ciclofor-each

public static int[] reverse(int[] v) { int[] result = new int[v.length]; for (int i=0; i < v.length; i++) { result [i] = v[v.length - i - 1]; } return result; } public static void main(String[] args) { int[] a = { 0, 1, 2, 3, 4}; int[] b = reverse(a); for (int i = 0; i < b.length; i++) { System.out.println(b[i]); } }

Criação de vectores (1)

➡ Este programa cria um novo vector, que resulta da inversão de { 0, 1, 2, 3, 4 }, i.e., { 4, 3, 2, 1, 0 }.

➡ Em main o vector é construído com os valores constantes em causa. 28

• 0 1 2 3 4

public static int[] reverse(int[] v) { int[] result = new int[v.length]; for (int i=0; i < v.length; i++) { result [i] = v[v.length - i - 1]; } return result; } public static void main(String[] args) { int[] a = { 0, 1, 2, 3, 4}; int[] b = reverse(a); for (int i = 0; i < b.length; i++) { System.out.println(b[i]); } }

Criação de vectores (2)

➡ Operador new define a criação de um vector com um tamanho dado.

➡ As posições do vector são inicialmente preenchidas com um valor por defeito (0 no caso de vectores int). 29

• 0 1 2 3 4

• 0 0 0 0 0

• 4 3 2 1 0

Vectores e referências

➡ O valor de a é atribuido a b … o que isso significa?➡ O valor das variáveis em causa não “são” vectores em si, mas antes

referências a vectores …➡ Assim, b vai passar a referenciar o mesmo vector que a. ➡ b[1] = 2 modificará o mesmo vector.

➡ a == b avalia para true

int[] a = { 1 , 1, 1}; int[] b = a;

b[1] = 2;System.out.println(a[1]);System.out.println(b[1]);if (a == b) {

System.out.println(“a == b”);}

30

• 1a 1 1

•b

• 1a 2 1

•bb[1] = 2;

impressão

12a == b

Clonagem de vectores

➡ a.clone() cria uma cópia de a

➡ … e então b contém referência para um vector distinto

➡ Operadores == e != apenas testam se referências são idênticas. Para testar equivalência de conteúdo podemos usar o método Arrays.equals().

int[] a = { 1 , 1, 1}; int[] b = a.clone();

b[1] = 2;System.out.println(a[1]);System.out.println(b[1]);if (a != b) {

System.out.println(“a != b”);}

31

• 1a 1 1

•b

• 1a 1 1

•bb[1] = 2;

impressão

12a != b

1 1 1 1 2 1

package pco;public class NullExample { public static void main(String[] args) { int[] v = null; // This will cause NullPointerException to be thrown int a = v[0]; // The following will not be executed System.out.println(a); }}

Referência nula (null)

➡ A referência nula é identificada pela palavra-chave null.

➡ Acesso à referência nula leva à excepção NullPointerException

32

Exception in thread "main" java.lang.NullPointerException

at pco.NullExample.main(NullReferenceExample.java:6)

Vectores multi-dimensionais

➡ v é um vector com 4 posições

➡ Cada posição de v contém por sua vez uma referência a um vector de tipo char

33

abcdefghij

char[][] v = { { 'a', 'b', 'c', 'd'}, { 'e', 'f', 'g' }, { 'h', 'i' }, { 'j' }};for (int i = 0; i < v.length; i++) { for (int j = 0; j < v[i].length; j++) { System.out.print(v[i][j]); } System.out.print('\n');}

a

v

b

c

• • •

e

f

g

h

i

d

j

impressão

Vectores multi-dimensionais (2)

34

int[][] a = new int[3][2]; // equivalent to { {0,0}, {0,0}, {0,0} }int[][] b = new int[3][]; // equivalent to { null, null, null }int[][] c = { {0}, { 1, 2 }, {3, 4, 5}};int[][][] v = { a, b, c };System.out.println(v[2][1][0]); // What value is printed?

0

a

0

• • •

0

0

0

0

•b / / / •

0

c • • •

1

2

3

4

5

•v • • •