¿Cuál es la diferencia entre "long", "long long", "long int" y "long long int" en C ++?

210

Estoy haciendo la transición de Java a C ++ y tengo algunas preguntas sobre el longtipo de datos. En Java, para mantener un número entero mayor que 2 32 , simplemente escribiría long x;. Sin embargo, en C ++, parece que longes tanto un tipo de datos como un modificador.

Parece que hay varias formas de usar long:

long x;
long long x;
long int x;
long long int x;

Además, parece que hay cosas como:

long double x;

y así.

¿Cuál es la diferencia entre todos estos diversos tipos de datos, y todos tienen el mismo propósito?

1110101001
fuente
2
@ user2612743 - para estar seguro, piense cuáles son sus requisitos y use el tipo apropiado. long longpodría ser más lento que long, lo que podría ser más lento que int.
Pete Becker
1
No, "estar seguro, usar mucho tiempo" es lo mismo que decir "estar seguro, solo dale a todos un SIDA de la tierra, para que no tengamos que preocuparnos por el sexo seguro, ¡de todos modos ya lo tenemos!" Tonto, no? Piense en los datos y los posibles valores que puede tener, y use el tipo que mejor se ajuste. Esto también ayuda al compilador a realizar optimizaciones adicionales sin romper la intención del código original, como si tuviera que cargar bibliotecas adicionales para manejar números más grandes que el ancho de bits natural de la plataforma de destino.
CM
Usar mucho tiempo con cuadros de lista win32 y similares no suele causar estragos en su memoria y otras variables, incluso si no se violan los límites. Incluso con las advertencias de aspecto inocuo C4244 no es fácil de detectar.
Laurie Stearn

Respuestas:

182

longy long intson idénticos Así son long longy long long int. En ambos casos, el intes opcional.

En cuanto a la diferencia entre los dos conjuntos, el estándar C ++ exige rangos mínimos para cada uno, y eso long longes al menos tan amplio como long.

Las partes de control del estándar (C ++ 11, pero esto ha existido durante mucho tiempo) son, por ejemplo 3.9.1 Fundamental types, la sección 2 (una sección posterior proporciona reglas similares para los tipos integrales sin signo):

Hay cinco tipos de enteros con signo estándar: char firmado, short int, int, long int y long long int. En esta lista, cada tipo proporciona al menos tanto almacenamiento como los que le preceden en la lista.

También hay una tabla 9 7.1.6.2 Simple type specifiers, que muestra las "asignaciones" de los especificadores a los tipos reales (mostrando que intes opcional), una sección de la cual se muestra a continuación:

Specifier(s)         Type
-------------    -------------
long long int    long long int
long long        long long int
long int         long int
long             long int

Tenga en cuenta la distinción entre el especificador y el tipo. El especificador es cómo le dice al compilador cuál es el tipo, pero puede usar diferentes especificadores para terminar en el mismo tipo.

Por lo tanto, longpor sí solo no es un tipo ni un modificador como plantea su pregunta, es simplemente un especificador para el long inttipo. Lo mismo para long longser un especificador para el long long inttipo.

Aunque el estándar C ++ en sí mismo no especifica los rangos mínimos de los tipos integrales, sí cita C99, en 1.2 Normative references, como aplicable. Por lo tanto, C99 5.2.4.2.1 Sizes of integer types <limits.h>se aplican los rangos mínimos establecidos en .


En términos de long double, eso es en realidad un valor de coma flotante en lugar de un número entero. De manera similar a los tipos integrales, se requiere tener al menos tanta precisión como doubleay proporcionar un superconjunto de valores sobre ese tipo (es decir, al menos esos valores, no necesariamente más valores).

paxdiablo
fuente
44
lo mismo con unsignedyunsigned int
Kal
2
Estoy bastante seguro de que longtiene al menos 32 bits (2 ^ 31-1 en cualquier lado de cero) y long longes de al menos 64 (2 ^ 63-1 en cualquier lado).
Chris
2
Y long doublese garantiza que tiene al menos el rango de double, pero puede ser el mismo. Depende de la computadora. Algunas FPU tienen precisión extendida; los chips x87 tenían precisión simple de 32 bits, precisión doble de 64 bits y precisión extendida de 80 bits.
Eric Jablow
En cuanto a los requisitos de rango, el estándar C ++ 11 hace referencia al estándar C11, que tiene rangos reales.
Chris
La parte "int" simplemente diferencia entre un tipo entero y punto flotante, carácter u otro tipo no entero. En muchos casos, el compilador puede inferir esto, por lo que puede descartarse. Por eso, "unsigned" es lo mismo que "unsigned int", por ejemplo. La parte "int" simplemente se supone a menos que el programador especifique algo más, como "char" o "double". En cuanto a los tamaños reales utilizados ... según el estándar que lea, cada tamaño puede tener un número mínimo de bits, pero todos están definidos de manera que cada uno sea al menos tan grande como el tipo anterior.
CM
64

Long y long int son de al menos 32 bits.

long long y long long int son al menos 64 bits. Debe estar utilizando un compilador c99 o mejor.

los dobles largos son un poco extraños. Búscalos en Wikipedia para más detalles.

Eric Lippert
fuente
17

longes equivalente a long int, tal como shortes equivalente a short int. A long intes un tipo integral con signo que tiene al menos 32 bits, mientras que a long longo long long intes un tipo integral con signo tiene al menos 64 bits.

Esto no significa necesariamente que a long longsea ​​más ancho que a long. Muchas plataformas / ABI usan el LP64modelo, donde long(y punteros) tienen 64 bits de ancho. Win64 usa LLP64, donde longtodavía tiene 32 bits, y long long(y los punteros) tienen 64 bits de ancho.

Hay un resumen bien de los modelos de datos de 64 bits aquí .

long doubleno garantiza mucho más que será al menos tan ancho como a double.

Brett Hale
fuente
7

Esto parece confuso porque está tomando longcomo un tipo de datos en sí mismo.

longno es más que la abreviatura para long intcuando lo está usando solo.

longes un modificador, puedes usarlo doubletambién como long double.

long== long int.

Ambos toman 4 bytes.

Siraj Alam
fuente
La toma larga de 4 bytes solo es válida en Win64, depende de la plataforma
Prodigle
1
Sí, obviamente ... no solo largo ... int toma 4 bytes y 2 bytes dependen de la plataforma, sin duda.
Siraj Alam
3

Históricamente, en los primeros tiempos de C, cuando los procesadores tenían una longitud de palabra de 8 o 16 bits, intera idéntico al de hoy short(16 bits). En cierto sentido, int es un tipo de datos más abstracto que char, short, longo long long, como no se puede estar seguro sobre el ancho de bits.

Al definir int n;, podría traducir esto con "dame el mejor compromiso de ancho de bit y velocidad en esta máquina para n". Quizás en el futuro espere que los compiladores traduzcan inta 64 bits. Entonces, cuando desee que su variable tenga 32 bits y no más, mejor use un explícito longcomo tipo de datos.

[Editar: #include <stdint.h>parece ser la forma correcta de garantizar los anchos de bits utilizando los tipos int ## _ t, aunque todavía no es parte del estándar.]

Thomiel
fuente
2
La última parte, usar un "largo" para obtener 32 bits cuando int es de 64 bits, es incorrecta. Si int es de 64 bits, entonces long será de al menos 64 bits también. Long garantiza que sea al menos tan grande como int, aunque puede ser más grande, pero nunca más pequeño. La mayoría de los compiladores tienen varios métodos que permiten que el programador sea más específico, como un tipo __int32 (no portátil) que es exactamente de 32 bits, y así sucesivamente.
CM
1
Como se define en el estándar C, longse garantiza que al menos 32 bits. (Los estándares pueden cambiar mucho.) El borrador actual de C ++ 14 solo dice: @CM "Las entradas simples tienen el tamaño natural sugerido por la arquitectura del entorno de ejecución. Los otros tipos de enteros firmados se proporcionan para satisfacer necesidades especiales" (sección 3.9.1 ) No encontré ninguna palabra sobre las relaciones de longitud de varias entradas en él. __int32 no es realmente parte del estándar, pero desde C ++ 11 hay typedefs disponibles como int_fast32_t o int_least32_t disponibles para obtener exactamente lo que desea.
thomiel
Yo diría que en las implementaciones del siglo XX para microcomputadoras reprogramables de propósito general, charera casi unánimemente de 8 bits, shorttenía 16 y long32; intpodría ser 16 o 32. Nota para algunas plataformas (especialmente el 68000), tanto de 16 bits como de 32 bits interan bastante comunes, y de hecho algunos compiladores tenían opciones de soporte. Por lo tanto, se esperaba que el código que debía ser portátil se usara shorto longpreferiría int.
supercat
0

Mientras que en Java a longsiempre tiene 64 bits, en C ++ esto depende de la arquitectura de la computadora y del sistema operativo . Por ejemplo, a longes de 64 bits en Linux y 32 bits en Windows (esto se hizo para mantener la compatibilidad con versiones anteriores, permitiendo que los programas de 32 bits se compilen en Windows de 64 bits sin ningún cambio).

Se considera un buen estilo de C ++ para evitar short int long ... y en su lugar usar:

std::int8_t   # exactly  8 bits
std::int16_t  # exactly 16 bits
std::int32_t  # exactly 32 bits
std::int64_t  # exactly 64 bits

std::size_t   # can hold all possible object sizes, used for indexing

Estos ( int*_t) se pueden usar después de incluir el <cstdint>encabezado. size_testá en <stdlib.h>.

xjcl
fuente