Conversão de tipo

Na ciência da computação , conversão de tipo , [1] [2] conversão de tipo , [1] [3] coerção de tipo , [3] e malabarismo de tipo [4] [5] são maneiras diferentes de alterar uma expressão de um tipo de dados para outro . Um exemplo seria a conversão de um valor inteiro em um valor de ponto flutuante ou sua representação textual como uma string , e vice-versa. As conversões de tipo podem aproveitar certos recursos de hierarquias de tipo ou representações de dados . Dois aspectos importantes de uma conversão de tipo são se ela acontece implicitamente (automaticamente) ou explicitamente , [1] [6] e se a representação de dados subjacente é convertida de uma representação em outra, ou se uma determinada representação é meramente reinterpretada como a representação de outra tipo de dados. [6] [7] Em geral, tipos de dados primitivos e compostos podem ser convertidos.

Cada linguagem de programação tem suas próprias regras sobre como os tipos podem ser convertidos. Linguagens com tipagem forte normalmente fazem pouca conversão implícita e desencorajam a reinterpretação de representações, enquanto linguagens com tipagem fraca realizam muitas conversões implícitas entre tipos de dados. Linguagem de digitação fraca geralmente permite forçar o compilador a interpretar arbitrariamente um item de dados como tendo representações diferentes – isso pode ser um erro de programação não óbvio ou um método técnico para lidar diretamente com o hardware subjacente.

Na maioria das linguagens, a palavra coerção é usada para denotar uma conversão implícita , seja durante a compilação ou durante o tempo de execução . Por exemplo, em uma expressão que mistura números inteiros e de ponto flutuante (como 5 + 0,1), o compilador converterá automaticamente a representação inteira em representação de ponto flutuante para que as frações não sejam perdidas. As conversões de tipo explícitas são indicadas escrevendo código adicional (por exemplo, adicionando identificadores de tipo ou chamando rotinas integradas ) ou codificando rotinas de conversão para o compilador usar quando, de outra forma, pararia devido a uma incompatibilidade de tipo.

Na maioria das linguagens do tipo ALGOL , como Pascal , Modula-2 , Ada e Delphi , conversão e conversão são conceitos distintamente diferentes. Nessas linguagens, conversão refere-se à alteração implícita ou explícita de um valor de um formato de armazenamento de tipo de dados para outro, por exemplo, um número inteiro de 16 bits para um número inteiro de 32 bits. As necessidades de armazenamento podem mudar como resultado da conversão, incluindo uma possível perda de precisão ou truncamento. A palavra cast , por outro lado, refere-se à alteração explícita da interpretação do padrão de bits que representa um valor de um tipo para outro. Por exemplo, 32 bits contíguos podem ser tratados como uma matriz de 32 booleanos, uma string de 4 bytes, um número inteiro não assinado de 32 bits ou um valor de ponto flutuante de precisão única IEEE. Como os bits armazenados nunca são alterados, o programador deve conhecer detalhes de baixo nível, como formato de representação, ordem de bytes e necessidades de alinhamento, para fazer uma conversão significativa.

Na família de linguagens C e no ALGOL 68 , a palavra cast normalmente se refere a uma conversão de tipo explícita (em oposição a uma conversão implícita), causando alguma ambigüidade sobre se esta é uma reinterpretação de um padrão de bits ou uma representação de dados real. conversão. Mais importante é a multiplicidade de maneiras e regras que se aplicam a qual tipo de dados (ou classe) é localizado por um ponteiro e como um ponteiro pode ser ajustado pelo compilador em casos como herança de objeto (classe).

Casting explícito em vários idiomas

Ada

Ada fornece uma função de biblioteca genérica Unchecked_Conversion. [8]

Linguagens semelhantes a C

Conversão de tipo implícita

A conversão implícita de tipos, também conhecida como coerção ou malabarismo de tipos , é uma conversão automática de tipos feita pelo compilador . Algumas linguagens de programação permitem que os compiladores forneçam coerção; outros exigem isso.

Em uma expressão de tipo misto, os dados de um ou mais subtipos podem ser convertidos em um supertipo conforme necessário em tempo de execução para que o programa seja executado corretamente. Por exemplo, o seguinte é o código legal da linguagem C :

duplo d ; longo eu ; int eu ;  
    
     

se ( d > i ) d = i ; se ( i > l ) l = i ; se ( d == l ) d *= 2 ;        
        
       

Embora d , l e i pertençam a tipos de dados diferentes, eles serão automaticamente convertidos em tipos de dados iguais sempre que uma comparação ou atribuição for executada. Este comportamento deve ser usado com cautela, pois podem surgir consequências indesejadas . Os dados podem ser perdidos ao converter representações de ponto flutuante para número inteiro, pois os componentes fracionários dos valores de ponto flutuante serão truncados (arredondados para zero). Por outro lado, a precisão pode ser perdida ao converter representações de inteiro para ponto flutuante, uma vez que um tipo de ponto flutuante pode não ser capaz de representar exatamente todos os valores possíveis de algum tipo inteiro. Por exemplo, pode ser um tipo de precisão única IEEE 754 , que não pode representar exatamente o número inteiro 16777217, enquanto um tipo inteiro de 32 bits pode. Isso pode levar a um comportamento não intuitivo, conforme demonstrado pelo código a seguir: float

#include <stdio.h> 

int main ( void ) { int i_value = 16777217 ; float f_value = 16777216,0 ; printf ( "O número inteiro é: %d \n " , i_value ); printf ( "O float é: %f \n " , f_value ); printf ( "Sua igualdade: %d \n " , i_value == f_value ); } 

         
       
     
     
       

Em compiladores que implementam floats como precisão única IEEE e ints como pelo menos 32 bits, este código fornecerá esta impressão peculiar:

O número inteiro é: 16777217
O flutuador é: 16777216.000000
Sua igualdade: 1

Observe que 1 representa igualdade na última linha acima. Esse comportamento estranho é causado por uma conversão implícita de i_valuefloat quando comparado com f_value. A conversão causa perda de precisão, o que torna os valores iguais antes da comparação.

Conclusões importantes:

  1. floatcausar truncamentoint , ou seja , remoção da parte fracionária.
  2. doublepara floatcausar arredondamento do dígito.
  3. longcausa inta queda de bits de ordem superior em excesso.
Digite promoção

Um caso especial de conversão implícita de tipo é a promoção de tipo, onde um objeto é automaticamente convertido em outro tipo de dados representando um superconjunto do tipo original. As promoções são comumente utilizadas com tipos menores que o tipo nativo da unidade lógica aritmética (ALU) da plataforma alvo , antes das operações aritméticas e lógicas, para tornar tais operações possíveis, ou mais eficientes se a ALU puder trabalhar com mais de um tipo. C e C++ realizam essa promoção para objetos dos tipos booleano, caractere, caractere largo, enumeração e número inteiro curto que são promovidos para int, e para objetos do tipo float, que são promovidos para double. Ao contrário de alguns outros tipos de conversões, as promoções nunca perdem a precisão ou modificam o valor armazenado no objeto.

Em Java :

int x = 3 ; duplo y = 3,5 ; Sistema . fora . imprimirln ( x + y ); // A saída será 6,5   
   
   

Conversão de tipo explícito

A conversão explícita de tipo, também chamada de conversão de tipo, é uma conversão de tipo que é definida explicitamente em um programa (em vez de ser feita automaticamente de acordo com as regras da linguagem para conversão implícita de tipo). É solicitado pelo usuário no programa.

duplo da = 3,3 ; duplo db = 3,3 ; pb duplo = 3,4 ; int resultado = ( int ) da + ( int ) db + ( int ) dc ; // resultado == 9 // se a conversão implícita fosse usada (como em "resultado = da + db + dc"), o resultado seria igual a 10   
   
   
        

Existem vários tipos de conversão explícita.

verificado
Antes de a conversão ser executada, é feita uma verificação em tempo de execução para ver se o tipo de destino pode conter o valor de origem. Caso contrário, uma condição de erro será levantada.
desmarcado
Nenhuma verificação é realizada. Se o tipo de destino não puder conter o valor de origem, o resultado será indefinido.
Padrão de bits
A representação de bits brutos da origem é copiada literalmente e reinterpretada de acordo com o tipo de destino. Isto também pode ser conseguido através de alias .

Nas linguagens de programação orientadas a objetos , os objetos também podem ser downcast  : uma referência de uma classe base é convertida em uma de suas classes derivadas.

C# e C++

Em C# , a conversão de tipo pode ser feita de maneira segura ou insegura (ou seja, semelhante a C), a primeira chamada de check type cast . [9]

Animal animal = novo Gato ();    

Bulldog b = animal ( Bulldog ) ; // se (animal é Bulldog), stat.type(animal) é Bulldog, caso contrário uma exceção b = animal as Bulldog ; // if (animal é Bulldog), b = (Bulldog) animal, else b = null      
             

animal = nulo ; b = animal como Bulldog ; // b == nulo  
             

Em C++, um efeito semelhante pode ser alcançado usando a sintaxe de conversão no estilo C++ .

Animal * animal = novo Gato ;    

Bulldog * b = static_cast < Bulldog *> ( animal ); // compila apenas se Animal ou Bulldog for derivado do outro (ou mesmo) b = dynamic_cast < Bulldog *> ( animal ); // if (animal é Bulldog), b = (Bulldog*) animal, else b = nullptr    
           

Bulldog & br = static_cast < Bulldog &> ( * animal ); // igual ao acima, mas uma exceção será lançada se um nullptr for retornado // isso não é visto no código onde o tratamento de exceções é evitado    
                                              

excluir animal ; // sempre libera recursos animal = nullptr ; b = dynamic_cast < Bulldog *> ( animal ); //b == nullptr  
  
           

Eiffel

Em Eiffel, a noção de conversão de tipos é integrada às regras do sistema de tipos. A Regra de Atribuição diz que uma atribuição, como:

x := y  

é válido se e somente se o tipo de sua expressão de origem, yneste caso, for compatível com o tipo de sua entidade de destino, xneste caso. Nesta regra, compatível com significa que o tipo da expressão de origem está em conformidade ou é convertido no tipo de expressão de destino. A conformidade de tipos é definida pelas regras familiares para polimorfismo em programação orientada a objetos . Por exemplo, na atribuição acima, o tipo está yem conformidade com o tipo de xse a classe na qual yse baseia é descendente daquela em que xse baseia.

Definição de conversão de tipo em Eiffel

As ações de conversão de tipo em Eiffel, especificamente conversões para e conversões de são definidas como:

Um tipo baseado em uma classe CU é convertido em um tipo T baseado em uma classe CT (e T é convertido de U) se

CT tem um procedimento de conversão usando U como tipo de conversão, ou
CU tem uma consulta de conversão listando T como tipo de conversão

Exemplo

Eiffel é uma linguagem totalmente compatível com o Microsoft .NET Framework . Antes do desenvolvimento do .NET, Eiffel já possuía extensas bibliotecas de classes. O uso de bibliotecas de tipos .NET, especialmente com tipos comumente usados, como strings, representa um problema de conversão. O software Eiffel existente usa classes de string (como STRING_8) das bibliotecas Eiffel, mas o software Eiffel escrito para .NET deve usar a classe de string .NET ( System.String) em muitos casos, por exemplo, ao chamar métodos .NET que esperam itens do .NET tipo a ser passado como argumentos. Portanto, a conversão desses tipos precisa ser o mais simples possível.

    my_string : STRING_8 -- String nativa do Eiffel my_system_string : SYSTEM_STRING -- String nativa do .NET                  
          

        ...

            minha_string := minha_string_sistema  

No código acima, duas strings são declaradas, uma de cada tipo diferente ( SYSTEM_STRINGé o alias compatível com Eiffel para System.String). Como System.Stringnão está em conformidade com STRING_8, a atribuição acima será válida somente se System.Stringfor convertida em STRING_8.

A classe Eiffel STRING_8possui um procedimento de conversão make_from_cilpara objetos do tipo System.String. Os procedimentos de conversão também são sempre designados como procedimentos de criação (semelhantes aos construtores). A seguir está um trecho da STRING_8aula:

    classe STRING_8 ... criar make_from_cil ... converter make_from_cil ({ SYSTEM_STRING }) ... 
        
    
        
        
    
         
        

A presença do procedimento de conversão torna a atribuição:

            minha_string := minha_string_sistema  

semanticamente equivalente a:

            crie minha_string . make_from_cil ( meu_sistema_string )  

no qual my_stringé construído como um novo objeto do tipo STRING_8com conteúdo equivalente ao de my_system_string.

Para lidar com uma atribuição com origem e destino originais invertidos:

            minha_string_sistema := minha_string  

a classe STRING_8também contém uma consulta de conversão to_cilque produzirá System.Stringuma instância de STRING_8.

    classe STRING_8 ... criar make_from_cil ... converter make_from_cil ({ SYSTEM_STRING }) para_cil : { SYSTEM_STRING } ... 
        
    
        
        
    
         
         
        

A atribuição:

            minha_string_sistema := minha_string  

então, torna-se equivalente a:

            minha_string_sistema := minha_string . to_cil  

No Eiffel, a configuração para conversão de tipo é incluída no código da classe, mas parece acontecer tão automaticamente quanto a conversão explícita de tipo no código do cliente. Inclui não apenas atribuições, mas também outros tipos de anexos, como substituição de argumentos (parâmetros).

Ferrugem

Rust não fornece conversão implícita de tipo (coerção) entre tipos primitivos. Porém, a conversão explícita de tipo (casting) pode ser realizada usando a aspalavra-chave. [10]

seja x = 1000 ; imprimir! ( "1000 como u16 é: {}" , x como u16 );   
   

Casting implícito usando uniões não marcadas

Muitas linguagens de programação suportam tipos de união que podem conter valores de vários tipos. Uniões não marcadas são fornecidas em alguns idiomas com verificação de tipo flexível, como C e PL/I , mas também no Pascal original . Eles podem ser usados ​​para interpretar o padrão de bits de um tipo como um valor de outro tipo.

Problemas de segurança

No hacking , typecasting é o uso indevido da conversão de tipo para alterar temporariamente o tipo de dados de uma variável de como ela foi originalmente definida. [11] Isso oferece oportunidades para hackers, pois na conversão de tipo após uma variável ser "typecast" para se tornar um tipo de dados diferente, o compilador tratará essa variável hackeada como o novo tipo de dados para aquela operação específica. [12]

Veja também

Referências

  1. ^ abc Mehrotra, Dheeraj (2008). Ciência da Computação de S. Chand . S. Chand. pp. 81–83. ISBN 978-8121929844.
  2. ^ Linguagens de programação - Design e construções . Publicações Laxmi. 2013. pág. 35.ISBN _ 978-9381159415.
  3. ^ ab Reilly, Edwin (2004). Enciclopédia Concisa de Ciência da Computação. John Wiley e Filhos. páginas 82, 110. ISBN 0470090952.
  4. ^ Fenton, Steve (2017). Pro TypeScript: desenvolvimento de JavaScript em escala de aplicativo . Aperte. págs. ISBN 978-1484232491.
  5. ^ "PHP: Malabarismo de tipos - Manual" . php.net . Recuperado em 27 de janeiro de 2019 .
  6. ^ ab Olsson, Mikael (2013). Referência rápida de sintaxe C++ . Aperte. pp. 87–89. ISBN 978-1430262770.
  7. ^ Kruse, Rodolfo; Borgelt, cristão; Braune, cristão; Mostaghim, Sanaz; Steinbrecher, Matthias (16 de setembro de 2016). Inteligência Computacional: Uma Introdução Metodológica . Springer. pág. 269. ISBN 978-1447172963.
  8. ^ "Conversões de tipo não verificadas" . Câmara de informações de Ada . Recuperado em 11 de março de 2023 .
  9. ^ Mössenböck, Hanspeter (25 de março de 2002). "C # avançado: conversões de tipo verificadas" (PDF) . Instituto de Software de Sistemas, Johannes Kepler Universität Linz, Fachbereich Informatik. pág. 5 . Recuperado em 4 de agosto de 2011 . no Tutorial C#
  10. ^ "Fundição - Ferrugem por exemplo" . doc.rust-lang.org .
  11. ^ Jon Erickson Hacking, 2ª Edição: The Art of Exploitation 2008 1593271441 p51 "Typecasting é simplesmente uma maneira de alterar temporariamente o tipo de dados de uma variável, apesar de como ela foi originalmente definida. Quando uma variável é convertida em um tipo diferente, o compilador é basicamente instruído a tratar essa variável como se fosse o novo tipo de dados, mas apenas para aquela operação. A sintaxe para conversão de tipo é a seguinte: (typecast_data_type) variável ..."
  12. ^ Arpita Gopal Ampliação C 2009 8120338618 p. 59 "Do exposto acima, fica claro que o uso da conversão de tipos é fazer com que uma variável de um tipo atue como outro tipo para uma única operação. Portanto, usando essa capacidade de conversão de tipos, é possível criar caracteres ASCII convertendo números inteiros para isso é ..."

links externos

  • Elenco em Ada
  • Transmissão em C++
  • Guia de referência de C++ Por que eu odeio operadores de elenco C++, por Danny Kalev
  • Transmissão em Java
  • Conversões implícitas em C#
  • Casting de tipo implícito em Cppreference.com
  • Fundições estáticas e de reinterpretação em C++
  • Upcasting e Downcasting em F#
Obtido em "https://en.wikipedia.org/w/index.php?title=Type_conversion&oldid=1180303797#Implicit_type_conversion"