PCF-3

Questões comentadas, artigos e notícias

Arquivo do Autor

Java Puzzles [#6] – O incremento.

Posted by p3r1t0cr1m1n4l em 05/03/2009

Qual a saída do programa abaixo?

public class Incremento {
public static void main(String[] args){
int j = 0;
for (int i = 0; i < 100; i++) j = j++; System.out.println(j); } } [/sourcecode]

Posted in Programação | Etiquetado: | 4 Comments »

Java Puzzle [#5] – Jackson 5.

Posted by p3r1t0cr1m1n4l em 24/02/2009

Cansado de resolver cenários de provas da PF e querendo dar uma desopilada, nosso colega Alexandre Teixeira (grande fã dos Jackson 5) decide fazer uma homenagem à sua música favorita: ABC ( http://www.youtube.com/watch?v=ZOXG8wtxx_w ). Ele abre o VIM e começa a codificar o seguinte programa:

public class ABC {
     public static void main(String args[]) {
          String amoEssaMusica = "ABC";
          char[] todosJuntos = { '1', '2', '3' };
          System.out.println(amoEssaMusica + " easy as " + todosJuntos);
     }
}

A pergunta que não quer calar, ele conseguiu imprimir o refrão da tão amada música?

Solução:

Infelizmente ao rodar o programa, o ilustre Alexandre terá como saída ABC easy as [C@16f0472.

O que aconteceu?

Muitas bibliotecas tratam os valores char de forma especial, representando caracteres ao invés de números. Por exemplo, passado um valor char para o println, ele vai imprimir um caractere Unicode, e não o seu código número. Com um array de valores char não é diferente! Através do overloading do método println serão impressos todos os caracteres contidos no array, invocando o .toString() de cada objeto.

O que acontece no entanto quando se invoca o toString() de um array de chars não-nulos? É retornada uma String com o nome da classe da qual o objeto é instância, a arroba (@) e uma representação hexadecimal do código hash do objeto.

A especificação de Class.getName diz que o resultado de invocar esse método em um objeto char[] é “[C”. Complementando com a arroba e o hexadecimal temos esse monstrinho da saída. =)

Como poderia ser resolvido?

public class ABC {
     public static void main(String args[]) {
          String amoEssaMusica = "ABC";
          char[] todosJuntos = { '1', '2', '3' };
          System.out.println(amoEssaMusica + " easy as " + String.valueOf( todosJuntos ) );
     }
}

Até o próximo!

Posted in Programação | Etiquetado: | 1 Comment »

Java Puzzle [#4] – Operador Condicional

Posted by p3r1t0cr1m1n4l em 20/02/2009

O que o programa abaixo imprime?

public class JavaPuzzle4 {
  public static void main(String[] args) {
    char x = 'X';
    int i = 0;
    System.out.print(true ? x : 0);
    System.out.print(false ? i : x);
  }
}

Solução: O programa imprime X88.

Para se determinar tipo resultante de uma expressão condicional, é necessário analisar três pontos:

(1) Se os operandos têm o mesmo tipo, esse será o tipo resultante da expressão condicional.

(2) Se um dos operadores é do tipo T: byte, short ou char, e o outro operador é uma expressão constante do tipo int cujo valor pode ser representado por T, o tipo da expressão condicional será T.

(3) Caso contrário, a promoção numérica binária será aplicada aos tipos do operando.

Analisando a primeira parte:

char x = 'X';
System.out.print(true ? x : 0);

Um dos operadores é char e o outro é um inteiro constante (zero) e pode ser representado em char (0). Caímos então no caso (2). O resultado é ‘X’.

Analisando a segunda parte:

int i = 0;
System.out.print(false ? i : x);

Um dos operadores ainda é zero, porém na forma da variável i. Aplicando a promoção numérica binária, o resultado será int.

O tipo da expressão condicional determina qual método de print será invocado. Na primeira expressão ( PrintStream.print(char) )e na segunda ( PrintStream.print(int) ). Aquele método imprime o valor da variável x como um caractere Unicode (X), enquanto este imprime um decimal inteiro que representa o X em Unicode (88).

Até o próximo puzzle!

Posted in Programação | 1 Comment »

Java Puzzle [#3] – Multicast

Posted by p3r1t0cr1m1n4l em 15/02/2009

Os casts em Java são usados para converter um valor de um tipo para outro tipo. O que o programa abaixo imprime?

public class Multicast {
  public static void main(String[] args) {
    System.out.println((int) (char) (byte) -1);
  }
}

Resposta:

O resultado é 65535.

O Java utiliza complemento de dois, e o inteiro -1 é representado pelos 32 bits setados em 1:

11111111 11111111 11111111 11111111

Ao converter para byte que é signed, sem problemas: ele deixa apenas o último byte e retira os demais valores 1’s mais significativos, ainda representando -1:

11111111

A pegadinha ocorre porém na transformação de byte (signed) para char (unsigned – não dá para representar negativos), cujo resultado são 16 bits, todos setados em 1:

11111111 11111111 = 2^16 = 65535.

A transformação para int ocorre também sem problemas, apenas acrescentando zeros nos 16 bits que faltavam para completar os 32 bits:

00000000 00000000 11111111 11111111 = 65535 (resultado final)

Posted in Programação | Etiquetado: | Leave a Comment »