Em diversas linguagens de programação existe o conceito de variável. Uma variável corresponde a uma posição de memória. Uma posição de memória pode guardar um valor. Uma declaração de variável define seu tipo e o identificador (nome) e também outros atributos. Uma das coisas que podemos fazer com uma variável é usa-la como alvo de uma iniciação/inicialização ou ainda como alvo de uma operação de atribuição (assignment).
A sintaxe simplificada para a declaração de uma variável
é:
<tipo> <nomeDeVariavel>;
Esta forma apenas declara a variável; outra sintaxe:
<tipo> <nomeDeVariavel>=<expressao>;
Esta segunda forma corresponde a declarar e iniciar/inicializar o valor
da posição de memória correspondente à variável.
A sintaxe simplificada de um comando ou operação de atribuição
é:
<identificador da variável> = <expressão>;
Neste comando o valor correspondente à expressão é
copiado para a posição de memória correspondente à
variável. Note que o antigo valor é perdido. Só podemos
atribuir um valor para uma variável que tenha sido declarada.
A sintaxe e semântica de uma <expressão>
serão definidas mais tarde; os programas abaixo apresentam expressões
simples e bem intuitivas. Um exemplo de tipo em Java é o tipo int
correspondente a um subconjunto finito do conjunto dos inteiros da Matemática
e outro exemplo é o tipo double correspondente a um subconjunto
finito do conjunto dos números reais da Matemática.
O trecho de programa a seguir ilustra algumas declarações
de variáveis e comandos de atribuição:
int v1;
double v2;
v1=123;
v2=3.1415;
No trecho acima são dclaradas duas variáveis, a variável
v1 é do tipo int e a variável v2 é do tipo double.
Vemos ainda dois comandos de atribuição usando expressões
simples.
O tipo restringe os valores que podem ser atribuidos a uma variável.
A restrição de tipo para uma variável acarreta maior
disciplina por parte do programador e permite programas mais eficientes
e com menor probabilidade de erros. O trecho a seguir não é
permitido na linguagem Java:
int v1;
v1=3.1415; /*erro! */
O compilador emite um erro dizendo que a constante 3.1415 é
do tipo double e não pode ser utilizada na atribuição
para uma variável do tipo int (mais a frente será visto como
que valores de tipos diferentes do tipo da variável podem ser utilizados
em expressões de atribuição).
A associação de um tipo a uma variável na Computação
é similar à amarração de uma variável
a um domínio como ocorre na Matemática. No entanto deve ser
ressaltado que o conceito de variável em Computação
e o conceito de variável em Matemática são conceitos
que apresentam aspectos distintos. Uma das distinções mais
notáveis é que uma variável na Matemática,
usualmente, não tem um valor específico. Considere a
expressão da Matemática
y=x+3
A variável x não tem um valor, esta expressão
pode ser interpretada como representando o lugar geométrico dos
pontos de um plano correspondentes a uma reta. A variável (da Matemática)
x pode tomar qualquer valor real. As vezes os autores cuidadosos explicitam
que a variável x "pode tomar valores em" ou "pertence ao" domínio
dos números Reais, outros autores assumem que o leitor irá
deduzir isso. Na Computação, uma variável, no
escopo onde ela é válida, sempre tem um determinado valor
associado a ela, este valor possivelmente muda ao longo do tempo, mas a
cada momento o valor de uma variável é único. Na Matemática,
uma expressão envolvendo uma variável, deve sempre considerar
que aquela variável, em todo ponto que ela aparece, tem sempre um
mesmo valor. Na Computação, em particular na linguagem Java,
isto não é verdade, considere o trecho de programa abaixo:
int x;
x=(x=((x=1)+1)+1);
Na expressão acima a variável x aparece três vezes.
Em cada uma das vezes x tem um valor distinto associado a ela. (A
expressão acima não tem muito sentido (melhor escrever x=3;)
mas, mais a frente na disciplina, veremos o conceito de função
ou método e teremos oportunidade de construir expressões
onde este aspecto faça mais sentido)
A linguagem Java tem oito tipos primitivos:
O trecho de programa Java correspondente a System.out.println(<argumento>)
ou System.out.print(<argumento>) corresponde a invocar a impressão
do argumento no video do sistema. O argumento deve ser do tipo String (o
tipo String não é um tipo primitivo e será visto mais
a frente na disciplina). A linguagem Java permite que o programador use
como argumento uma variável ou expressão de um tipo que não
seja String, e neste caso é feita uma conversão do
argumento para o tipo String. Os programas abaixo ilustram declarações
de variáveis e comandos de atribuição conforme discutido
acima. Observe o uso de "comentários", eles podem ser introduzidos
através do uso de duas barras: //
ou ainda podem ser delimitados através do "inicio de comentário":
/* (barra seguido de asterisco) e "fim de comentário": */
(asterisco seguido de barra).
Literais
Um literal é a forma de representar no texto de um programa um
valor de um certo tipo. A linguagem Java apresenta 6 tipos de literais:
IntegerLiteral
FloatingPointLiteral
BooleanLiteral
CharacterLiteral
StringLiteral
NullLiteral
Os literais String (cadeias de caracteres) consistem de sequências de caracteres delimitadas por aspas (p.ex. "A", "AB", "ABC", "ABCD"). Existem também expressões do tipo String. O operador + (adição) além de representar a soma de inteiros ou soma de ponto flutuante pode representar a concatenação de cadeias de caracteres. A cadeia "ABCD" é equivalente à expressão "AB" + "CD" ou à expressão "A" + "BCD".
Os literais inteiros podem ser expressos por sequencias de caracteres em decimal (p.ex. 1, 23, 456), sequencias de caracteres em hexadecimal precedidas port 0x ou 0X (0x1, 0xA, 0xFF02) ou sequencias de caracteres em octal precedidas por 0 (sim! um zero à esquerda! p.ex. 01, 023, 0456). Os literais inteiros podem apresentar como sufixo a letra L maiúscula ou minúscula, neste caso o literal inteiro passa a ser do tipo long (p. ex. 23L, OXAL, 026L). Os literais inteiros podem designar valores para variáveis do tipo int, long, short, byte e char.
A linguagem Java tem regras sobre quais literais com quais valores podem
ser atribuidos a variáveis inteiras. O compilador faz as conversões
necessárias e internamente todos valores são representados
através de zeros e uns. O trecho de programa abaixo mostra uma inicialização
ou iniciação e a impressão deste valor em diferentes
bases:
Os literais de ponto flutuante tem as seguintes partes: parte inteira, ponto decimal, parte fracionária, expoente e sufixo. O expoente, se presente, é indicado pela letra e ou E seguido de um inteiro. Os literais de ponto flutuante podem designar valores para variáveis do tipo float e double. O maior literal do tipo float é 3.40282347E+38F, o menor positivo finito diferente de zero é 1.40239846E-45F. O maior literal double positivo é 1.79769313486231570E+308, o menor positivo diferente de zero é 4.94065645841246544E-324
Os tipos float e double, segundo a recomendação do padrão
IEEE 754 podem representar infinito. Não existem literais para infinito
devem ser usadas expressões do tipo 1f/0f ou -1d/0d
Os literais float e double somente podem ser expressos na base dez.
Os literais de caracteres são sequências de caracteres
entre apóstrofos. O literal correspondente à letra a minúscula
é 'a', este é um exemplo de literal de um só
caractere mas existe também a Seqüência de Escape.
A representação da barra invertida: '\\', a representação
de aspas '\"' e a representação do apostrofo:
'\''.
Alguns literais de caracteres representam caracteres que podem ser tratados
de forma especial por alguns dispositivos de entrada e saída: '\n'
(newline), '\t' (tabulation), '\b' (backspace), '\r' (return), '\f' (form
feed). É importante entender que um caractere em um vídeo
ou impressora, em geral, corresponde a um valor do tipo int, a linguagem
Java possui o tipo char para poder explicitar que estamos tratando
de um valor int que deve ser considerado como um caractere. Estes dois
tipos tem similaridades mas são distintos! Considere o programa
abaixo:
class prog{
public static void main(String[] args){
int i;
char c;
i=65;
c=65;
System.out.println(i);
System.out.println(c);
}
}
O programa acima imprime uma linha com:
65
correspondente à conversão do valor de i em um valor
do tipo String e uma outra linha com:
A
correspondente à conversão do valor de c em um valor
so tipo String. Na convenção seguida por Java o caractere
A
('A') é codificado usando o valor int 65. Modifique o programa acima
para poder obter diferentes caracteres quando da impressão de um
valor de uma variável do tipo char.
Complete a tabela de compatibilidade de atribuição
de literais e variáveis (faça os programas e verifique!)
As colunas são os tipos de literais e as linhas representam os tipos
de variáveis.
| literal
tipo var |
Integer | Floating | Boolean | Character | String | Null |
| byte | ok | x | x | |||
| short | ok | x | x | |||
| int | ok | x | x | |||
| long | ok | x | x | |||
| char | ok | x | x | |||
| float | ok | x | x | |||
| double | ok | x | x | |||
| boolean | ok | x | x | |||
| referência | x | x | x | x | (*) | ok |
(*) um literal String para poder ser atribuído a uma variável exige que a classe desta variável seja do tipo String ou descendente desta classe, isto será visto mais à frente na disciplina.
A linguagem Java permite algumas atribuições entre variáveis
de tipos diferentes. Considere o trecho de programa abaixo:
int i=3;
long j=2;
j=i; /* permitido: valor de um tipo mais
restrito para um menos restrito */
Mas neste outro trecho há um problema:
int i=3;
long j=2;
i=j; /* erro!!
*/
A linguagem Java exige que, na atribuição de um valor
de tipo menos restrito para uma variável de tipo mais restrito,
seja usado, de forma explícita, um mecanismo denominado "elencamento"
(cast). O "elenco" de valores de uma variável do tipo long
é maior que o "elenco" de valores do tipo int. A linguagem Java
exige que o programador explicite o elencamento do valor long para um valor
int. Grosseiramente é como se a linguagem obrigasse o programador
a declarar que ele sabe que aquela atribuição pode resultar
em problemas, ou seja é mais uma medida de disciplinamento do programador.
int i=3;
long j=2;
i= (int) j; /* ok */
j=9999999999L;
i= (int) j; /* permitido mas o valor em
j não e' preservado */
A conversão em um elencamento envolve,
em geral, abandonar alguns bits de mais alta ordem. No trecho abaixo a
variável b é iniciada com um valor que no contexto do tipo
short é negativo, mas que ao ser elencado perde alguns bits e passa
a ser, no contexto do tipo byte, um valor positivo! No trecho abaixo o
conteúdo de s é -134 e o conteúdo de b é 122.
short s= -134;
byte b = (byte) s;
System.out.println(s);
System.out.println(b);
Uma outra tabela trata da questão da atribuição
entre variáveis de tipos primitivos diferentes. Considere a atribuição
A=B; O tipo de A corresponde às linhas e o tipo de B corresponde
às colunas. Complete a tabela abaixo, onde inválido
significa que a linguagem não permite a atribuiçao nem mesmo
com o uso de elencamento (cast), auto significa que a conversão
é feito de forma implícita e elencar significa que
a atribuição só é possível através
do uso de elencamento.
| A B-> | long | int | short | char | byte | double | float | boolean |
| long |
|
auto | auto | auto | auto | elencar | elencar | inválido |
| int | elencar |
|
inválido | |||||
| short | elencar | elencar |
|
inválido | ||||
| char | elencar | elencar |
|
inválido | ||||
| byte | elencar | elencar |
|
inválido | ||||
| double | auto | auto |
|
inválido | ||||
| float | auto | auto |
|
inválido | ||||
| boolean | inválido | inválido | inválido | inválido | inválido | inválido | inválido |
|
Observe que a linguagem Java não permite a mistura do tipo boolean com nenhum outro tipo. Em algumas linguagens, como por exemplo C e C++ é permitido tratar valores booleanos como sendo inteiro e vice-versa. Nestas linguagens o valor false corresponde ao valor zero (zero inteiro) e o valor true a valores diferentes de zero.
Exercícios:
Um dos problemas enfrentados por quem aprende novos conceitos são
as colisões de representação. Na linguagem Java um
símbolo tal como como o 1 pode representar
um valor do tipo int, um valor do tipo char ou um valor do
tipo String (que será visto a frente) ou um valor do tipo short.
Não é uma questão trivial entender que o valor int
representado por 1 não é a mesma
coisa que o valor char representado por 1.
O problema é que estamos falando de diferentes "uns" representados
pelo mesmo símbolo: 1. O valor char 1
corresponde ao valor int 49.
Escreva um programa em Java que ilustra o que foi dito acima.