Qual é a diferença entre "long", "long long", "long int" e "long long int" em C ++?

210

Estou fazendo a transição do Java para o C ++ e tenho algumas perguntas sobre o longtipo de dados. Em Java, para armazenar um número inteiro maior que 2 32 , você simplesmente escreverialong x; . No entanto, em C ++, parece que longé um tipo de dados e um modificador.

Parece haver várias maneiras de usar long:

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

Além disso, parece que existem coisas como:

long double x;

e assim por diante.

Qual é a diferença entre todos esses tipos de dados e todos eles têm o mesmo objetivo?

1110101001
fonte
2
@ user2612743 - para garantir a segurança, pense em quais são seus requisitos e use o tipo apropriado. long longpode ser mais lento que long, o que pode ser mais lento que int.
Pete Becker
1
Não, "estar em segurança, usar por muito tempo" é o mesmo que dizer "estar em segurança, basta dar a todos uma única Aids, para que não tenhamos que nos preocupar com sexo seguro, todos nós já o temos de qualquer maneira!" Parvo, não? Pense nos dados e em quais valores possíveis eles podem ter e use o tipo de melhor ajuste. Isso também ajuda o compilador a fazer otimizações adicionais sem interromper a intenção do código original, como se tivesse que carregar bibliotecas adicionais para manipular números maiores que a largura de bits natural da plataforma de destino.
CM
Usar muito tempo com caixas de listagem win32 e similares costuma prejudicar sua memória e outras variáveis, mesmo que os limites não sejam violados. Mesmo com os avisos C4244 de aparência inócua, não é fácil detectar.
Laurie Stearn 26/02

Respostas:

182

longe long intsão idênticos. Então são long longe long long int. Nos dois casos, oint é opcional.

Quanto à diferença entre os dois conjuntos, o padrão C ++ exige intervalos mínimos para cada um, e que long longé pelo menos tão amplo quantolong .

As partes de controle do padrão (C ++ 11, mas isso já existe há muito tempo) são, por um lado 3.9.1 Fundamental types, a seção 2 (uma seção posterior fornece regras semelhantes para os tipos integrais não assinados):

Existem cinco tipos de números inteiros assinados padrão: char assinado, int curto, int, int longo e int long long. Nesta lista, cada tipo fornece pelo menos a quantidade de armazenamento que os anteriores à lista.

Há também uma tabela 9 7.1.6.2 Simple type specifiers, que mostra os "mapeamentos" dos especificadores para tipos reais (mostrando que inté opcional), cuja seção é mostrada abaixo:

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

Observe a distinção existente entre o especificador e o tipo. O especificador é como você diz ao compilador qual é o tipo, mas você pode usar diferentes especificadores para terminar no mesmo tipo.

Portanto, longpor si só, não é um tipo nem um modificador, como sugere sua pergunta, é simplesmente um especificador para o long inttipo. O mesmo vale por long longser um especificador para olong long int tipo.

Embora o próprio padrão C ++ não especifique os intervalos mínimos de tipos integrais, ele cita C99, in 1.2 Normative references, como aplicável. Portanto, os intervalos mínimos, conforme estabelecido em, C99 5.2.4.2.1 Sizes of integer types <limits.h>são aplicáveis.


Em termos de long double, na verdade, é um valor de ponto flutuante em vez de um número inteiro. Da mesma forma que os tipos integrais, é necessário ter pelo menos tanta precisão quanto doubleae fornecer um superconjunto de valores sobre esse tipo (significando pelo menos esses valores, não necessariamente mais valores).

paxdiablo
fonte
4
mesma coisa com unsignedeunsigned int
Kal
2
Eu tenho certeza que longtem pelo menos 32 bits (2 ^ 31-1 em ambos os lados do zero) e long longé pelo menos 64 (2 ^ 63-1 em ambos os lados).
Chris
2
E long doubleé garantido que tenha pelo menos o intervalo de double, mas pode ser o mesmo. Depende do computador. Algumas FPUs têm precisão estendida; os chips x87 tinham precisão única de 32 bits, precisão dupla de 64 bits e precisão estendida de 80 bits.
precisa saber é o seguinte
Quanto aos requisitos de faixa, o padrão C ++ 11 faz referência ao padrão C11, que possui faixas reais.
chris
A parte "int" simplesmente diferencia entre um tipo inteiro e ponto flutuante, caractere ou outro tipo não inteiro. Em muitos casos, isso pode ser inferido pelo compilador, e pode ser descartado. É por isso que "unsigned" é o mesmo que "unsigned int", por exemplo. A parte "int" é simplesmente assumida, a menos que o programador especifique outra coisa, como "char" ou "double". Quanto aos tamanhos reais usados ​​.. dependendo do padrão que você lê, cada tamanho pode ter um número mínimo de bits, mas todos são definidos de modo que cada um seja pelo menos tão grande quanto o tipo anterior.
CM
64

Long e long int são pelo menos 32 bits.

long long e long long int são pelo menos 64 bits. Você deve estar usando um compilador c99 ou melhor.

duplas longas são um pouco estranhas. Pesquise-os na Wikipedia para obter detalhes.

Eric Lippert
fonte
17

longé equivalente a long int, assim como shorté equivalente a short int. A long inté um tipo integral assinado com pelo menos 32 bits, enquanto a long longou long long inté um tipo integral assinado com pelo menos 64 bits.

Isso não significa necessariamente que a long longé mais amplo que a long. Muitas plataformas / ABIs usam o LP64modelo - onde long(e ponteiros) têm 64 bits de largura. O Win64 usa o LLP64, onde longainda há 32 bits, e long long(e ponteiros) têm 64 bits de largura.

Há um bom resumo dos modelos de dados de 64 bits aqui .

long doublenão garante muito mais do que será pelo menos tão largo quanto um double.

Brett Hale
fonte
7

Isso parece confuso porque você está usando longcomo um tipo de dados.

longnada mais é do que uma abreviação para long intquando você está usando sozinho.

longé um modificador, você pode usá-lo doubletambém comolong double .

long== long int.

Ambos têm 4 bytes.

Siraj Alam
fonte
Longo tomar 4 bytes é válida apenas em Win64, é dependente de plataforma
Prodigle
1
Sim, obviamente ... não apenas por muito tempo ... int leva 4 bytes e 2 bytes dependem da plataforma, sem dúvida.
Siraj Alam
3

Historicamente, nos primeiros tempos C, quando os processadores tinham comprimento de palavra de 8 ou 16 bits, intera idêntico ao de hoje short(16 bits). Em certo sentido, int é um tipo de dados mais abstrato do que char, short, longoulong long , como você não pode ter certeza sobre a largura de bits.

Ao definir, int n;você pode traduzir isso com "me dê o melhor compromisso de largura de banda e velocidade nesta máquina para n". Talvez no futuro você deva esperar que os compiladores sejam traduzidos intem 64 bits. Portanto, quando você quiser que sua variável tenha 32 bits e não mais, use melhor um método explícitolong como tipo de dados.

[Editar: #include <stdint.h>parece ser a maneira correta de garantir largura de bits usando os tipos int ## _ t, embora ainda não faça parte do padrão.]

Thomiel
fonte
2
Essa última parte, usando um "longo" para obter 32 bits quando int é 64 bits, está incorreta. Se int tiver 64 bits, o comprimento também será de pelo menos 64 bits. É garantido que long é pelo menos tão grande quanto int, embora possa ser maior, mas nunca menor. A maioria dos compiladores possui vários métodos que permitem ao programador ser mais específico, como um tipo __int32 (não portátil) com exatamente 32 bits e assim por diante.
CM
1
Conforme definido no padrão C, a longé garantido como sendo pelo menos 32 bits. (Os padrões podem ser difíceis.) O rascunho atual do C ++ 14 diz apenas: @CM "Ints simples têm o tamanho natural sugerido pela arquitetura do ambiente de execução; os outros tipos de números inteiros assinados são fornecidos para atender a necessidades especiais" (seção 3.9.1 ) Não encontrei nenhuma palavra sobre as relações de comprimento de várias entradas nele. __int32 não é realmente parte do padrão, mas desde o C ++ 11 existem typedefs disponíveis como int_fast32_t ou int_least32_t disponíveis para obter exatamente o que você deseja.
thomiel
Eu diria que nas implementações do século XX para microcomputadores reprogramáveis ​​de uso geral, chareram quase unanimemente 8 bits, short16 e long32; intpode ser 16 ou 32. Nota para algumas plataformas (especialmente a 68000), tanto de 16 como de 32 bits interam bastante comuns e, de fato, alguns compiladores tinham opções para oferecer suporte. O código que precisava ser portátil deveria, portanto, usar shortou longpreferir int.
supercat
0

Enquanto em Java a longé sempre de 64 bits, em C ++ isso depende da arquitetura e do sistema operacional do computador . Por exemplo, umlong é 64 bits no Linux e 32 bits no Windows (isso foi feito para manter a compatibilidade com versões anteriores, permitindo que programas de 32 bits sejam compilados no Windows de 64 bits sem nenhuma alteração).

É considerado um bom estilo C ++ para evitar short int long ... e 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

Estes ( int*_t) podem ser usados ​​depois de incluir o <cstdint>cabeçalho. size_testá em <stdlib.h>.

xjcl
fonte