C ++ 'da bir int ve uzun arasındaki fark nedir?


120

Eğer Yanlışsam beni düzelt,

int, -2.147.483.648 ile 2.147.483.647 (2 ^ 31)
arasında bir değer aralığı ile 4 bayttır, -2.147.483.648 ile 2.147.483.647 (2 ^ 31) arasında bir değer aralığı ile 4 bayttır

C ++ 'daki fark nedir? Birbirlerinin yerine kullanılabilirler mi?


32 bit işlemci üzerinde çalışan VS2005'imde varsayılan int boyutu 4 bayttır.


Taşınabilir kod yazmak istiyorsanız, kullanmayı #include <stdint.h>ve ardından boyutu belirten türleri kullanmayı düşünün . Örn uint32_t. Yeni bir platformda, sadece stdint.h'nin o platform için doğru olduğundan ve kodunuzun amaçlandığı gibi çalıştığından emin olmanız gerekir.
BitTickler

Yanıtlar:


112

Uygulamaya bağlıdır.

Örneğin, Windows altında bunlar aynıdır, ancak örneğin Alpha sistemlerinde uzun 64 bit iken bir int 32 bittir. Bu makale , değişken platformlarda Intel C ++ derleyicisinin kurallarını kapsar. Özetlemek:

  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  

Sanırım bu cevabı (örnek bir cevap) C ++ standardıyla ilgili aşağıdaki detaylardan bazılarıyla birleştirmeyi düşünmeliyiz. C ++ 0x taslağı open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2798.pdf adresindedir ve işaretlenmiştir, böylece onunla son devir arasındaki farkları görebilirsiniz.
Patrick Johnmeyer

Türlerin göreceli boyut bakımından sırasına bir şey dahil etmek, farklı platformlar için boyutları sıralamaktan çok daha fazla bilgi sağlar - @ Kevin'in çok güzel ifade etmesi gibi. (-1vote)
xtofl

2
Hatta bazı derleyiciler, int ve long'un varsayılan boyutunu değiştirmenize izin veren bayraklara sahiptir, yani onları 8 veya 16'ya zorlar vb. Ayrıntılar için derleyicinizin belgelerine bakın.
Martin York

7
Not, bunlar uzun
rogerdpack

1
Lütfen int boyutlarını da ekleyin.
cegprakash

82

Sahip olduğunuz tek garanti:

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

Ayrıca bkz: Is longen az 32 bit olması garanti?


1
Hmm, bu geçerli değildir, eğer sizeof (short)> = sizeof (char) ise, sadece sizeof (short)> = 1 (> = 2 değil) olduğunu biliyoruz, ki btw tüm türler için geçerli. Bu sizeof'a göre (herhangi bir integral türü)> = 1. Hangisi doğrudur, örneğin Z80'de sizeof (int) == 1'i hatırlıyorum, ancak uzun süre daha güçlü bir garanti yok mu?
Andreas Magnusson

6
C ++ standardının 3.9.1.2'si sizeof (long)> = sizeof (int)> = sizeof (short)> = sizeof (char) olduğunu belirtir. C ++ standardının 5.3.3.1'i sizeof (char), sizeof (unsigned char) , ve sizeof (işaretli karakter) 1'e eşittir. (devamı ...)
KTC

4
(... devamı) İntegral türleri tarafından gösterilebilen maksimum ve minimum değerler, <limits.h> (ve dolayısıyla <climits>) içinde makrolar olarak tanımlanır. C ++ standardından referans olarak dahil edilen C (1990) standardının Ek E'si, bu makroların minimum büyüklüklerini belirtir. (devamı ...)
KTC

4
(... devamı) ve bunlar kısa, int ve uzun için sırasıyla (2 ^ 15) -1, (2 ^ 15) -1, (2 ^ 31) -1, CHAR_BIT 8 ise (bu aynı zamanda minimum değerdir) Martin York tarafından buradaki cevabında yayınlanmıştır.
KTC

2
@Giles: Yukarıda söylediğim bu değil mi? sizeof (short) * CHAR_BITS> = 16. Diğer birkaç şeyi ekleyin. :-)
Martin York

13

X64 için derlerken, int ve long arasındaki fark, kullandığınız derleyiciye bağlı olarak 0 ile 4 bayt arasındadır.

GCC, LP64 modelini kullanır; bu, girişlerin 32 bit olduğu ancak uzunların 64 bit modunda 64 bit olduğu anlamına gelir.

Örneğin MSVC, LLP64 modelini kullanır, bu da hem ints hem de longların 64-bit modunda bile 32-bit olduğu anlamına gelir.


muhtemelen 0 bayt? hmm
rogerdpack

12

C ++ şartname kendisi (bunun için eski sürüm ama yeterince iyi) bu açık bırakır.

Dört işaretli tam sayı türü vardır: ' signed char', ' short int', ' int' ve ' long int'. Bu listede, her tür, listede kendisinden önce gelenler kadar en az depolama alanı sağlar. Düz girişler, yürütme ortamının * mimarisinin önerdiği doğal boyuta sahiptir;

[Dipnot: yani, başlıkta tanımlandığı gibi INT_MIN ve INT_MAX aralığındaki herhangi bir değeri içerecek kadar büyüktür <climits>. --- foonote sonlandır]


7

Kevin Haines'in işaret ettiği gibi, girişler, INT_MIN ve INT_MAX'a uyması gereken, yürütme ortamı tarafından önerilen doğal boyuta sahiptir.

C89 standardı, UINT_MAXen az 2 ^ 16-1, USHRT_MAX2 ^ 16-1 olması gerektiğini belirtir veULONG_MAX 2 ^ 32-1 . Bu, kısa ve int için en az 16 ve uzun için 32 bit sayımı yapar. Char için en az 8 bit ( CHAR_BIT) olması gerektiğini açıkça belirtir . C ++, limits.h dosyası için bu kuralları miras alır, bu nedenle C ++ 'da bu değerler için aynı temel gereksinimlere sahibiz. Bununla birlikte gerektiğini değil o int en az 2 bayt olduğunu kaynaklanıyor. Teorik olarak, char, int ve long 1 bayt olabilir, bu durumda CHAR_BITen az 32 olmalıdır. Unutmayın ki "bayt" her zaman bir char boyutundadır, yani char daha büyükse, bayt herhangi bir 8 bit değildir. Daha.


byteC ++ 'da bir veri türü olduğunu düşünmemiştim . Öyle değil mi? Eğer öyleyse ve a byte8 bitten başka boyutlara sahipse, tamamen aptalca. Mutlaka 8 bit olmadıkça neden bayt olarak adlandırıyorlar?
Alderath

6

Derleyicinize bağlıdır. Uzunluğun en az bir int kadar geniş olacağı garantilidir, ancak daha uzun olacağı garanti edilmez.


5

Çoğunlukla, bayt sayısı ve değer aralığı, C ++ tarafından değil CPU'nun mimarisi tarafından belirlenir. Bununla birlikte, C ++ minimum gereksinimleri belirler, bu da litb'nin doğru bir şekilde açıkladığı ve Martin York'ta yalnızca birkaç hata yaptı.

İnt ve long'u birbirinin yerine kullanamamanızın nedeni, her zaman aynı uzunlukta olmamalarıdır. C, bir baytın 8 bit, int'in iki bayt olduğu ve doğrudan donanım talimatları ile işlenebileceği bir PDP-11'de icat edildi. C programcıları genellikle dört baytlık aritmetiğe ihtiyaç duyduğundan, uzun icat edildi ve kütüphane işlevleri tarafından yönetilen dört bayttı. Diğer makinelerin farklı özellikleri vardı. C standardı bazı asgari gereklilikler getirdi.


5

Derleyici satıcısının ilkel tür boyutları uygulamasına güvenmek, kodunuzu başka bir makine mimarisinde, işletim sisteminde veya başka bir satıcının derleyicisinde derlerseniz sizi rahatsız etmek için GERİ DÖNECEKTİR.

Çoğu derleyici satıcısı, ilkel türleri açık tür boyutlarıyla tanımlayan bir başlık dosyası sağlar. Bu ilkel türler, kod potansiyel olarak başka bir derleyiciye taşındığında kullanılmalıdır (bunu HER ZAMAN HER durumda olarak okuyun). Örneğin, çoğu UNIX derleyicisinde int8_t uint8_t int16_t int32_t uint32_t. Microsoft INT8 UINT8 INT16 UINT16 INT32 UINT32. Borland / CodeGear'ı tercih ederim int8 uint8 int16 uint16 int32 uint32. Bu isimler ayrıca amaçlanan değerin boyutu / aralığı hakkında küçük bir hatırlatma sağlar.

Yıllardır Borland'ın açık ilkel tür adlarını ve #includeherhangi bir C / C ++ derleyicisi için bu adlarla açık ilkel türleri tanımlamayı amaçlayan aşağıdaki C / C ++ başlık dosyasını (primitive.h) kullandım (bu başlık dosyası aslında her şeyi kapsamayabilir) derleyici, ancak Windows, UNIX ve Linux'ta kullandığım birkaç derleyiciyi kapsıyor, ayrıca (henüz) 64bit türleri tanımlamıyor).

#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 <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
#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

C99, int32_t, uint64_t, vb. Gibi görünen typdefs'in derleyici tarafından tanımlandığını ve tam olarak adından da anlaşılacağı gibi çok sayıda biti olduğunu belirtir. Çoğu C ++ derleyicisi (g ++ dahil) bu sabitleri C ++ kodunda kullanmanıza izin verir.
rmeador

5

C ++ Standart şöyle der:

3.9.1, §2:

Beş işaretli tam sayı türü vardır: "işaretli karakter", "kısa int", "int", "long int" ve "long long int". Bu listede, her tür, listede kendisinden önce gelenler kadar en az depolama alanı sağlar. Düzlükler, yürütme ortamının mimarisinin önerdiği doğal boyuta sahiptir (44); diğer işaretli tam sayı türleri özel ihtiyaçları karşılamak için sağlanır.

(44) yani başlıkta tanımlandığı gibi INT_MIN ve INT_MAX aralığındaki herhangi bir değeri içerecek kadar büyük <climits> .

Sonuç: hangi mimari üzerinde çalıştığınıza bağlıdır. Diğer herhangi bir varsayım yanlıştır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.