Você está na página 1de 10

Variveis Tipos e Expresses

Variveis e memria
A memria pode ser entendida como uma seqncia de clulas de tamanho fixo, nas quais se pode armazenar informao. Cada clula endereada atravs de um nmero seqencial conhecido como endereo. Em um dado momento, uma clula armazena apenas um nico valor. Para facilitar a manipulao da memria pelo programador as linguagens de programao nos fornecem uma abstrao conhecida como varivel. Uma varivel um nome (ou rtulo) que est associado a uma rea da memria (localizada atravs de seu endereo), assim o programador no precisa se preocupar em usar endereos na memria, utilizando apenas nomes intuitivos escolhidos atravs de bom senso. Fica a cargo de o compilador saber como localizar certo nome na memria, ou controlar as regies nas quais cada varivel deve existir. Cada varivel possui um tipo associado, isto , cada varivel possui uma associao com o tipo especfico de dado que ela deve armazenar, e um tipo de dado define um conjunto de valores e operaes. Uma vez que cada tipo pode possuir um tamanho diferente, cada varivel pode ocupar um tamanho (ou nmero de clulas) diferente na memria.

Rigidez de tipos
C# uma linguagem com rigidez de tipos (em ingls, strongly typed). Em uma linguagem com rigidez de tipos voc deve declarar o tipo de cada varivel que voc cria (por exemplo, inteiros, nmeros reais, cadeias de caracteres, etc.) e o compilador ir auxili-lo a prevenir erros de programao garantindo que apenas os dados dos tipos corretos so associados s variveis declaradas. Dessa forma, os tipos corretos devem ser usados apenas nos contextos adequados a esse tipo (em operaes de atribuio e passagem de parmetros, por exemplo). Entretanto, algumas operaes de converso implcita podem ocorrer, como por exemplo de int para double ou de int para float.

Tipos simples
A maioria das linguagens orientadas a objetos tem dois tipos distintos: tipos intrnsecos linguagem (tipos primitivos ou simples) e tipos que podem ser criados pelos usurios da linguagem (classes). Tipos primitivos so geralmente tipos simples, como caracteres, inteiros ou nmeros reais. Classes, por outro lado, so tipos mais elaborados cujos membros podem ser tipos intrnsecos ou outras classes. Dois conjuntos discretos de tipos geralmente causam uma srie de problemas de compatibilidade. Portanto, em C#, apesar de podermos separar conceitualmente os tipos entre tipos simples e classes, no temos problemas com esse tipo de compatibilidade, j que em C# todo tipo na verdade um objeto. Alm disso, todos os objetos so derivados implicitamente de uma nica classe base, System.Object. A discusso sobre o que realmente so classes

ou o significado exato de derivao de uma classe ser exposta com mais detalhes na Parte 2 sobre Orientao a Objetos. Em C#, os tipos simples ou primitivos podem ser classificados em: Tipos numricos o Inteiros o Reais ou ponto flutuante o Decimais Tipo booleano Caracteres unicode Strings System.Object (discutido na Parte 2) Alm disso, os tipos so subdivididos em tipos simples de valor e tipos simples de referncia. A principal diferena entre eles a maneira como eles so armazenados na memria. Um tipo de valor, tem seu valor armazenado diretamente no endereo associado varivel, portanto mais eficiente. J um tipo de referncia contm associado ao nome da varivel apenas o endereo do tipo, que se localiza em outra posio da memria e acessado indiretamente. Todos os tipos simples so tipos de valor, exceto por System.Object e String. E todos os tipos definidos pelo usurio so tipos de referncia, exceto por struct, que ser discutido na Parte 2. Tipos simples de valor em C# Tipo
byte char bool sbyte short ushort int uint float

Tamanho (bytes) 1 1 1 1 2 2 4 4 4 Sem sinal (0 255) Caractere Unicode

Descrio

Verdadeiro (true) ou falso (false) Com sinal (-128 127) Com sinal (-32,768 32,767) Sem sinal (0 65,535) Inteiro com sinal, valores entre -2,147,483,648 e 2,147,483,647 Inteiro sem sinal, valores entre 0 e 4,294,967,295 Nmero de ponto flutuante. Armazena valores de aproximadamente +/- 1.5 * 10-45 at aproximadamente +/- 3.4 * 1038 com 7 dgitos significativos. Nmero de ponto flutuante de preciso dupla. Armazena valores de aproximadamente +/- 5.0 * 10-324 at aproximadamente +/1.7 * 10308 com 15-16 dgitos significativos.

double

decimal long ulong

16 8 8

Preciso fixa, at 28 dgitos e a posio do ponto decimal. Requer o sufixo "m" ou "M". Inteiros com sinal, desde -9,233,372,036,854,775,808 at 9,233,372,036,854,775,807 Inteiros sem sinal de 0 at 18,446,744,073,709,551,615.

Tipos inteiros Geralmente, se decide qual tamanho de inteiro utilizar (short, int ou long) baseado na magnitude do valor que se deseja armazenar. Por exemplo, um ushort pode somente armazenar valores de 0 at 65,535 enquanto um ulong pode armazenar valores de 0 at 4,294,967,295. Entretanto, o custo de memria razoavelmente barato e o custo de um programador cada vez mais caro; a maior parte do tempo voc ir simplesmente declarar suas variveis como sendo do tipo int, a menos que exista uma boa razo para no o fazer. Os tipos com sinal so os tipos numricos escolhidos pela maioria dos programadores, a menos que eles tenham uma boa razo para utilizar um tipo sem sinal. Embora voc possa se tentado a utilizar um ushort (sem sinal) para dobrar os valores positivos de um short (com sinal), aumentando o maior valor positivo de 32,767 para 65,535, mais fcil e prefervel utilizar um inteiro com sinal (int), com um valor mximo de 2,147,483,647. melhor utilizar uma varivel sem sinal quando o fato do valor ser positivo uma caracterstica inerente do dado. Por exemplo, se voc tivesse uma varivel para armazenar a idade de uma pessoa voc usaria um inteiro sem sinal (uint) porque uma idade no pode ser negativa. Tipos reais Os tipos float, double e decimal oferecem vrios graus de preciso e tamanho. Para a maior parte dos nmeros fracionrios pequenos float recomendado. Note que o compilador assume que todo nmero com um ponto decimal do tipo double, a menos que indicado de forma diferente. Para representar um literal do tipo float, adicione o sufixo f ao nmero.
float numeroReal = 57f; float outroNumeroReal = 1.55f;

Tipos de caracteres O nico tipo de caractere disponvel em C# o tipo char. O tipo char representa um caractere em formato Unicode. Para representar de forma literal um caractere simples basta apenas envolve-lo em aspas simples, por exemplo 'A'. Para representar outros caracteres, precisamos utilizar caracteres de controle, por exemplo '\u0041' um caractere Unicode, '\t' uma tabulao, '\n' um caractere de nova linha.

char letraA = 'A' char unicode = '\u0041'

Tipos booleanos Tipos booleanos so o resultado de operaes lgicas como comparaes de igualdade, desigualdade, etc. ou simplesmente uma representao de um significado lgico particular. Diferentemente de C e C++, C# possui um tipo booleano explcito chamado de bool. Os valores possveis para uma varivel booleana so somente true ou false, isto , verdadeiro ou falso respectivamente. Valores inteiros no representam valores booleanos em C# e no existe nenhum tipo de converso implcita. Converso de tipos simples Tipos podem ser convertidos implicitamente ou explicitamente. As converses implcitas ocorrem automaticamente; o compilador se encarrega disso. Converses explcitas acontecem somente quando explicitamente indicadas pelo programador, e so conhecidas pelo termo em ingls cast (de forjar ou dar molde, forma). Deve-se tomar muito cuidado j que ao explicitar uma converso o compilador acredita que o programador sabe exatamente o que est fazendo, e dessa forma algum erro pode passar desapercebido. Converses implcitas acontecem automaticamente e se garante que no perdem informao. Por exemplo, possvel fazer uma converso implcita de um short para um int, j que independentemente do valor armazenado no short no haver perda de informao ao convert-lo num int.
short s = 42; int i = x; // converso implcita

Ao tentar converter no outro sentido, pode-se certamente perder informao caso o valor do int seja maior que 32,767, e nesse caso ele ser truncado durante a converso. O compilador no realizar uma converso implcita de int para short.
short s; int i = 500; s = i; // erro de compilao

Nesse caso, deve-se realizar a converso implcita, utilizando o operador de converso.


short s; int i = 500; s = (short) i; // compila, mas pode perder informao

Declarao de varivel
Podemos declarar variveis de qualquer um dos tipos bsicos ou dos tipos definidos pelo usurio. As variveis podem ser simplesmente declaradas ou declaradas e inicializadas simultaneamente. Como j sabemos, a estrutura da declarao simples e consiste do tipo da varivel seguido pelo nome e opcionalmente o sinal de igual e um valor inicial.

string str; int num = 10; bool b = false;

Podemos declarar vrias variveis do mesmo tipo, separando as declaraes por vrgula e omitindo o tipo nas declaraes aps a primeira.
string s1="ABC", s2="xyz"; int x,y,z; double u=1.0,v,w=5.5;

Comando de atribuio O comando de atribuio utilizado para atribuir ou mudar o valor de uma varivel. E sua forma padro :
varivel = expresso;

Onde varivel o nome de uma varivel e expresso qualquer expresso que retorne um valor. Aps a execuo do comando, o valor anterior perdido e varivel passa a ter o valor da expresso. A execuo do comando se d da seguinte forma, primeiramente o valor de expresso calculado e posteriormente atribudo varivel. Dessa forma atribuies do tipo z = z + 1; fazem sentido, j que z + 1 calculado e tem o resultado atribudo varivel z. So atribuies vlidas:
int x = z = b = x,z; bool b; z + 10; z + 1; true;

Atribuio definida C# requer que as variveis sejam inicializadas antes que sejam usadas. Caso se tente utilizar uma varivel sem valor definido compilador ir mostrar uma mensagem de erro durante a compilao. Esse tipo de restrio conhecido como atribuio definida (ou definite assignment, em ingls) e uma exigncia de C#.

Expresses e operadores
Uma expresso uma seqncia de operadores e operandos que especificam uma computao e retornam um valor. C# possui operadores unrios, operadores binrios e um operador ternrio. Podemos construir expresses complexas, pois uma expresso pode ser considerada um operando, como o operando (1 + 2) no seguinte exemplo:
((1 + 2) / 3)

Precedncia de operadores Quando uma expresso contm mltiplos operadores, a precedncia dos operadores controla a ordem na qual os operadores individuais so avaliados. Quando os operadores tm a

mesma precedncia, sua associatividade determina a ordem de avaliao. Os operadores unrios e os operadores binrios (com exceo dos operadores de atribuio) so associativos esquerda e so avaliados da esquerda para a direita. Os operadores de atribuio e o operador condicional (ternrio) so associativos direita e avaliados da direita para a esquerda. Por exemplo:
1 + 2 + 3 * 4

Ser avaliado como:


((1 + 2) + (3 * 4))

Isso ocorre uma vez que * tem uma precedncia maior do que +, e + um operador binrio com associatividade esquerda. sempre possvel inserir parnteses para mudar a ordem de avaliao ou para eliminar dvidas na ordem da avaliao. Os operadores de atribuio tambm retornam um valor, o valor atribudo varivel, e possuem associatividade direita, permitindo escrever expresses como essa:
int x,y,z; x = y = z = 10;

E so avaliadas como:
int x,y,z; x = (y = (z = 10));

Portanto o resultado final da expresso atribuir s variveis x, y e z o valor 10. O que nos mostra uma forma interessante e econmica de atribuir um mesmo valor a vrias variveis diferentes. Tabela de precedncia de operadores A tabela abaixo lista a maioria dos operadores em C# em ordem de precedncia. Operadores na mesma clula da tabela tm a mesma precedncia. A precedncia crescente de cima para baixo. Alguns dos operadores mostrados na tabela sero discutidos em mais detalhes posteriormente, em especial aqueles que lidam com objetos. Categoria Primrios Operadores Agrupamento: (x) Acesso a membro: x.y Chamada de mtodo: f(x) Indexao: a[x] Ps incremento: x++ Ps decremento: x-Chamada do construtor: new T

Unrios

Valor positivo (passivo): + Valor negativo: Negao: ! Complemento bit a bit: ~ Pr incremento: ++ Pr decremento: -Converso de tipos: (T)x Mutiplicao: * Diviso: / Resto da diviso: % Soma: + Subtrao: Deslocar bits esquerda: << Deslocar bits direita: >> Menor que: < Maior que: > Menor ou igual que: <= Maior ou igual que: >= Igual: == Diferente: != E (And): & Ou exclusivo (Xor): ^ Ou (Or): |

Multiplicativos

Aditivos Deslocamento Relacionais

Igualdade Lgico bit a bit

Lgico booleano

E (And): && Ou (Or): || Condicional ternrio: ? : Por ex. int x = a>b ? 2 : 7; equivalente a: int x; if (a>b) x=2 else x=7;

Atribuio

Atribuir/modificar: = *= /= %= += -= <<= >>= &= ^= |=

Exemplo: Operadores lgicos Opr.cs


/* Operadores lgicos */ using System; class Opr { public static void Main(string[] args){ bool t = true; bool f = false; Console.WriteLine( "t||f : {0} t&&f : {1} !t: {2} !f: {3}", t||f,t&&f,!t,!f ); } }

O exemplo acima aplica os operadores lgicos booleanos ou (||) e and (&&) e o operador de negao lgica no (!) a valores do tipo booleano e imprime os resultados. Exemplo: Operadores relacionais Opr2.cs
/* Operadores relacionais */ using System; class Opr2 { public static void Main(string[] args){ bool gt,lt,eq; int a = 100; int b = 333; gt = a > b; lt = a < b; eq = a == b; Console.WriteLine("a>b:{0}, a<b:{1}, a==b:{2}", gt,lt,eq ); } }

O objetivo desse exemplo mostrar a utilizao dos operadores relacionais (de igualdade e desigualdade). Note que, o resultado das expresses de comparao atribudo a variveis do tipo booleano, o tipo de retorno dos operadores relacionais, e seu valor utilizado posteriormente no momento da impresso dos resultados avaliados. Exemplo: Operadores aritmticos Opr3.cs
/* Operadores aritmticos */ using System; class Opr3 { public static void Main(string[] args){ int a = 127, b = 16, c = 4; int d = a/b/c; /* (a/b)/c */ int m = a+b*c; /* a+(b*c) */

Console.WriteLine( "a/b/c:{0}, a+b*c:{1}", d,m ); } }

Esse exemplo acima, verifica a precedncia dos operadores aritmticos, testando a ordem de precedncia e a associatividade. O valor que deveria ser avaliado pelo compilador est entre parnteses. interessante executar esse cdigo e verificar que o valor calculado exatamente o esperado. Alm disso, em caso de dvida sobre a precedncia de um operador, sempre uma boa prtica utilizar parnteses para agrupar termos. Operadores combinados Uma operao comum adicionar um valor a uma varivel, subtrair um valor de uma varivel, ou, de maneira geral, mudar um valor matemtico e atribu-lo novamente varivel. Uma maneira simples de obter esse efeito utilizando um operador de atribuio combinado. O operador de atribuio pode ser combinado com outros operadores aritmticos, criando outros operadores de atribuio. Seja op um operador aritmtico, ento a expresso que utiliza operadores combinados, a op= exp; um equivalente a a = a op (exp);. Por exemplo:
a a a a += -= *= %= b; 2; 1+1; b*c+d; /* /* /* /* equivalente equivalente equivalente equivalente a a a a */ */ */ */ a a a a = = = = a a a a + * % b; 2; (1+1); (b*c+d);

Auto-incremento e auto-decremento Muitas vezes queremos incrementar ou decrementar o valor da varivel de apenas uma unidade. Para esses casos, existem os operadores de auto-incremento ++ e auto-decremento --. Ambos podem ser utilizados em sua forma pr-fixa ou ps-fixa, isto , antes ou depois da varivel. Em ambos os casos, a funo do operador ++ incrementar uma unidade na varivel e -- de decrementar uma unidade, a diferena entre as formas pr ou ps-fixa est no valor de retorno da expresso. Se utilizado na forma pr-fixa, o valor retornado ser o valor da varivel aps o incremento ou decremento. J se utilizado na forma ps-fixa, o valor retornado ser o valor da varivel anterior ao incremento ou decremento. Muitas vezes, o valor de retorno do incremento ou decremento no importante e descartado, nesse caso, tanto a forma pr-fixa como a ps-fixa tm o mesmo efeito, entretanto importante notar que a forma pr-fixa, isto , ++var mais eficiente que a forma ps-fixa var++, pois a forma ps-fixa precisa fazer uma cpia do objeto antes de retorn-lo. Para tipos simples a economia de tempo pode ser negligvel, entretanto para objetos complexos no primitivos a economia de tempo pode ser considervel.
a = a/i++; /* equivalente a */ a = a/i; i = i+1;

b = --k*2; /* equivalente a */ k=k-1; b = k*2;

Você também pode gostar