Apa perbedaan antara int dan a long di C ++?

120

Koreksi saya jika saya salah,

int adalah 4 byte, dengan kisaran nilai dari -2,147,483,648 hingga 2,147,483,647 (2 ^ 31)
panjangnya adalah 4 byte, dengan kisaran nilai dari -2,147,483,648 hingga 2,147,483,647 (2 ^ 31)

Apa perbedaan C ++? Bisakah mereka digunakan secara bergantian?

Joel
sumber
Dalam VS2005 saya berjalan pada prosesor 32 bit, ukuran default int adalah 4 byte.
Jika Anda ingin menulis kode portabel, pertimbangkan untuk menggunakan #include <stdint.h>dan kemudian jenis yang menentukan ukurannya. Mis uint32_t. Pada platform baru, Anda hanya perlu memastikan stdint.h melakukannya dengan benar untuk platform tertentu dan kode Anda berfungsi sebagaimana mestinya.
BitTickler

Jawaban:

112

Ini tergantung pada implementasi.

Misalnya, di bawah Windows mereka sama, tetapi misalnya pada sistem Alpha panjangnya 64 bit sedangkan int adalah 32 bit. Artikel ini membahas aturan untuk kompiler Intel C ++ pada platform variabel. Untuk meringkas:

  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  
Rob Walker
sumber
Saya pikir kita harus mempertimbangkan untuk menggabungkan jawaban ini (jawaban dengan contoh) dengan beberapa detail di bawah ini mengenai standar C ++. Draf untuk C ++ 0x ada di open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2798.pdf dan telah di-markup sehingga Anda dapat melihat perbedaan antara itu dan rev terakhir.
Patrick Johnmeyer
Memasukkan sesuatu pada urutan ukuran relatif dari jenisnya menghasilkan lebih banyak informasi daripada menghitung ukuran untuk platform yang berbeda - seperti status @Kevin dengan sangat baik. (-1vote)
xtofl
2
Beberapa kompiler bahkan memiliki flag yang mengijinkan Anda untuk mengubah ukuran default dari int dan long yaitu memaksanya menjadi 8 atau 16 dll. Lihat dokumentasi compiler Anda untuk lebih detil.
Martin York
7
NB bahwa ini adalah ukuran long
rogerdpack
1
Harap sertakan ukuran int juga.
cegprakash
82

Satu-satunya jaminan yang Anda miliki adalah:

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

Juga lihat: Apakah longdijamin minimal 32 bit?

Martin York
sumber
1
Hmm, ini tidak berlaku, jika sizeof (pendek)> = sizeof (char) kita hanya tahu bahwa sizeof (pendek)> = 1 (bukan> = 2), yang btw berlaku untuk semua tipe. Menurut sizeof ini (tipe integral)> = 1. Mana yang benar, misalnya saya ingat sizeof (int) == 1 pada Z80, tetapi apakah tidak ada jaminan yang lebih kuat untuk waktu yang lama?
Andreas Magnusson
6
3.9.1.2 dari standar C ++ menetapkan bahwa sizeof (long)> = sizeof (int)> = sizeof (short)> = sizeof (char) 5.3.3.1 dari standar C ++ menentukan sizeof (char), sizeof (unsigned char) , dan sizeof (karakter bertanda tangan) sama dengan 1. (lanjutan)
KTC
4
(... lanjutan) Nilai maksimum dan minimum yang dapat diwakili oleh tipe integral didefinisikan sebagai makro di <batas.h> (dan karenanya <climits>). Lampiran E standar C (1990), yang disertakan dengan referensi dari standar C ++, menentukan besaran minimum makro ini. (lanjutan ...)
KTC
4
(... cont) dan mereka adalah (2 ^ 15) -1, (2 ^ 15) -1, (2 ^ 31) -1, masing-masing untuk pendek, int, dan panjang, yang menghasilkan nilai sebagai diposting oleh Martin York dalam tanggapannya di sini jika CHAR_BIT adalah 8 (yang juga merupakan nilai minimumnya).
KTC
2
@ Giles: Bukankah itu yang saya katakan di atas? sizeof (pendek) * CHAR_BITS> = 16. Plust beberapa hal lainnya. :-)
Martin York
13

Saat mengompilasi untuk x64, perbedaan antara int dan long berada di antara 0 dan 4 byte, tergantung pada kompiler yang Anda gunakan.

GCC menggunakan model LP64, yang berarti int adalah 32-bit tetapi panjang adalah 64-bit dalam mode 64-bit.

MSVC misalnya menggunakan model LLP64, yang berarti int dan long adalah 32-bit bahkan dalam mode 64-bit.

Adrian
sumber
mungkin 0 byte? hmm
rogerdpack
12

Spesifikasi C ++ itu sendiri (versi lama tetapi cukup baik untuk ini) membiarkannya terbuka.

Ada empat jenis bilangan bulat bertanda: ' signed char', ' short int', ' int', dan 'long int '. Dalam daftar ini, setiap jenis menyediakan setidaknya penyimpanan sebanyak yang sebelumnya dalam daftar. Int biasa memiliki ukuran alami yang disarankan oleh arsitektur lingkungan eksekusi *;

[Catatan kaki: cukup besar untuk memuat nilai apa pun dalam rentang INT_MIN dan INT_MAX, seperti yang ditentukan di tajuk <climits>. --- akhiri foonote]

Kevin Haines
sumber
7

Seperti yang ditunjukkan Kevin Haines, int memiliki ukuran alami yang disarankan oleh lingkungan eksekusi, yang harus sesuai dengan INT_MIN dan INT_MAX.

Standar C89 menyatakan bahwa UINT_MAXsetidaknya harus 2 ^ 16-1, USHRT_MAX2 ^ 16-1 dan ULONG_MAX2 ^ 32-1. Itu membuat hitungan bit setidaknya 16 untuk pendek dan int, dan 32 untuk panjang. Untuk char itu menyatakan secara eksplisit bahwa ia harus memiliki setidaknya 8 bit ( CHAR_BIT). C ++ mewarisi aturan tersebut untuk file limit.h, jadi di C ++ kita memiliki persyaratan dasar yang sama untuk nilai tersebut. Namun Anda tidak boleh mendapatkan dari int yang setidaknya 2 byte. Secara teoritis, char, int dan long semuanya bisa 1 byte, dalam hal ini CHAR_BITminimal harus 32. Ingatlah bahwa "byte" selalu seukuran char, jadi jika char lebih besar, byte tidak hanya 8 bit saja. lebih.

Johannes Schaub - litb
sumber
Saya tidak berpikir bytetipe data ada di C ++. Tidak, bukan? Jika ya, dan bytekaleng memiliki ukuran selain 8 bit, itu benar-benar bodoh. Mengapa mereka menyebutnya byte kecuali jika benar-benar harus 8 bit?
Alderath
6

Itu tergantung pada kompiler Anda. Anda dijamin bahwa panjang akan setidaknya sebesar int, tetapi Anda tidak dijamin bahwa itu akan lebih lama lagi.

Andru Luvisi
sumber
5

Sebagian besar, jumlah byte dan rentang nilai ditentukan oleh arsitektur CPU, bukan oleh C ++. Namun, C ++ menetapkan persyaratan minimum, yang dijelaskan litb dengan benar dan Martin York hanya membuat beberapa kesalahan.

Alasan mengapa Anda tidak dapat menggunakan int dan long secara bergantian adalah karena panjangnya tidak selalu sama. C ditemukan pada PDP-11 di mana satu byte memiliki 8 bit, int adalah dua byte dan dapat ditangani langsung oleh instruksi perangkat keras. Karena pemrogram C sering membutuhkan aritmatika empat-byte, panjang ditemukan dan empat byte, ditangani oleh fungsi perpustakaan. Mesin lain memiliki spesifikasi yang berbeda. Standar C memberlakukan beberapa persyaratan minimum.

Pemrogram Windows
sumber
5

Mengandalkan implementasi vendor compiler untuk ukuran tipe primitif AKAN kembali menghantui Anda jika Anda pernah mengompilasi kode Anda pada arsitektur mesin lain, OS, atau compiler vendor lain.

Sebagian besar vendor compiler menyediakan file header yang mendefinisikan tipe primitif dengan ukuran tipe explict. Jenis primitif ini harus digunakan ketika kode mungkin berpotensi di-porting ke kompiler lain (baca ini sebagai SELALU dalam SETIAP contoh). Misalnya, sebagian besar kompiler UNIX memiliki int8_t uint8_t int16_t int32_t uint32_t. Microsoft memiliki INT8 UINT8 INT16 UINT16 INT32 UINT32. Saya lebih suka Borland / CodeGear int8 uint8 int16 uint16 int32 uint32. Nama-nama ini juga memberikan sedikit pengingat akan ukuran / range dari nilai yang diinginkan.

Selama bertahun-tahun saya telah menggunakan nama tipe primitif eksplisit Borland dan #includefile header C / C ++ berikut (primitive.h) yang dimaksudkan untuk mendefinisikan tipe primitif eksplisit dengan nama-nama ini untuk kompiler C / C ++ (file header ini mungkin tidak benar-benar mencakup setiap compiler tetapi mencakup beberapa kompiler yang telah saya gunakan pada Windows, UNIX dan Linux, itu juga (belum) mendefinisikan tipe 64bit).

#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
Roger Nelson
sumber
C99 mengamanatkan bahwa typdef yang terlihat seperti int32_t, uint64_t, dll. Didefinisikan oleh kompilator dan memiliki bit sebanyak yang disarankan namanya. Kebanyakan kompiler C ++ (termasuk g ++) akan mengizinkan Anda menggunakan konstanta ini dalam kode C ++.
pemimpin
5

Standar C ++ mengatakannya seperti ini:

3.9.1, §2:

Ada lima jenis bilangan bulat bertanda: "char bertanda tangan", "short int", "int", "long int", dan "long long int". Dalam daftar ini, setiap jenis menyediakan setidaknya penyimpanan sebanyak yang sebelumnya dalam daftar. Plain int memiliki ukuran alami yang disarankan oleh arsitektur lingkungan eksekusi (44); jenis bilangan bulat bertanda tangan lainnya disediakan untuk memenuhi kebutuhan khusus.

(44) yaitu, cukup besar untuk memuat nilai apa pun dalam rentang INT_MIN dan INT_MAX, seperti yang ditentukan di tajuk <climits> .

Kesimpulannya: itu tergantung pada arsitektur mana yang sedang Anda kerjakan. Asumsi lainnya salah.

Jérôme Radix
sumber