Qual è la differenza tra "long", "long long", "long int" e "long long int" in C ++?


210

Sto passando da Java a C ++ e ho alcune domande sul longtipo di dati. In Java, per contenere un numero intero maggiore di 2 32 , dovresti semplicemente scrivere long x;. Tuttavia, in C ++, sembra che longsia sia un tipo di dati che un modificatore.

Sembra che ci siano diversi modi per usare long:

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

Inoltre, sembra che ci siano cose come:

long double x;

e così via.

Qual è la differenza tra tutti questi vari tipi di dati e hanno tutti lo stesso scopo?



2
@utente2612743 - per sicurezza, pensa a quali sono le tue esigenze e usa il tipo appropriato. long longpotrebbe essere più lento di long, che potrebbe essere più lento di int.
Pete Becker,


1
No, "per essere sicuri, usa molto tempo" è lo stesso che dire "per essere sicuri, dai a tutti un AIDS terrestre, quindi non dobbiamo preoccuparci del sesso sicuro, lo abbiamo già tutti!" Sciocco no? Pensa ai dati e ai possibili valori che possono avere e usa il tipo più adatto. Questo aiuta anche il compilatore a effettuare ulteriori ottimizzazioni senza interrompere l'intento del codice originale, ad esempio se deve caricare librerie aggiuntive per gestire numeri maggiori della larghezza di bit naturale della piattaforma di destinazione.
CM

Usare long long con le caselle di riepilogo win32 e simili non farà danni con la memoria e altre variabili, anche se i limiti non vengono violati. Anche con gli innocui avvisi C4244 non è facile da rilevare.
Laurie Stearn,

Risposte:


182

longe long intsono identici. Così sono long longe long long int. In entrambi i casi, intè facoltativo.

Per quanto riguarda la differenza tra i due insiemi, lo standard C ++ impone intervalli minimi per ciascuno, e questo long longè almeno altrettanto ampio long.

Le parti di controllo dello standard (C ++ 11, ma questo esiste da molto tempo) sono, per esempio 3.9.1 Fundamental types, la sezione 2 (una sezione successiva fornisce regole simili per i tipi integrali senza segno):

Esistono cinque tipi di numeri interi con segno standard: carattere con segno, int breve, int, long int e long long int. In questo elenco, ogni tipo fornisce almeno lo stesso spazio di archiviazione di quelli che lo precedono nell'elenco.

C'è anche una tabella 9 in 7.1.6.2 Simple type specifiers, che mostra i "mapping" degli specificatori ai tipi effettivi (mostrando che intè facoltativo), una sezione della quale è mostrata di seguito:

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

Nota la distinzione tra lo specificatore e il tipo. Lo specificatore è il modo in cui dici al compilatore di che tipo è ma puoi usare diversi specificatori per finire con lo stesso tipo.

Quindi longda solo non è né un tipo un modificatore come pone la tua domanda, è semplicemente un identificatore per il long inttipo. Idem per long longessere un identificatore per il long long inttipo.

Sebbene lo standard C ++ stesso non specifichi gli intervalli minimi di tipi integrali, cita C99, in 1.2 Normative references, come applicabile. Pertanto, C99 5.2.4.2.1 Sizes of integer types <limits.h>sono applicabili le gamme minime indicate in .


In termini di long double, questo è in realtà un valore in virgola mobile piuttosto che un numero intero. Analogamente ai tipi integrali, è necessario avere almeno la stessa precisione di a doublee fornire un superset di valori rispetto a quel tipo (ovvero almeno quei valori, non necessariamente più valori).


4
stessa cosa con unsignedeunsigned int
Kal

2
Sono abbastanza sicuro che longsia almeno 32 bit (2 ^ 31-1 su entrambi i lati dello zero) ed long longè almeno 64 (2 ^ 63-1 su entrambi i lati).
chris,

2
Ed long doubleè garantito che abbia almeno la gamma di double, ma potrebbe essere la stessa. Dipende dal computer. Alcune FPU hanno una precisione estesa; i chip x87 avevano precisione singola a 32 bit, precisione doppia a 64 bit e precisione estesa a 80 bit.
Eric Jablow,

Per quanto riguarda i requisiti di intervallo, lo standard C ++ 11 fa riferimento allo standard C11, che ha intervalli effettivi.
chris,

La parte "int" fa semplicemente una distinzione tra un tipo intero e virgola mobile, carattere o altro tipo non intero. In molti casi, questo può essere dedotto dal compilatore, quindi può essere eliminato - Ecco perché "unsigned" è lo stesso di "unsigned int", per esempio. La parte "int" viene semplicemente assunta a meno che il programmatore non specifichi qualcos'altro, come "char" o "double". Per quanto riguarda le dimensioni effettive utilizzate .. a seconda dello standard letto, ogni dimensione può avere un numero minimo di bit, ma sono tutti definiti in modo tale che ognuno sia almeno grande quanto il tipo precedente.
CM


17

longè equivalente a long int, così come shortè equivalente a short int. A long intè un tipo integrale con segno che è di almeno 32 bit, mentre a long longo long long intè un tipo integrale con segno di almeno 64 bit.

Questo non significa necessariamente che a long longsia più largo di a long. Molte piattaforme / ABI usano il LP64modello - dove long(e puntatori) hanno una larghezza di 64 bit. Win64 utilizza LLP64, dove longsono ancora 32 bit e long long(e puntatori) sono larghi 64 bit.

C'è un buon riassunto dei modelli di dati a 64 bit qui .

long doublenon garantisce molto altro che sarà largo almeno quanto a double.


7

Questo sembra confuso perché stai prendendo longcome un tipo di dati stesso.

longnon è altro che la scorciatoia per long intquando lo usi da solo.

longè un modificatore, puoi usarlo doubleanche con as long double.

long== long int.

Entrambi richiedono 4 byte.


Il lungo utilizzo di 4 byte è valido solo su Win64, dipende dalla piattaforma
Prodigle

1
Sì, ovviamente ... non solo a lungo ... int richiede 4 byte e 2 byte dipendono dalla piattaforma, senza dubbio.
Siraj Alam,

3

Storicamente, nei primi tempi del C, quando i processori avevano una lunghezza di parola di 8 o 16 bit, intera identico a quello attuale short(16 bit). In un certo senso, int è un tipo di dati più astratto char, short, longolong long , come non si può essere sicuri della bitwidth.

Quando si definisce int n;è possibile tradurre questo con "dammi il miglior compromesso di larghezza di bit e velocità su questa macchina per n". Forse in futuro dovresti aspettarti che i compilatori traducano inta 64 bit. Quindi, quando vuoi che la tua variabile abbia 32 bit e non di più, usa meglio un tipo esplicito longcome tipo di dati.

[Modifica: #include <stdint.h>sembra essere il modo corretto per garantire bitwidth usando i tipi int ## _ t, anche se non fa ancora parte dello standard.]


2
L'ultima parte, usando un "long" per ottenere 32 bit quando int è 64 bit, non è corretta. Se int è a 64 bit, anche long sarà almeno a 64 bit. Long è garantito per essere almeno grande quanto int, anche se può essere più grande, ma mai più piccolo. La maggior parte dei compilatori ha vari metodi che consentono al programmatore di essere più specifico, come un tipo __int32 (non portatile) che è esattamente a 32 bit e così via.
CM

1
Come definito nello standard C, a longè garantito che sia almeno 32 bit. (Gli standard possono cambiare molto.) L'attuale bozza C ++ 14 dice semplicemente: @CM "Gli ints semplici hanno le dimensioni naturali suggerite dall'architettura dell'ambiente di esecuzione, gli altri tipi interi con segno sono forniti per soddisfare esigenze speciali" (sezione 3.9.1 ). Non ho trovato alcuna parola sulle relazioni di lunghezza di vari ints in esso. __int32 non fa veramente parte dello standard, ma dal C ++ 11 ci sono typedef disponibili come int_fast32_t o int_least32_t disponibili per darti esattamente quello che vuoi.
thomiel,

Direi che sulle implementazioni del ventesimo secolo per i microcomputer riprogrammabili per uso generico, charera quasi all'unanimità a 8 bit, a short16 e a long32; intpotrebbe essere 16 o 32. Nota per alcune piattaforme (in particolare il 68000) sia 16-bit che 32-bit interano abbastanza comuni, e in effetti alcuni compilatori avevano opzioni per supportare entrambi. Ci si aspettava quindi che il codice che doveva essere portatile fosse usato shorto longpreferito int.
supercat,

0

Mentre in Java a longè sempre 64 bit, in C ++ questo dipende dall'architettura del computer e dal sistema operativo . Ad esempio, a longè 64 bit su Linux e 32 bit su Windows (ciò è stato fatto per mantenere la retrocompatibilità, consentendo la compilazione di programmi a 32 bit su Windows a 64 bit senza alcuna modifica).

È considerato un buon stile C ++ da evitare short int long ... e invece usare:

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

Questi ( int*_t) possono essere utilizzati dopo aver incluso l' <cstdint>intestazione. size_tè dentro <stdlib.h>.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.