int to 4 bajty, z zakresem wartości od -2 147 483 648 do 2147 483647 (2 ^ 31)
long to 4 bajty, z zakresem wartości od -2 147 483 648 do 2 147 483 647 (2 ^ 31)
Jaka jest różnica w C ++? Czy można ich używać zamiennie?
Jeśli chcesz pisać kod przenośny, rozważ użycie, #include <stdint.h>a następnie typów, które określają rozmiar. Np uint32_t. Na nowej platformie musisz tylko upewnić się, że stdint.h działa prawidłowo dla tej konkretnej platformy, a kod działa zgodnie z przeznaczeniem.
BitTickler
Odpowiedzi:
112
Jest to zależne od implementacji.
Na przykład w systemie Windows są takie same, ale na przykład w systemach Alpha długość long wynosiła 64 bity, podczas gdy int - 32 bity. W tym artykule omówiono zasady dotyczące kompilatora Intel C ++ na platformach zmiennych. Podsumowując:
OS arch size
Windows IA-324 bytes
WindowsIntel644 bytes
Windows IA-644 bytes
Linux IA-324 bytes
LinuxIntel648 bytes
Linux IA-648 bytes
Mac OS X IA-324 bytes
Mac OS X Intel648 bytes
Myślę, że powinniśmy rozważyć połączenie tej odpowiedzi (odpowiedzi na przykładzie) z niektórymi szczegółami dotyczącymi standardu C ++ poniżej. Wersja robocza C ++ 0x znajduje się pod adresem open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2798.pdf i jest oznaczona, aby można było zobaczyć różnice między nią a ostatnią wersją.
Patrick Johnmeyer,
Uwzględnienie czegoś we względnej kolejności według rozmiaru daje o wiele więcej informacji niż wyliczanie rozmiarów dla różnych platform - tak ładnie stwierdza @Kevin. (-1 głos)
xtofl
2
Niektóre kompilatory mają nawet flagi, które pozwalają na modyfikację domyślnego rozmiaru int i long, tj. Wymuszają na nich 8 lub 16 itd. Szczegóły znajdziesz w dokumentacji kompilatora.
Martin York,
7
Uwaga, to są rozmiary long
rogerdpack
1
Proszę podać również rozmiary int.
cegprakash
82
Jedyną gwarancją, jaką masz, są:
sizeof(char)==1sizeof(char)<=sizeof(short)<=sizeof(int)<=sizeof(long)<=sizeof(longlong)// FROM @KTC. The C++ standard also has:sizeof(signedchar)==1sizeof(unsignedchar)==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.hsizeof(short)* CHAR_BIT >=16sizeof(int)* CHAR_BIT >=16sizeof(long)* CHAR_BIT >=32sizeof(longlong)* CHAR_BIT >=64
CHAR_BIT >=8// Number of bits in a byte
Hmm, to nie jest prawdą, jeśli sizeof (short)> = sizeof (char) znamy tylko ten sizeof (short)> = 1 (not> = 2), co przy okazji dotyczy wszystkich typów. Zgodnie z tym sizeof (dowolny typ całkowy)> = 1. Co jest prawdą, np. Pamiętam sizeof (int) == 1 na Z80, ale czy nie ma silniejszej gwarancji na długo?
Andreas Magnusson
6
3.9.1.2 standardu C ++ określa, że sizeof (long)> = sizeof (int)> = sizeof (short)> = sizeof (char) 5.3.3.1 standardu C ++ określa, że sizeof (char), sizeof (unsigned char) , a rozmiar (znak ze znakiem) jest równy 1. (cd ...)
KTC
4
(... cd) Maksymalne i minimalne wartości reprezentowane przez typy całkowite są zdefiniowane jako makra w <limits.h> (a zatem <climits>). Załącznik E do normy C (1990), który jest włączony przez odniesienie do standardu C ++, określa minimalne wielkości tych makr. (ciąg dalszy ...)
KTC,
4
(... cd.) i są to (2 ^ 15) -1, (2 ^ 15) -1, (2 ^ 31) -1, odpowiednio dla short, int i long, co okazuje się być wartością równą opublikowane przez Martina Yorka w jego odpowiedzi tutaj, jeśli CHAR_BIT wynosi 8 (co jest również jego minimalną wartością).
KTC,
2
@Giles: Czy to nie to, co powiedziałem powyżej? sizeof (short) * CHAR_BITS> = 16. Wybierz kilka innych rzeczy. :-)
Martin York
13
Podczas kompilacji dla x64 różnica między int i long wynosi od 0 do 4 bajtów, w zależności od używanego kompilatora.
GCC używa modelu LP64, co oznacza, że wartości typu int są 32-bitowe, ale długie są 64-bitowe w trybie 64-bitowym.
Na przykład MSVC używa modelu LLP64, co oznacza, że zarówno int, jak i long są 32-bitowe nawet w trybie 64-bitowym.
Sama specyfikacja C ++ (stara wersja, ale wystarczająco dobra do tego) pozostawia to otwarte.
Istnieją cztery typy liczb całkowitych ze znakiem: „ signed char”, „ short int”, „ int” i „ long int”. Na tej liście każdy typ zapewnia co najmniej tyle samo miejsca, co te poprzedzające go na liście. Zwykłe liczby int mają naturalny rozmiar sugerowany przez architekturę środowiska wykonawczego *;
[Przypis: to znaczy wystarczająco duży, aby zawierać dowolną wartość z zakresu INT_MIN i INT_MAX, zgodnie z definicją w nagłówku <climits>. --- end foonote]
Jak wskazuje Kevin Haines, ints mają naturalny rozmiar sugerowany przez środowisko wykonawcze, które musi mieścić się w INT_MIN i INT_MAX.
Standard C89 określa, że UINT_MAXpowinno to wynosić co najmniej 2 ^ 16-1, USHRT_MAX2 ^ 16-1 i ULONG_MAX2 ^ 32-1. To daje co najmniej 16 bitów dla short i int oraz 32 dla long. Dla char wyraźnie stwierdza, że powinien mieć co najmniej 8 bitów ( CHAR_BIT). C ++ dziedziczy te reguły dla pliku limits.h, więc w C ++ mamy te same podstawowe wymagania dla tych wartości. Należy jednak nie wynikają z tego, że int jest co najmniej 2 bajt. Teoretycznie wszystkie znaki char, int i long mogą wynosić 1 bajt, w którym to przypadku CHAR_BITmusi wynosić co najmniej 32. Pamiętaj tylko, że „bajt” ma zawsze rozmiar znaku, więc jeśli znak jest większy, bajt to nie tylko 8 bitów więcej.
Nie sądziłem, że byteistnieje typ danych w C ++. Tak nie jest, prawda? Jeśli tak, a bytemoże mieć inne rozmiary niż 8 bitów, jest to po prostu głupie. Dlaczego mieliby nazywać to bajtem, jeśli absolutnie koniecznie jest to 8 bitów?
Alderath
6
To zależy od twojego kompilatora. Masz gwarancję, że long będzie co najmniej tak duży jak int, ale nie masz gwarancji, że będzie dłuższy.
W większości przypadków liczba bajtów i zakres wartości jest określana przez architekturę procesora, a nie przez C ++. Jednak C ++ wyznacza minimalne wymagania, które litb poprawnie wyjaśnił, a Martin York popełnił tylko kilka błędów z.
Powodem, dla którego nie można używać zamiennie int i long, jest to, że nie zawsze mają taką samą długość. C został wynaleziony na PDP-11, gdzie bajt miał 8 bitów, int miał dwa bajty i mógł być obsługiwany bezpośrednio przez instrukcje sprzętowe. Ponieważ programiści C często potrzebowali czterobajtowej arytmetyki, wynaleziono long i było to cztery bajty, obsługiwane przez funkcje biblioteczne. Inne maszyny miały inne specyfikacje. Norma C nakładała pewne minimalne wymagania.
Poleganie na implementacji prymitywnych rozmiarów typów przez dostawcę kompilatora POWRÓCI i prześladuje Cię, jeśli kiedykolwiek skompilujesz swój kod na innej architekturze maszyny, systemie operacyjnym lub kompilatorze innego dostawcy.
Większość dostawców kompilatorów udostępnia plik nagłówkowy, który definiuje typy pierwotne z jawnymi rozmiarami typów. Te typy pierwotne powinny być używane, gdy kod może zostać potencjalnie przeniesiony do innego kompilatora (czytaj to ZAWSZE w KAŻDEJ instancji). Na przykład większość kompilatorów UNIX ma int8_t uint8_t int16_t int32_t uint32_t. Microsoft ma INT8 UINT8 INT16 UINT16 INT32 UINT32. Wolę Borland / CodeGear int8 uint8 int16 uint16 int32 uint32. Nazwy te również przypominają nieco rozmiar / zakres zamierzonej wartości.
Od lat używam jawnych nazw typów pierwotnych Borlanda i #includenastępującego pliku nagłówkowego C / C ++ (primitive.h), który ma na celu zdefiniowanie jawnych typów pierwotnych z tymi nazwami dla dowolnego kompilatora C / C ++ (ten plik nagłówkowy może w rzeczywistości nie obejmować wszystkich kompilator, ale obejmuje kilka kompilatorów, których używałem na Windows, UNIX i Linux, również (jeszcze) nie definiuje typów 64-bitowych).
#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.#definefloat64double#definefloat32float// 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 <classlib/defs.h># else# define bool int# define true 1# define false 0# endif# endif#endif#ifdef __BCPLUSPLUS__
# include <systypes.h>#else# ifdef unix# ifdef hpux# include <sys/_inttypes.h># endif# ifdef sun# include <sys/int_types.h># endif# ifdef linux# include <idna.h># 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 <BaseTSD.h># 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#endiftypedefint8 sint8;typedefint16 sint16;typedefint32 sint32;typedefuint8 nat8;typedefuint16 nat16;typedefuint32 nat32;typedefconstchar* cASCIIz;// constant null terminated char arraytypedefchar*ASCIIz;// null terminated char array#endif//primitive.h
C99 nakazuje, aby typdefy wyglądające jak int32_t, uint64_t itp. Były definiowane przez kompilator i miały dokładnie tyle bitów, ile sugeruje nazwa. Większość kompilatorów C ++ (w tym g ++) pozwoli ci użyć tych stałych w kodzie C ++.
Istnieje pięć typów liczb całkowitych ze znakiem: „signed char”, „short int”, „int”, „long int” i „long long int”. Na tej liście każdy typ zapewnia co najmniej tyle samo miejsca, co te poprzedzające go na liście. Zwykłe int mają naturalny rozmiar sugerowany przez architekturę środowiska wykonawczego (44); inne typy liczb całkowitych ze znakiem są dostarczane w celu spełnienia specjalnych potrzeb.
(44) to znaczy wystarczająco duże, aby zawierać dowolną wartość z zakresu INT_MIN i INT_MAX, zgodnie z definicją w nagłówku
<climits> .
Wniosek: to zależy od architektury, nad którą pracujesz. Każde inne założenie jest fałszywe.
#include <stdint.h>
a następnie typów, które określają rozmiar. Npuint32_t
. Na nowej platformie musisz tylko upewnić się, że stdint.h działa prawidłowo dla tej konkretnej platformy, a kod działa zgodnie z przeznaczeniem.Odpowiedzi:
Jest to zależne od implementacji.
Na przykład w systemie Windows są takie same, ale na przykład w systemach Alpha długość long wynosiła 64 bity, podczas gdy int - 32 bity. W tym artykule omówiono zasady dotyczące kompilatora Intel C ++ na platformach zmiennych. Podsumowując:
źródło
Jedyną gwarancją, jaką masz, są:
Zobacz także: Czy
long
gwarantowane jest co najmniej 32 bity?źródło
Podczas kompilacji dla x64 różnica między int i long wynosi od 0 do 4 bajtów, w zależności od używanego kompilatora.
GCC używa modelu LP64, co oznacza, że wartości typu int są 32-bitowe, ale długie są 64-bitowe w trybie 64-bitowym.
Na przykład MSVC używa modelu LLP64, co oznacza, że zarówno int, jak i long są 32-bitowe nawet w trybie 64-bitowym.
źródło
Sama specyfikacja C ++ (stara wersja, ale wystarczająco dobra do tego) pozostawia to otwarte.
źródło
Jak wskazuje Kevin Haines, ints mają naturalny rozmiar sugerowany przez środowisko wykonawcze, które musi mieścić się w INT_MIN i INT_MAX.
Standard C89 określa, że
UINT_MAX
powinno to wynosić co najmniej 2 ^ 16-1,USHRT_MAX
2 ^ 16-1 iULONG_MAX
2 ^ 32-1. To daje co najmniej 16 bitów dla short i int oraz 32 dla long. Dla char wyraźnie stwierdza, że powinien mieć co najmniej 8 bitów (CHAR_BIT
). C ++ dziedziczy te reguły dla pliku limits.h, więc w C ++ mamy te same podstawowe wymagania dla tych wartości. Należy jednak nie wynikają z tego, że int jest co najmniej 2 bajt. Teoretycznie wszystkie znaki char, int i long mogą wynosić 1 bajt, w którym to przypadkuCHAR_BIT
musi wynosić co najmniej 32. Pamiętaj tylko, że „bajt” ma zawsze rozmiar znaku, więc jeśli znak jest większy, bajt to nie tylko 8 bitów więcej.źródło
byte
istnieje typ danych w C ++. Tak nie jest, prawda? Jeśli tak, abyte
może mieć inne rozmiary niż 8 bitów, jest to po prostu głupie. Dlaczego mieliby nazywać to bajtem, jeśli absolutnie koniecznie jest to 8 bitów?To zależy od twojego kompilatora. Masz gwarancję, że long będzie co najmniej tak duży jak int, ale nie masz gwarancji, że będzie dłuższy.
źródło
W większości przypadków liczba bajtów i zakres wartości jest określana przez architekturę procesora, a nie przez C ++. Jednak C ++ wyznacza minimalne wymagania, które litb poprawnie wyjaśnił, a Martin York popełnił tylko kilka błędów z.
Powodem, dla którego nie można używać zamiennie int i long, jest to, że nie zawsze mają taką samą długość. C został wynaleziony na PDP-11, gdzie bajt miał 8 bitów, int miał dwa bajty i mógł być obsługiwany bezpośrednio przez instrukcje sprzętowe. Ponieważ programiści C często potrzebowali czterobajtowej arytmetyki, wynaleziono long i było to cztery bajty, obsługiwane przez funkcje biblioteczne. Inne maszyny miały inne specyfikacje. Norma C nakładała pewne minimalne wymagania.
źródło
Poleganie na implementacji prymitywnych rozmiarów typów przez dostawcę kompilatora POWRÓCI i prześladuje Cię, jeśli kiedykolwiek skompilujesz swój kod na innej architekturze maszyny, systemie operacyjnym lub kompilatorze innego dostawcy.
Większość dostawców kompilatorów udostępnia plik nagłówkowy, który definiuje typy pierwotne z jawnymi rozmiarami typów. Te typy pierwotne powinny być używane, gdy kod może zostać potencjalnie przeniesiony do innego kompilatora (czytaj to ZAWSZE w KAŻDEJ instancji). Na przykład większość kompilatorów UNIX ma
int8_t uint8_t int16_t int32_t uint32_t
. Microsoft maINT8 UINT8 INT16 UINT16 INT32 UINT32
. Wolę Borland / CodeGearint8 uint8 int16 uint16 int32 uint32
. Nazwy te również przypominają nieco rozmiar / zakres zamierzonej wartości.Od lat używam jawnych nazw typów pierwotnych Borlanda i
#include
następującego pliku nagłówkowego C / C ++ (primitive.h), który ma na celu zdefiniowanie jawnych typów pierwotnych z tymi nazwami dla dowolnego kompilatora C / C ++ (ten plik nagłówkowy może w rzeczywistości nie obejmować wszystkich kompilator, ale obejmuje kilka kompilatorów, których używałem na Windows, UNIX i Linux, również (jeszcze) nie definiuje typów 64-bitowych).źródło
Standard C ++ mówi to tak:
3.9.1, §2:
Wniosek: to zależy od architektury, nad którą pracujesz. Każde inne założenie jest fałszywe.
źródło