quarta-feira, 27 de maio de 2015

Exceção - código 3

01 /** Causando...
02 ?? como ver qual o erro??
03 java StackEater 2> err.txt
04 
05 */
06 public class StackEater {
07    public static void main (String[] args) {
08       int a=0, b=0;
09       c(a,b);
10    }
11    static void (int a, int b) {
12       System.out.println ("x");
13       c(a,b);
14    }
15 }
Java2html

Exceção - código 2

01 /** Causando...
02 ?? como ver qual o erro??
03 java StackEater 2> err.txt
04 
05 */
06 public class StackEater {
07    public static void main (String[] args) {
08       int a=0, b=0;
09       c(a,b);
10    }
11    static void (int a, int b) {
12       System.out.println ("x");
13       c(a,b);
14    }
15 }
Java2html

Exceção código 1

01 /** Causando...
02 
03 */
04 public class DivZero {
05    public static void main (String[] args) {
06       int a, b;
07       a=5;
08       b=0;
09       a=a/b;
10       System.out.println (a);
11    }
12 }
Java2html

Array na memória

1 class TestaArray {
2    public static void main (String[] args){
3       int[] arr;
4       arr= new int[10];
5       arr[5]=5;
6    }
7 }
Java2html




Sobre memória

O hardware e instruções para gerenciamento de memória em processadores Intel Core pode ser visto no capítulo 3 do manual do processador:
http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.html

A forma como a memória física é usada por Windows e por Linux pode ser vista em:
http://blog.codinghorror.com/dude-wheres-my-4-gigabytes-of-ram/
http://duartes.org/gustavo/blog/post/motherboard-chipsets-memory-map/
(não encontrei referências no site da Microsoft ou do Linux... a maioria das referências que visitei concordam com as apresentadas)

Agora aumenta a importância do post para nós:

O sistema operacional gerencia a memória física (inclui RAM, HD, swap,...) e quando carrega o executável em memória para que seja executado, expõe aos programas um mapeamento da memória física (que é o espaço de endereçamento virtual):

http://stackoverflow.com/questions/2048007/linux-ia-32-memory-model
http://www.linuxjournal.com/article/4681
http://www.linuxjournal.com/article/6701?page=0,0
http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/

Em especial o exemplo relativo a figura abaixo é bastante ilustrativo do que explico sobre onde (no espaço de endereçamento virtual) ficam armazenados o programa, os literais e as variáveis (estáticas, tipos primitivos e objetos (tipos abstratos)) em aula.

http://static.duartes.org/img/blogPosts/mappingBinaryImage.png

Agora é totalmente nosso território!!!:

Em especial, quando criamos arrays com new e com referência atribuída a uma variável estática, a variável fica no "segmento" de dados e os elementos do array fica no heap.

No escopo de ACH2001 o interesse maior é com a alocação de variáveis (objetos) em memória, geralmente sem preocupação sobre sua localização exata ("segmento" de código, de dados, pilha (stack), heap,...). É suficiente considerar a memória um espaço de armazenamento com endereços.

Relembrando (o pouco que) sabemos sobre compiladores, os identificadores são necessários para facilitar o trabalho do programador. Compiladores substituem identificadores por (algum tipo de) endereço de memória, é suficiente para o programa operar corretamente. Assim, em representações de memória, o identificador é colocado como um rótulo dado a uma posição de memória.

 

quinta-feira, 23 de abril de 2015

Aula - 23.04.2015

1 public interface Despesa {
2     /** retorna a despesa mensal total */
3     double getDespesaMensal();
4     /** le da tela todos os dados para calculo da despesa */
5     void setDados();
6 }
Java2html

1 public class TestaDespesa {
2     public static void main (String[] args) {
3         Despesa d = new TransporteEAlimentacao();
4         d.setDados();
5         System.out.println (d.getDespesaMensal());
6     }
7 }
Java2html

01 import java.util.Scanner;
02 
03 public class Transporte implements Despesa {
04     double transporteMensal;
05     public double getDespesaMensal(){
06         return transporteMensal;
07     }
08     public void setDados() {
09         Scanner sc=new Scanner (System.in);
10         System.out.println ("Quantas vezes você vai aa EACH no mes?");
11         int n=sc.nextInt();
12         System.out.println ("Quanto custa cada ida-e-volta?");
13         double v=sc.nextDouble();
14         transporteMensal=(doublen * v;
15     }
16 }
Java2html

01 import java.util.Scanner;
02 
03 public class TransporteEAlimentacao extends Transporte {
04     double alimentacaoMensal;
05     public double getDespesaMensal(){
06         return super.getDespesaMensal() + alimentacaoMensal;
07     }
08     public void setDados() {
09         super.setDados();
10         Scanner sc=new Scanner (System.in);
11         System.out.println ("Quantas vezes você almoca na EACH no mes?");
12         int n=sc.nextInt();
13         System.out.println ("Quanto custa cada refeicao?");
14         double v=sc.nextDouble();
15         alimentacaoMensal=(doublen * v;
16     }
17 }
Java2html

quarta-feira, 15 de abril de 2015

Anotações

Perguntar aos alunos onde eles pesquisam sobre a linguagem.

Diferença entre retornar e imprimir na tela:
- Imprimir na tela é feito por System.out.println(...);
- retornar ocorre quando um método termina e a execução retorna ao fluxo de execução anterior. Neste momento é possível retornar um valor.

Caso o autor do método não deseje retornar nenhum valor, ele declara o método com tipo de retorno void. O retorno ocorre quando chega-se ao final do método ou quando for executado o comando return.

Caso deseje retornar um valor, ele declara o método com o tipo desejado. Desta forma ele se obriga a dizer o que quer retornar. Isto é feito passando um argumento no comando, ou seja: return <valor de retorno>. Todos os caminhos de computação existentes no código, inclusive os não usados, exigem return. Por exemplo:

int met (int a) {
    if (a>0) return 3;  // teste 1
    if (a<=0) return -3;  // teste 2
}

Ocorre erro na compilação do método acima pois há três caminhos de computação possíveis:

1-) teste 1 é true;
2-) teste 1 é false e teste 2 é true;
3-) teste1 e false e teste2 é false;

O caminho de computação 3 não tem return.

Alguém poderia dizer que o caminho 3 não ocorre pois a não pode assumir nenhum valor que torne os dois testes falsos. Concordo, MAS o compilador não analisa a lógica do código até esse nível, logo ele foi construído para exigir esse return.

Então o que retornar?? Já que não é executado, pode ser um valor qualquer?
Não é boa prática retornar um valor qualquer pois a maioria dos programadores espera que valores de retorno signifiquem algo, logo isto atrapalha o entendimento do código;
Nem sempre é tão fácil decidir se um caminho de computação será executado ou não (geralmente é difícil);
Programadores erram (e você também), embora sempre presumam que o que fazem funcionará corretamente. retornar um valor qualquer dificulta a localização de erros, fazendo você perder tempo e passar raiva.

Então o que é melhor fazer?
Reescrever o código para que ele não tenha caminhos que não são executados. Isto sempre é possível. No exemplo acima:


int met (int a) {
    if (a>0) return 3;  // teste 1
    return -3;  // se teste 1 é false, teste2 não é necessário pois será sempre true.
}
-----

Quero retornar mais de um valor (primitivo) com um return. Isso é possível?
Sim, você cria um objeto que contenha todos os valores e faz o método "retornar esse objeto".

------

Referências são variáveis através das quais acessa-se alguma outra entidade (por exemplo a instância de uma classe, um método ou outra variável).

Uma variável de tipo primitivo contém um valor que o tipo primitivo pode assumir. Por exemplo em
int a=125;

declaramos uma variável com identificador (nome) a, que contém 125.

Em objetos e tipos abstratos, por exemplo o Scanner normalmente faz-se:

Scanner sc= new Scanner( System.in );

esta linha especifica dois conjuntos de ações, por isso vou separá-la em duas:

Scanner sc;
sc=new Scanner( System.in );

a primeira linha é a declaração de uma variável com identificador (nome) sc, do tipo Scanner;

a segunda linha especifica dois subconjuntos de ações.
O operador de atribuição '=' opera sobre duas entidades (é binário) e armazena no operando da esquerda o valor contido no operando da direita.

O operando da direita é um comando 'new' aplicado a um método 'Scanner ( System.in )'.
O comando 'new' aloca quantidade de memória necessária para armazenar uma instância da classe  Scanner, inicializa estruturas de controle, invoca o método e retorna o ENDEREÇO para acessar o local de memória onde foi armazenada a instância.