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

Correggimi se sbaglio,

int è 4 byte, con un intervallo di valori da -2.147.483.648 a 2.147.483.647 (2 ^ 31)
lungo è 4 byte, con un intervallo di valori da -2.147.483.648 a 2.147.483.647 (2 ^ 31)

Qual è la differenza in C ++? Possono essere usati in modo intercambiabile?

È dipendente dall’implementazione.

Ad esempio, sotto Windows sono uguali, ma per esempio su sistemi Alpha un lungo era di 64 bit mentre un int era di 32 bit. Questo articolo riguarda le regole per il compilatore Intel C ++ su piattaforms variabili. Riassumere:

  OS arch size Windows IA-32 4 bytes Windows Intel 64 4 bytes Windows IA-64 4 bytes Linux IA-32 4 bytes Linux Intel 64 8 bytes Linux IA-64 8 bytes Mac OS X IA-32 4 bytes Mac OS X Intel 64 8 bytes 

L’unica garanzia che hai sono:

 sizeof(char) == 1 sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long) // FROM @KTC. The C++ standard also has: sizeof(signed char) == 1 sizeof(unsigned char) == 1 // NOTE: These size are not specified explicitly in the standard. // They are implied by the minimum/maximum values that MUST be supported // for the type. These limits are defined in limits.h sizeof(short) * CHAR_BIT >= 16 sizeof(int) * CHAR_BIT >= 16 sizeof(long) * CHAR_BIT >= 32 sizeof(long long) * CHAR_BIT >= 64 CHAR_BIT >= 8 // Number of bits in a byte 

Vedi anche: è garantito che abbia almeno 32 bit?

Quando compili per x64, la differenza tra int e long è da qualche parte tra 0 e 4 byte, a seconda del compilatore che usi.

GCC usa il modello LP64, il che significa che gli interi sono a 32 bit ma quelli lunghi sono a 64 bit in modalità a 64 bit.

MSVC ad esempio utilizza il modello LLP64, il che significa che sia ints che long sono 32 bit anche in modalità 64 bit.

La specifica C ++ stessa (vecchia versione ma abbastanza valida per questo) lascia aperta questa.

Esistono quattro tipi di interi con signed char : ‘ signed char ‘, ‘ short int ‘, ‘ int ‘ e ‘ long int ‘. In questo elenco, ciascun tipo fornisce almeno lo stesso spazio di archiviazione di quelli che lo precedono nell’elenco. I plain ints hanno le dimensioni naturali suggerite dall’architettura dell’ambiente di esecuzione *;

[Nota in calce: cioè, abbastanza grande da contenere qualsiasi valore nell’intervallo di INT_MIN e INT_MAX, come definito nell’intestazione . — end foonote]

Come sottolinea Kevin Haines, gli inte hanno le dimensioni naturali suggerite dall’ambiente di esecuzione, che deve rientrare in INT_MIN e INT_MAX.

Lo standard C89 afferma che UINT_MAX dovrebbe essere almeno 2 ^ 16-1, USHRT_MAX 2 ^ 16-1 e ULONG_MAX 2 ^ 32-1. Questo rende un conteggio di almeno 16 in breve e int e 32 in lungo. Per char afferma esplicitamente che dovrebbe avere almeno 8 bit ( CHAR_BIT ). C ++ eredita quelle regole per il file limits.h, quindi in C ++ abbiamo gli stessi requisiti fondamentali per quei valori. Non dovresti comunque derivare da ciò che int è almeno 2 byte. Teoricamente, char, int e long potrebbero essere tutti 1 byte, nel qual caso CHAR_BIT deve essere almeno 32. Basta ricordare che “byte” è sempre la dimensione di un char, quindi se char è più grande, un byte non è solo 8 bit più.

Dipende dal tuo compilatore. Hai la certezza che un lungo sarà grande almeno quanto un int, ma non ti sarà garantito che lo sarà ancora.

Per la maggior parte, il numero di byte e l’intervallo di valori è determinato dall’architettura della CPU non da C ++. Tuttavia, C ++ stabilisce requisiti minimi, che litb ha spiegato correttamente e Martin York ha fatto solo alcuni errori con.

Il motivo per cui non è ansible utilizzare int e long intercambiabile è perché non sono sempre della stessa lunghezza. C è stato inventato su un PDP-11 in cui un byte aveva 8 bit, int era due byte e poteva essere gestito direttamente dalle istruzioni hardware. Dato che i programmatori C spesso avevano bisogno di aritmetica a quattro byte, fu inventato a lungo ed erano quattro byte, gestiti dalle funzioni di libreria. Altre macchine avevano specifiche diverse. Lo standard C impone alcuni requisiti minimi.

Affidarsi all’implementazione di dimensioni di tipo primitive da parte del fornitore del compilatore tornerà a perseguitarti se compili il tuo codice su un’altra architettura di macchina, su un sistema operativo o su un altro compilatore di un fornitore.

La maggior parte dei produttori di compilatori fornisce un file di intestazione che definisce i tipi primitivi con dimensioni di tipo explict. Questi tipi primitivi dovrebbero essere usati quando mai il codice può essere potenzialmente portato su un altro compilatore (leggi questo come SEMPRE in OGNI istanza). Ad esempio, la maggior parte dei compilatori UNIX ha int8_t uint8_t int16_t int32_t uint32_t . Microsoft ha INT8 UINT8 INT16 UINT16 INT32 UINT32 . Preferisco l’ int8 uint8 int16 uint16 int32 uint32 di Borland / CodeGear int8 uint8 int16 uint16 int32 uint32 . Questi nomi danno anche un piccolo promemoria della dimensione / intervallo del valore previsto.

Per anni ho usato i nomi di tipo primitivo esplicito di Borland e #include il seguente file di intestazione C / C ++ (primitive.h) che è destinato a definire i tipi primitivi espliciti con questi nomi per qualsiasi compilatore C / C ++ (questo file di intestazione potrebbe non effettivamente copre ogni compilatore ma copre diversi compilatori che ho usato su Windows, UNIX e Linux, ma non definisce (ancora) i tipi a 64 bit).

 #ifndef primitiveH #define primitiveH // Header file primitive.h // Primitive types // For C and/or C++ // This header file is intended to define a set of primitive types // that will always be the same number bytes on any operating operating systems // and/or for several popular C/C++ compiler vendors. // Currently the type definitions cover: // Windows (16 or 32 bit) // Linux // UNIX (HP/US, Solaris) // And the following compiler vendors // Microsoft, Borland/Imprise/CodeGear, SunStudio, HP/UX // (maybe GNU C/C++) // This does not currently include 64bit primitives. #define float64 double #define float32 float // Some old C++ compilers didn't have bool type // If your compiler does not have bool then add emulate_bool // to your command line -D option or defined macros. #ifdef emulate_bool # ifdef TVISION # define bool int # define true 1 # define false 0 # else # ifdef __BCPLUSPLUS__ //BC++ bool type not available until 5.0 # define BI_NO_BOOL # include  # else # define bool int # define true 1 # define false 0 # endif # endif #endif #ifdef __BCPLUSPLUS__ # include  #else # ifdef unix # ifdef hpux # include  # endif # ifdef sun # include  # endif # ifdef linux # include  # endif # define int8 int8_t # define uint8 uint8_t # define int16 int16_t # define int32 int32_t # define uint16 uint16_t # define uint32 uint32_t # else # ifdef _MSC_VER # include  # define int8 INT8 # define uint8 UINT8 # define int16 INT16 # define int32 INT32 # define uint16 UINT16 # define uint32 UINT32 # else # ifndef OWL6 // OWL version 6 already defines these types # define int8 char # define uint8 unsigned char # ifdef __WIN32_ # define int16 short int # define int32 long # define uint16 unsigned short int # define uint32 unsigned long # else # define int16 int # define int32 long # define uint16 unsigned int # define uint32 unsigned long # endif # endif # endif # endif #endif typedef int8 sint8; typedef int16 sint16; typedef int32 sint32; typedef uint8 nat8; typedef uint16 nat16; typedef uint32 nat32; typedef const char * cASCIIz; // constant null terminated char array typedef char * ASCIIz; // null terminated char array #endif //primitive.h 

Lo standard C ++ dice in questo modo:

3.9.1, §2:

Esistono cinque tipi di interi con segno: “signed char”, “short int”, “int”, “long int” e “long long int”. In questo elenco, ciascun tipo fornisce almeno lo stesso spazio di archiviazione di quelli che lo precedono nell’elenco. I plain ints hanno le dimensioni naturali suggerite dall’architettura dell’ambiente di esecuzione (44); gli altri tipi di interi con segno sono forniti per soddisfare esigenze particolari.

(44) cioè, abbastanza grande da contenere qualsiasi valore nell’intervallo di INT_MIN e INT_MAX, come definito nell’intestazione .

La conclusione: dipende da quale architettura stai lavorando. Ogni altra ipotesi è falsa.