AULA 9 - Introdução à Linguagem C - FIC

De IFSC
Ir para navegação Ir para pesquisar

CONVERSÕES DE TIPOS

Apesar do tipo de cada variável e constante ser definido no início das funções, eventualmente uma variável ou constante precisará ser convertida para outro tipo, no meio do programa.


Uma conversão pode ocorrer porque definimos um operando como sendo de um tipo e depois precisamos compará-lo ou realizar alguma operação aritmética com este e outro operando de outro tipo.

Ou então porque o tipo do operando não foi suficiente para armazená-lo durante todo o correr do programa.

O fato é que conversões de tipos de variáveis e constantes acontecem e podem ser:

  • Conversão Automática - Ocorre quando tipos diferentes aparecem numa mesma expressão. A

regra geral é converter o tipo "menor" para o tipo "maior". Ex:

  int x=5;
  float y = 2.4;
  ... soma = x + y; /* Nesta linha o inteiro x é convertido para o valor real 5.0 */
  • Conversão Forçada - Também conhecida como conversão "cast". Ocorre quando um tipo

específico for necessário e o operando não foi definido como tal. A sintaxe é:

(tipo) expressão

onde tipo é o tipo para o qual será convertido o operando e expressão é uma expressão que contém a variável ou constante a ser convertida. Ex:

float r = 3.5;
int i;
.... i = (int) r; /* Nesta linha o valor 3 (truncamento do real r) foi atribuído a i */

Conversões de tipos são perigosas, pois além de poderem gerar um código não-portátil (pois o tamanho dos tipos varia de máquina para máquina), podem criar problemas de armazenamento dos operandos.

Por exemplo, quando um número real muito grande, cuja representação da parte inteira exceda 16 bits (por exemplo 3.24e14), for convertido para inteiro, o resultado será imprevisível, pois não se pode determinar o que será feito com a parte inteira que não couber nos 16 bits de um int.

As regras para conversões automáticas são:

  • Tipo Char e Short - São convertidos automaticamente para Int. Utiliza-se o código ASCII do

caractere. Se o caractere contém o bit MSB em 1, o inteiro resultante poderá ser negativo, ou não, dependendo da máquina. Se o caractere for unsigned, o inteiro será positivo e os bits de maior ordem serão preenchidos com zeros.

  • Tipo Float - É convertido para Double.


Conversão de Operandos Aritméticos

o tipo "maior", dentre os tipos da expressão será o do resultado. A regra é: double > long > unsigned > int.


Conversão de Operandos de Atribuição

o lado direito será convertido para o tipo do lado esquerdo.

A regra é:

Operando à direita Operando à esquerda Conversão
Double Float com arredondamento
Float Int trunca parte frac., se o número não couber em int: resultado indeterm.
Long Int elimina os bits MSB
Int Char elimina os bits MSB


Exemplo 1 – diferentes tipos numa mesma expressão:

Tiposmesmaexpr.png


Exemplo 2:

Conversao2.png


Exemplo 3:

A expressão:

   (float) x/2 ⇒ converte x e, por consequência, o 2 para float

Já a expressão:

   (float) (x/2) ⇒ converte o resultado inteiro de x/2 para float


PRECEDÊNCIA

Os operadores obedecem uma certa ordem de precedência. Isto é: operações de maior precedência são realizadas antes das de menor precedência. O operador de mais alta precedência é o abre e fecha-parênteses ("()"), portanto, tudo que estiver entre eles será realizado primeiro. Por exemplo: primeiro *= segundo <= terceiro Primeiramente o segundo operando é comparado ao terceiro e depois a atribuição ao primeiro é feita, porque o operador "<=" tem uma precedência maior que o "*=". Esta expressão é equivalente a: primeiro *= (segundo <= terceiro ) Observe que a expressão (segundo <= terceiro) tem valor zero ou um. No caso da expressão: primeiro = segundo -= terceiro os operadores "=" e "-=" têm igual precedência, mas o segundo operando é avaliado antes do primeiro porque os compiladores C costumam avaliar expressões condicionais e de atribuição da direita para a esquerda. Existem 15 classes de precedência, ou seja, todos os operadores pertencentes à mesma classe têm igual precedência. Neste caso, valem as regras de associatividade, para determinar-se quais operações serão realizadas primeiro. A tabela abaixo mostra as classes de precedência dos operadores, em ordem decrescente:


Operador Nome do Operador Precedência Associatividade
( ) Chamada de função 1 esq. p/ dir.
[ ] Elemento Matriz 1 esq. p/ dir.
Ponteiro para Membro Estrutura 1 esq. p/ dir.
. Membro de Estrutura 1 esq. p/ dir.
Negação Lógica

2 dir. p/ esq. ~ Complemento de um ++ Incremento -- Decremento - Menos unário (tipo) Cast

  • Ponteiro

& Endereço sizeof Tamanho do Objeto

  • Multiplicação

/ Divisão 3 esq. p/ dir. % Resto da Divisão + Adição 4 esq. p/ dir. - Subtração << Deslocamento à Esquerda 5 esq. p/ dir. >> Deslocamento à Direita < Menor Que 6 esq. p/ dir. <= Menor ou Igual a > Maior Que >= Maior ou Igual a == Igualdade 7 esq. p/ dir. != Desigualdade & AND, Bit a Bit 8 esq. p/ dir. ^ XOR, Bit a Bit 9 esq. p/ dir.

OR, Bit a Bit 10 esq. p/ dir.

&& AND Lógico 11 esq. p/ dir.

OR Lógico 12 esq. p/ dir.

?: Condicional 13 dir. p/ esq. = Atribuição 14 dir. p/ esq. op= Atribuição Reduzida , Vírgula 15 esq. p/ dir.

ORDEM DE AVALIAÇÃO

A ordem de avaliação de uma expressão indica se a operação será avaliada da direita pra esquerda ou o contrário. Os operadores "&&", "||", e "," sempre são avaliados da esquerda para a direita. Fora este caso, a ordem de avaliação dependerá do compilador. Ex:

int i=5;

... y = (++i) + (--i); ... Neste caso, y poderá receber o valor 5+4= 9, 6+5 = 11 ou até 10(???)!!! Dependerá do compilador.