Jump to content

[Duvida] Compilar vs Interpretar


Strabush
 Share

Recommended Posts

Boa tarde users do P@P.

Estou em fase de transferência do C pro Java. Notei que não há muita diferença, mas no entanto venho cá apresentar uma dúvida primária e gostaria que me pudessem ajudar.

Por exemplo, tenho o código em java, exemplo.java, para compila-lo no cmd(windows) faço "java exemplo.java" ou "javac exemplo.java"?

E para interpretar ?

Cumprimentos.

Link to comment
Share on other sites

Compilar, em Java, pode referir-se a dois processos:

1) A compilação do código fonte, presente nos ficheiros .java, para bytecode através do uso do compilador javac;

2) A compilação feita durante o arranque ou execução da aplicação por um dos componentes da JVM;

Para ti, como programador, o único processo de compilação que interessa é o primeiro. Pegas nos teus ficheiros de código fonte e passas os ditos ficheiros ao compilador, javac.

Para executares aplicações Java, então usas o comando java. Não interessa se vai ser interpretado ou não dado que até pode nem ser interpretado.

Portanto, javac para compilar, java para executar.

Se estás habituado a usar ferramentas de auxílio à compilação de software, como o make, para Java tens o Ant que pode ser útil já que compilar tudo manualmente com o javac pode ser um processo tedioso.

Estranho que do C para o Java não notes muita diferença porque o paradigma orientado a objectos costuma causar confusão para quem vem de C, mas é bom saber que a transição está a ser simples 😄

Edit:

Alteração nas variáveis de que forma? Uma instalação correcta do JDK deve tratar de todas as configurações necessárias em todos os sistemas operativos.

Link to comment
Share on other sites

Provavelmente as variáveis de ambiente que ele fala deve ser por causa do path para o javac...

Não achares muita diferença entre java e C é realmente estranho, são niveis diferentes de abstracção! A nao ser que estejas a usar Java para programares num paradigma procedimental.

Link to comment
Share on other sites

Tive de alterar o conteúdo do path, colocar a localização da pasta "jdkupdate_6_20".

Acabei de fazer uma espécie de Binary_Search em java, igualizinho ao C xD:

import java.io.*;
import java.util.*;

public class Main {
    static int count;

    public static int binary_search(int vct[], int size, int valor){
        int indice, limInf, limSup;
        limInf = 0;
        limSup = size - 1;
        count = 0;

        while (true) {
            count++;
            indice = (limInf + limSup) / 2;
            if(vct[indice] == valor) return indice;
            if(vct[indice] > valor) limSup = indice;
            if(vct[indice] < valor) limInf = indice + 1;
            if(limSup <= limInf) return -1;
        }

    }
    
    public static void main(String[] args) {
        int v[] = {2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40};
        int max = 20;
        int aux;

        aux = binary_search(v,max,6);
        System.out.print("Retorno da função = " +aux);

    }

}

Pretendo agora trabalhar com ficheiros, notei que há muitas bibliotecas específicas. Tenho uma dúvida, como especifico o caminho exacto do ficheiro, por exemplo "C:\(...)\example.txt"? O que tenho feito é isto:

in = new FileInputStream("example.txt"); 

Mas o NetBeans diz que não encontra o ficheiro, e ele está na mesma pasta que o código e class.

Link to comment
Share on other sites

Ora, e não é que isso de Java tem.... zero! 😄

Declaração de variáveis de forma errada, mau uso de variáveis de classe, nem as convenções de código Java são seguidas. É verdade que a sintaxe é bem parecida mas se continuas a programar em Java dessa forma vais desenvolver péssimos programas, não que não funcionem, mas não usarão Java como deve de ser.

Quanto a abrir o ficheiro, a forma como escreveste faz uso da working directory que no caso do NetBeans IDE é a pasta do projecto, não é a de código nem a de ficheiros compilados.

"C:\" é algo de Windows e deve ser evitado, além de impedir que a tua aplicação funcione noutros sistemas operativos, pode dar alguns problemas quando acedes a ficheiros de outras formas.

A classe File aceita uma String como caminho para o ficheiro e tem algumas variáveis de classe que podem ser usadas para criar o caminho de forma independente do sistema operativo. Podes e deves, sempre que possível, usar URLs e URIs em vez de caminhos criados manualmente.

Por exemplo:

this.getClass().getResource("/org/sergiolopes/teste/image.jpg");

Isto permite aceder a uma imagem que está no package org.sergiolopes.teste, é útil quando os ficheiros estão dentro dos vários packages juntamente com o código. Não é a única maneira mas é uma forma.

Se quiseres ficheiros que estão fora dos packages da tua aplicação podes criar o caminho usando as variáveis de classe da classe File, que te dão o separador de caminhos do sistema operativo sem que tenhas de te preocupar com isso.

Link to comment
Share on other sites

O erro estava nesta barra "\", é esta que devo usar "/". Tenho ainda muito a explorar neste Java, só hoje começei.

Já agora, dizes-me sff o que está errado sintaxe do mini-código acima? Só pra ver se reparo e começo a usar o Java como deve ser.

Link to comment
Share on other sites

Nem deves usar uma barra nem deves usar outra, deves usar as variáveis que a classe File te oferece porque a barra depende do sistema operativo.

Não é tanto uma questão de sintaxe, porque senão o teu código nem compilava, é mais do uso correcto da linguagem/tecnologia.

Começando pela escrita de código, que pode não ser considerada importante mas que ajuda quando queres mostrar o teu código a outros programadores de Java, não se usam underscores, isso é coisa de C, em Java usa-se CamelCase.

Quanto ao uso da linguagem, estás a usar variáveis estáticas, que são variáveis de classe, sem que as variáveis que tens tenham de ser de classe. Variáveis de classe têm algumas regras que as variáveis de instância não têm, e problemas associados que também não existem em outros tipos de variáveis.

Não estás a definir correctamente a visibilidade das variáveis, tendo em conta os princípios da linguagem.

Um exemplo alterado:

// Todas as classes devem ter um package definido, 
// nunca devem ser criada sem package
package learning.strabush; 

// Nunca se fazem imports destes, deves importar
// apenas as classes que precisas e não mais que isso, senão estás a
// adicionar todo um package, por vezes com milhares de classes, ao teu 
//código. É desnecessário e cria dependências entre o teu código e as bibiotecas.
// import java.io.*;
// import java.util.*;

// Dá nomes melhores às classes, afinal é com elas que vais interagir e 
// criar o teu programa.
public class Main {

    private int count; //variável de instância. Nada de static!

    // método de instância, não de classe, nada de static!
    public int binarySearch(int vct[], int size, int valor){
        int indice, limInf = 0, limSup = size - 1;

        // se é usada  internamente não devia ser de instância 
        // ou de classe mas sim local como as outras
        count = 0;

        while (true) {
            count++;
            indice = (limInf + limSup) / 2;
            if(vct[indice] == valor) return indice;
            if(vct[indice] > valor) limSup = indice;
            if(vct[indice] < valor) limInf = indice + 1;
            if(limSup <= limInf) return -1;
        }
    }
   
    public static void main(String[] args) {
        int v[] = {2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40};
        int max = 20;
        int aux;

        // instanciar a nossa classe para se usarem os métodos de instância
        Main m = new Main();

        aux = m.binarySearch(v, max, 6);
        // system.out e concatenação de Strings serve para debug e para aprender
        // mas uma aplicação real não faz uso deste tipo de código. Esporadicamente
        // system.out mas não concatenação de Strings. São dois processos lentos.
        System.out.print("Retorno da função = " + aux);
    }
}

Num exemplo tão simples é complicado explicar a diferença de conceitos, mas o que fizeste foi pegar na abordagem procedimental de C e converter as diferenças de sintaxe para Java, mas Java é uma linguagem orientada a objectos e deve ser usada nesse sentido, senão além de não estares a aproveitar as vantagens dos objectos estás a desenvolver mau código e más aplicações. Embora possa parecer desnecessário neste exemplo, deves fazer os possíveis para usar as características da linguagem desde início, por mais básico que seja, de modo a aprenderes a fazer uso delas.

Na Wiki do P@P tens um tutorial de Java que podes seguir/ver, e o tutorial da Oracle é também bastante bom, http://java.sun.com/docs/books/tutorial/reallybigindex.html

Link to comment
Share on other sites

Antes de mais nada obrigado Knitter.

Não percebi o porquê do :

m.binarySearch(v, max, 6);

, mais precisamente o "m.".

EDIT: Forget it, já percebi, não tinha reparado na relação com a linha de código anterior a essa. Preciso realmente entender melhor as classes e tipos das mesmas. Isto de static, public e private parece ser diferente de C em termos de compreensão.

Link to comment
Share on other sites

Vejamos... os erros:

import java.io.*;
import java.util.*;

Sempre que possível indica-se a lista exaustiva do que se usa. Tanto para ajudar quem escreve e lê como para "pesar" menos o programa.

public class Main {
    static int count;

Verifica se consegues viver sem esta variável.

Se precisares mm dela, então usa assim:

private static int count;

Há que manter a segurança criando as variáveis restringindo o acesso ao menos possível.

    public static int binary_search(int vct[], int size, int valor){

aonde está:

int vct[]

é que usa-se assim:

int[] vct

e para o nome do método n se usa o "_" mas o Cam|Case

Em vez de usar o _ escreve-se a 1ª letra da 1ª palávra em maiúscula. Então seria:

binarySearch(...)

        int indice, limInf, limSup;

Para melhorar a leitura do código nunca se declara mais que uma variável por linha

        limInf = 0;
        limSup = size - 1;
        count = 0;

        while (true) {

Em java nunca se escreve assim. while(true) ou while(false) nunca se usa.

Em vez disso declara-se uma variável do tipo boolean e é esta que é actualizada para controlar o funcionamento do while.

Alternativamente podes usar uma outra comparação, por exemplo, while(i < 50)

            count++;
            indice = (limInf + limSup) / 2;
            if(vct[indice] == valor) return indice;
            if(vct[indice] > valor) limSup = indice;
            if(vct[indice] < valor) limInf = indice + 1;
            if(limSup <= limInf) return -1;

Os if, por motivo de leitura, n se escreve assim. cmo escreveste. é assim:

if(/*boolean sentense*/)

/*what happens*/

n esquecer a tabulação antes de: /*what happens*/

e outra coisa:

esse desenvolvimento n está correcto.

Para uma coisa desse tipo qd:

limSup <= limInf || vct[indice] == valor

ele saí do while, certo?

Então podias por dento do while isto:

while(limSup <= limInf || vct[indice] == valor)

e no final:

return (vct[indice] == valor)? indice : -1;

        }

    }
    
    public static void main(String[] args) {
        int v[] = {2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40};
        int max = 20;
        int aux;

        aux = binary_search(v,max,6);
        System.out.print("Retorno da função = " +aux);

Por motivos de simprificação e de melhoar o código as 5 linhas q estão em cima disto deviam ser assim:

System.out.print("Retorno da função = " +binary_search(v,max,6));

    }

}

Acho q já apontei o q é mais importante.

Boa sorte

ADD:

...

Quanto ao uso da linguagem, estás a usar variáveis estáticas, que são variáveis de classe, sem que as variáveis que tens tenham de ser de classe. Variáveis de classe têm algumas regras que as variáveis de instância não têm, e problemas associados que também não existem em outros tipos de variáveis.

...

Segundo artigos q andei a ver e aulas de Faculdade:

Faz sentido o q tu dizes mas perante um caso deste tipo usar métodos com o modificador static está correcto.

"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Link to comment
Share on other sites

Como estavas a usar a palavra reservada static, isso significava que podias aceder aos métodos e às variáveis usando a classe, a palavra reservada indica que o método ou a variável passam a ser da classe e por isso podem ser acedidos com o nome da classe, sem serem instanciados.

Isto é, com a tua versão, seu eu fizer Main.binary_search, estou a aceder a um método estático da classe Main, neste caso, como estás dentro da própria classe Main podes omitir o seu nome. Por isso é que se invocares só o método, o Java sabe que é um método estático da classe onde estás.

No entanto, nós devemos usar variáveis de instância e não variáveis de classe. Estas últimas têm um propósito muito específico e um mecanismo de iniciação diferente das outras, o mesmo acontece para os métodos, há diferenças na forma como o Java lida com métodos e varáveis de classe, a começar pela forma como lhes acedemos.

O que fiz foi passar a ter variáveis de instância, ora variáveis de instância são variáveis que só existem dentro de uma instância de um objecto. Considera o que tinhas em C, tinhas variáveis normais e ponteiros, com as variáveis normais era só declarar e podias começar a usar directamente, não tinhas de reservar memória para o variável porque o C fazia isso por ti. No caso de ponteiros, tinhas de reservar memória primeiro, tipicamente com um malloc ou uma função similar, sem reservares a memória não podias aceder ao ponteiro para guardar dados.

Em Java, uma instância de um objecto funciona de forma similar, tens uma referência para um objecto, neste caso o object m do tipo Main, é uma variável que irá apontar para um objecto. Antes de a poderes usar tens de a instânciar, tens de reservar a memória para esse objecto, por isso usa-se o construtor da classe o operador new. Portanto Main m = new Main() é a declaração de uma variável chamada m, tipo Main e faz logo a reserva do espaço em memória, onde o objecto vai residir.

Depois de teres uma instância podes aceder aos métodos e atributos de intância, daí o m.binarySeach, estamos a aceder ao método binarySearch que existe num objecto do tipo Main, neste caso o objecto identificado pela variável m.

Há que refira a isto como "enviar uma mensagem ao objecto", de forma simples é aceder aos seus métodos e variáveis, quando a visibilidade permite. Estes métodos e variáveis apenas existem depois de teres construído o objecto, se tentares usar antes, vais ter erros de compilação/execução.

Se precisares mm dela, então usa assim:

private static int count;

Não, isto seria trocar uma variável estática com visibilidade de package por uma estática com visibilidade privada, e o erro maior está no facto de ser estática.

aonde está:

int vct[]

é que usa-se assim:

int[] vct

São sintaxes que fazem o mesmo, não há convenção para uma ou para outra, e o Java permite as duas. É mais comum ver a segunda do que a primeira, mas não há inconveniente de se usar a primeira.

Em java nunca se escreve assim. while(true) ou while(false) nunca se usa.

Em vez disso declara-se uma variável do tipo boolean e é esta que é actualizada para controlar o funcionamento do while.

Alternativamente podes usar uma outra comparação, por exemplo, while(i < 50)

Disparate, sem ofensa isso não veio de algum professor mais esquisito? Não há qualquer razão para se preferir uma versão a outra, usa-se a que se achar melhor, ter a variável ou ter directamente o valor dá no mesmo, para quê ter uma variável que nunca se utiliza/altera?

Por motivos de simprificação e de melhoar o código as 5 linhas q estão em cima disto deviam ser assim:

System.out.print("Retorno da função = " +binary_search(v,max,6));

Aqui é uma questão de opinião, não considero o código acima mais simples nem melhor, apenas diferente, acho que fica ao critério de cada um.

Link to comment
Share on other sites

Obrigado pelos conselhos brunoais.

Usei o count fora das funções propositadamente para testar variáveis globais.

O Java não tem variáveis globais. As variáveis estáticas podem ser vistas como globais não não o devem ser. Se removeres a palavra static da variável vês que ela está disponível em toda a classe, em todos os métodos, só não está disponível em blocos de código estáticos.

Link to comment
Share on other sites

Vai ler o tutorial na wiki do P@P, pode ser que tenha explicado melhor aí 😄 , http://wiki.portugal-a-programar.org/java:tutorial:00_home

Uma classe != objecto. Uma classe é um molde, é algo que define o comportamento dos objectos, é o que cria, se quiseres aproximar ao C e às estruturas, um tipo de dados novo.

Um objecto é o resultado dessa classe com uma zona de memória reservada. Se pensarmos nas estruturas, quando criavas uma estrutura em C não a podias usar, era apenas código que escrevias e definia como seria uma variável daquele tipo. Uma classe é similar (se aproximarmos de forma grosseira) no sentido em que te define o comportamento dos objectos.

Mas tal como para usares a estrutura de C tinhas de ter uma variável desse tipo, para usares os métodos de instância tens de ter um objecto criado. E um objecto cria-se a partir do construtor.

Classe => Define o comportamento dos objectos, é um tipo e dados;

Objecto => É criado com o operador new e com o construtor e deixa-te aceder aos métodos e atributos. Existe em memória, tem um estado, tem comportamento, responde a mensagens, etc.

Link to comment
Share on other sites

Disparate, sem ofensa isso não veio de algum professor mais esquisito? Não há qualquer razão para se preferir uma versão a outra, usa-se a que se achar melhor, ter a variável ou ter directamente o valor dá no mesmo, para quê ter uma variável que nunca se utiliza/altera?

Se tentares usar while(true), por exemplo, o java compiler lança um warning.

"[Os jovens da actual geração]não lêem porque não envolve um telecomando que dê para mirar e atirar, não falam porque a trapalhice é rainha e o calão é rei" autor: thoga31

Life is a genetically transmitted disease, induced by sex, with death rate of 100%.

Link to comment
Share on other sites

Deixa la ver se consigo contribuir para a tua iniciação no mundo do POO.

Em Java não tens variáveis globais como já foi dito pelo Knitter, tudo pertence a uma classe! Tudo está contextualizado dentro de uma classe.

Podes ver as classes como as structs no C, quando fazes:

typedef struct Pessoa{
   int idade;
   char *nome;
}

isto é uma matriz digamos assim para construir pessoas entao quando precisas de uma pessoa usas o malloc certo?

Em Java é um bocado isto apesar de que as classes são matrizes para não só dados mas sim funções (métodos) e o malloc no Java é o new (se é que me permitem fazer esta analogia mas ajudou-me lol).

Podemos então fazer a distinção da classe e instância/objecto, Classe -> matriz/forma para os objectos e os objectos ou instâncias são a realização (instanciação em memória e consequente habilitação para se interagir com ela).

Claro está que isto é somente um vértice da ponta do iceberg mas com tempo tudo encaixa e não é nada de complicado 😄

Link to comment
Share on other sites

Obrigado chuckytuh.

Estive agora a lutar com um erro esquisito:

Exception in thread "main" java.lang.NoClassDefFoundError: Main (wrong name: fpp

roject/Main)

        at java.lang.ClassLoader.defineClass1(Native Method)

        at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)

        at java.lang.ClassLoader.defineClass(ClassLoader.java:616)

        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:14

1)

        at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)

        at java.net.URLClassLoader.access$000(URLClassLoader.java:58)

        at java.net.URLClassLoader$1.run(URLClassLoader.java:197)

        at java.security.AccessController.doPrivileged(Native Method)

        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)

        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)

        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)

        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

Could not find the main class: Main.  Program will exit.

Após várias tentativas, mudança das variáveis de ambiente, reinstalação, notei que isso só acontecia qndo o ficheiro .java tinha:

package local_do_ficheiro;

(...) no cabeçalho.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.