Literal entero
Permite que valores de tipo entero se usen directamente en expresiones.
Sintaxis
Un literal entero tiene la forma
| literal-decimal sufijo-entero (opcional) | (1) | ||||||||
| literal-octal sufijo-entero (opcional) | (2) | ||||||||
| literal-hex sufijo-entero (opcional) | (3) | ||||||||
| literal-binario (opcional) sufijo-entero | (4) | (desde C++14) | |||||||
donde
- literal-decimal es un dígito decimal distinto de cero (
1,2,3,4,5,6,7,8,9), seguido de cero o más dígitos decimales (0,1,2,3,4,5,6,7,8,9); - literal-octal es el dígito cero (
0) seguido de cero o más dígitos octales: (0,1,2,3,4,5,6,7); - literal-hex es la secuencia de caracteres
0xo la secuencia de caracteres0Xseguida de uno o más dígitos hexadecimales (0,1,2,3,4,5,6,7,8,9,a,A,b,B,c,C,d,D,e,E,f,F); - literal-binario es la secuencia de caracteres
0bo la secuencia de caracteres0Bseguida de uno o más dígitos binarios (0,1); - sufijo-entero, si se proporciona, puede contener uno o ambos de los siguientes (si ambos se proporcionan, pueden aparecer en cualquier orden):
- sufijo-sin-signo (el carácter
uo el carácterU); - uno de
- sufijo-long (el carácter
lo el carácterL);
- sufijo-long (el carácter
- sufijo-sin-signo (el carácter
|
(desde C++11) |
|
(desde C++23) |
|
Pueden insertarse comillas sencillas opcionales ( |
(desde C++14) |
Un literal entero (como cualquier literal) es una expresión primaria.
Explicación
'a' a la 'f' representan los valores (decimales) del 10 al 15);El primer dígito de un literal entero es el más significativo.
Ejemplo. Las siguientes variables se inicializan en el mismo valor:
int d = 42;
int o = 052;
int x = 0x2a;
int X = 0X2A;
int b = 0b101010; // C++14
Ejemplo. Las siguientes variables también se inicializan en el mismo valor:
unsigned long long l1 = 18446744073709550592ull; // C++11
unsigned long long l2 = 18'446'744'073'709'550'592llu; // C++14
unsigned long long l3 = 1844'6744'0737'0955'0592uLL; // C++14
unsigned long long l4 = 184467'440737'0'95505'92LLU; // C++14
El tipo del literal
El tipo del literal entero es el primer tipo en el cual el valor puede encajar, de la lista de tipos, que depende de cuál base numérica y cuál sufijo-entero se usó:
| Sufijo | Bases decimales | Bases binarias, octales o hexadecimales |
|---|---|---|
| (sin sufijo) |
|
|
u o U
|
|
|
l o L
|
|
|
tanto l/Lcomo u/U
|
|
|
ll o LL
|
|
|
tanto ll/LLcomo u/U
|
|
|
z o Z
|
|
|
tanto z/Zcomo u/U
|
|
|
Si el valor del literal entero que no tiene sufijo-de-tamaño (desde C++23) es demasiado grande para encajar en cualquiera de los tipos permitidos por la combinación sufijo/base y el compilador admite un tipo entero extendido (como __int128) que puede representar el valor del literal, se le puede dar al literal ese tipo entero extendido; de lo contrario, el programa estará mal formado.
Notas
Las letras en los literales enteros no son sensibles a las mayúsculas o minúsculas: 0xDeAdBeEfU y 0XdeadBEEFu representan el mismo número (una excepción es el sufijo-long-long, que es ya sea ll o LL, nunca lL o Ll) (desde C++11).
No existen literales enteros negativos. Las expresiones como -1 aplican el operador menos unario al valor representado por el literal, lo que puede implicar conversiones de tipo implícitas.
En C antes de C99 (pero no en C++), los valores decimales sin sufijo que no encajan en long int se les permite que tengan el tipo unsigned long int.
|
Cuando se usan en una expresión controladora de #if o #elif, todas las constantes enteras con signo actúan como si tuvieran el tipo std::intmax_t y todas las constantes enteras sin signo actúan como si tuvieran el tipo std::uintmax_t. |
(desde C++11) |
Debido a la mascada máxima, los literales enteros hexadecimales que terminan en e y E, cuando están seguidos de los operadores + o -, deben estar separados del operador con espacio en blanco o paréntesis en el código fuente:
auto x = 0xE+2.0; // ERROR
auto y = 0xa+2.0; // de acuerdo
auto z = 0xE +2.0; // de acuerdo
auto q = (0xE)+2.0; // de acuerdo
De lo contrario, se forma un solo símbolo numérico de preprocesamiento inválido, que provoca que falle un análisis posterior.
| Macro de prueba de característica | Valor | Estándar | Comentario |
|---|---|---|---|
__cpp_binary_literals |
201304L |
(C++14) | Literales binarios |
__cpp_size_t_suffix |
202011L |
(C++23) | Sufjios de literal para std::size_t y su versión con signo |
Ejemplo
#include <cstddef>
#include <iostream>
#include <type_traits>
int main()
{
std::cout << 123 << '\n'
<< 0123 << '\n'
<< 0x123 << '\n'
<< 0b10 << '\n'
<< 12345678901234567890ull << '\n'
<< 12345678901234567890u << '\n'; // el tipo es unsigned long long
// incluso sin un sufijo long long
// std::cout << -9223372036854775808 << '\n'; // ERROR: el valor
// 9223372036854775808 no puede encajar en long long con signo, que es el
// tipo más grande permitido para un literal decimal entero sin sufijo
std::cout << -9223372036854775808u << '\n'; // el menos unario aplicado al valor
// sin signo lo sustrae de 2^64, esto da 9223372036854775808
std::cout << -9223372036854775807 - 1 << '\n'; // manera correcta para calcular
// el valor -9223372036854775808
#if __cpp_size_t_suffix >= 202011L // C++23
static_assert(std::is_same_v<decltype(0UZ), std::size_t>);
static_assert(std::is_same_v<decltype(0Z), std::make_signed_t<std::size_t>>);
#endif
}
Salida:
123
83
291
2
12345678901234567890
12345678901234567890
9223372036854775808
-9223372036854775808
Informes de defectos
Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.
| ID | Aplicado a | Comportamiento según lo publicado | Comportamiento correcto |
|---|---|---|---|
| CWG 2698 | C++23 | Un literal entero con sufijo-de-tamaño podría tener un tipo entero extendido. | Mal formado si es demasiado grande. |
Referencias
- El estándar C++23 (ISO/IEC 14882:2023):
- 5.13.2 Literales enteros [lex.icon]
- El estándar C++20 (ISO/IEC 14882:2020):
- 5.13.2 Literales enteros [lex.icon]
- El estándar C++17 (ISO/IEC 14882:2017):
- 5.13.2 Literales enteros [lex.icon]
- El estándar C++14 (ISO/IEC 14882:2014):
- 2.14.2 Literales enteros [lex.icon]
- El estándar C++11 (ISO/IEC 14882:2011):
- 2.14.2 Literales enteros [lex.icon]
- El estándar C++98 (ISO/IEC 14882:1998):
- 2.13.1 Literales enteros [lex.icon]
Véase también
| Literales definidos por el usuario(C++11) | Literales con sufijo definidos por el usuario |
Documentación de C para Constante entera
| |