Literal inteiro - Integer literal

Na ciência da computação , um literal inteiro é uma espécie de literal para um inteiro cujo valor é diretamente representado no código-fonte . Por exemplo, na instrução de atribuição x = 1 , a string 1 é um literal inteiro indicando o valor 1, enquanto na instrução x = 0x10 a string 0x10 é um literal inteiro indicando o valor 16, que é representado por 10 em hexadecimal (indicado pelo 0x prefixo).

Em contraste, em x = cos(0) , a expressão é cos(0) avaliada como 1 (como o cosseno de 0), mas o valor 1 não está literalmente incluído no código-fonte. Mais simplesmente, na x = 2 + 2, expressão 2 + 2 avalia para 4, mas o valor 4 não é incluído literalmente. Além disso, em x = "1" a "1" é um literal de cadeia , não um literal inteiro, porque é entre aspas. O valor da string é 1 , que por acaso é uma string inteira, mas esta é uma análise semântica da string literal - no nível sintático "1" é simplesmente uma string, não é diferente de "foo" .

Análise

Reconhecer uma string (sequência de caracteres no código-fonte) como um literal inteiro faz parte da fase de análise lexical (lexing), enquanto avaliar o valor do literal faz parte da fase de análise semântica . Dentro do lexer e da gramática de frase, a classe de token geralmente é denotada integer , com as minúsculas indicando uma classe de token de nível léxico, em oposição à regra de produção de nível de frase (como ListOfIntegers ). Uma vez que uma string foi lexed (tokenizada) como um literal inteiro, seu valor não pode ser determinado sintaticamente (é apenas um inteiro), e a avaliação de seu valor se torna uma questão semântica.

Literais inteiros são geralmente lexed com expressões regulares , como em Python .

Avaliação

Tal como acontece com outros literais, literais inteiros são geralmente avaliados em tempo de compilação, como parte da fase de análise semântica. Em alguns casos, essa análise semântica é feita no lexer, imediatamente no reconhecimento de um literal inteiro, enquanto em outros casos isso é adiado até o estágio de análise, ou até depois que a árvore de análise foi completamente construída. Por exemplo, ao reconhecer a string, 0x10 o lexer poderia avaliar imediatamente este para 16 e armazenar aquele (um token de tipo integer e valor 16) ou adiar a avaliação e, em vez disso, registrar um token de tipo integer e valor 0x10 .

Depois que os literais foram avaliados, uma análise semântica adicional na forma de dobramento constante é possível, o que significa que expressões literais envolvendo valores literais podem ser avaliadas na fase de compilação. Por exemplo, na instrução x = 2 + 2 depois que os literais foram avaliados e a expressão 2 + 2 analisada, ela pode ser avaliada como 4, embora o valor 4 não apareça como um literal.

Afixos

Literais inteiros freqüentemente têm prefixos que indicam a base e menos freqüentemente sufixos que indicam o tipo. Por exemplo, em C ++ 0x10ULL indica o valor 16 (porque hexadecimal) como um inteiro longo longo sem sinal.

Os prefixos comuns incluem:

Os sufixos comuns incluem:

  • l ou L por inteiro longo;
  • ll ou LL por inteiro longo longo;
  • u ou U para inteiro sem sinal.

Esses afixos são um tanto semelhantes aos sigilos , embora sigilos anexem a identificadores (nomes), não literais.

Separadores de dígitos

Em alguns idiomas, literais inteiros podem conter separadores de dígitos para permitir o agrupamento de dígitos em formas mais legíveis. Se estiver disponível, geralmente também pode ser feito para literais de ponto flutuante. Isso é particularmente útil para campos de bits e torna mais fácil ver o tamanho de grandes números (como um milhão) de relance, subitizando em vez de contar dígitos. Também é útil para números que normalmente são agrupados, como número de cartão de crédito ou números de previdência social . Números muito longos podem ser agrupados dobrando os separadores.

Normalmente, os números decimais (base 10) são agrupados em grupos de três dígitos (representando um dos 1000 valores possíveis), números binários (base 2) em grupos de quatro dígitos (um nibble , representando um dos 16 valores possíveis) e números hexadecimais ( base-16) em grupos de dois dígitos (cada dígito é um nibble, então dois dígitos são um byte , representando um dos 256 valores possíveis). Números de outros sistemas (como números de identificação) são agrupados seguindo qualquer convenção em uso.

Exemplos

Em Ada , C # (da versão 7.0), D , Eiffel , Go (da versão 1.13), Haskell (do GHC versão 8.6.1), Java (da versão 7), Julia , Perl , Python (da versão 3.6), Ruby , Rust e Swift , literais inteiros e literais flutuantes podem ser separados por um sublinhado ( _ ). Pode haver algumas restrições ao posicionamento; por exemplo, em Java, eles não podem aparecer no início ou no final do literal, nem ao lado de um ponto decimal. Observe que, embora o ponto final, a vírgula e os espaços (finos) sejam usados ​​na escrita normal para separação de dígitos, eles entram em conflito com o uso existente em linguagens de programação como ponto de raiz , separador de lista (e em C / C ++, o operador de vírgula ) e separador de tokens.

Exemplos incluem:

int oneMillion = 1_000_000;
int creditCardNumber = 1234_5678_9012_3456;
int socialSecurityNumber = 123_45_6789;

Em C ++ 14 (2014), o caractere apóstrofo pode ser usado para separar dígitos arbitrariamente em literais numéricos. O sublinhado foi proposto inicialmente, com uma proposta inicial em 1993, e novamente para C ++ 11 , seguindo outras linguagens. No entanto, isso causou conflito com literais definidos pelo usuário , portanto, o apóstrofo foi proposto em vez disso, como uma " vírgula superior " (que é usada em alguns outros contextos).

auto integer_literal = 1'000'000;
auto binary_literal = 0b0100'1100'0110;
auto very_long_binary_literal =
    0b0000'0001'0010'0011''0100'0101'0110'0111;

Notas

Referências