Saya mencari informasi terperinci mengenai ukuran tipe dasar C ++. Saya tahu bahwa itu tergantung pada arsitektur (16 bit, 32 bit, 64 bit) dan kompiler.
Tetapi apakah ada standar untuk C ++?
Saya menggunakan Visual Studio 2008 pada arsitektur 32-bit. Inilah yang saya dapatkan:
char : 1 byte
short : 2 bytes
int : 4 bytes
long : 4 bytes
float : 4 bytes
double: 8 bytes
Saya mencoba mencari, tanpa banyak keberhasilan, informasi yang dapat dipercaya menyatakan ukuran char
, short
, int
, long
, double
, float
(dan jenis lain saya tidak memikirkan) di bawah arsitektur yang berbeda dan compiler.
int16_t
,int32_t
danint64_t
(perluiostream
menyertakan untuk itu jika saya ingat dengan benar). Apa yang baik tentang ini bahwa int64_t seharusnya tidak memiliki masalah pada sistem 32bit (ini akan mempengaruhi kinerja).<cstdint>
, bukan<iostream>
.Jawaban:
Standar C ++ tidak menentukan ukuran tipe integral dalam byte, tetapi menentukan rentang minimum yang harus dapat dipegang. Anda dapat menyimpulkan ukuran minimum dalam bit dari rentang yang diperlukan. Anda dapat menyimpulkan ukuran minimum dalam byte dari itu dan nilai
CHAR_BIT
makro yang mendefinisikan jumlah bit dalam byte . Dalam semua platform kecuali yang paling tidak jelas itu 8, dan tidak boleh kurang dari 8. Itu karena itu harus cukup besar untuk menampung "unit kode delapan-bit dari bentuk pengkodean Unicode UTF-8."Satu kendala tambahan
char
adalah ukurannya selalu 1 byte, atauCHAR_BIT
bit (karena itu namanya). Ini dinyatakan secara eksplisit dalam standar.Standar C adalah referensi normatif untuk standar C ++, jadi meskipun tidak menyatakan persyaratan ini secara eksplisit, C ++ memerlukan rentang minimum yang disyaratkan oleh standar C (halaman 22), yang sama dengan yang berasal dari Tipe Data Mulai dari MSDN :
signed char
: -127 hingga 127 (catatan, bukan -128 hingga 127; ini mengakomodasi platform 1-pelengkap dan tanda-dan-besarnya)unsigned char
: 0 hingga 255char
: rentang yang sama dengansigned char
atauunsigned char
, didefinisikan oleh implementasisigned short
: -32767 hingga 32767unsigned short
: 0 hingga 65535signed int
: -32767 hingga 32767unsigned int
: 0 hingga 65535signed long
: -2147483647 hingga 2147483647unsigned long
: 0 hingga 4294967295signed long long
: -9223372036854775807 hingga 9223372036854775807unsigned long long
: 0 hingga 18446744073709551615Implementasi C ++ (atau C) dapat menentukan ukuran tipe dalam byte
sizeof(type)
ke nilai apa pun, asalkansizeof(type) * CHAR_BIT
mengevaluasi sejumlah bit yang cukup tinggi untuk memuat rentang yang diperlukan, dansizeof(int) <= sizeof(long)
.).Menyatukan semua ini, kami dijamin bahwa:
char
,,signed char
danunsigned char
setidaknya 8 bitsigned short
,unsigned short
,signed int
, Danunsigned int
setidaknya 16 bitsigned long
danunsigned long
setidaknya 32 bitsigned long long
danunsigned long long
setidaknya 64 bitTidak ada jaminan dibuat tentang ukuran
float
ataudouble
kecuali yangdouble
memberikan setidaknya setepat sebanyakfloat
.Rentang implementasi spesifik aktual dapat ditemukan di
<limits.h>
header di C, atau<climits>
di C ++ (atau bahkan lebih baik, templatedstd::numeric_limits
di<limits>
header).Misalnya, ini adalah bagaimana Anda akan menemukan rentang maksimum untuk
int
:C:
C ++ :
sumber
char
", dan bukan arti yang biasa.Untuk sistem 32-bit, standar 'de facto' adalah ILP32 - yaitu
int
,,long
dan pointer semuanya berjumlah 32-bit.Untuk sistem 64-bit, standar utama Unix 'de facto' adalah LP64 -
long
dan penunjuknya adalah 64-bit (tetapiint
32-bit). Windows 64-bit standar LLP64 -long long
dan pointer adalah 64-bit (tapilong
danint
yang kedua 32-bit).Pada suatu waktu, beberapa sistem Unix menggunakan organisasi ILP64.
Tidak satu pun dari standar de facto ini yang diundangkan oleh standar C (ISO / IEC 9899: 1999), tetapi semua diizinkan olehnya.
Dan, menurut definisi,
sizeof(char)
adalah1
, terlepas dari pengujian dalam skrip konfigurasikan Perl.Perhatikan bahwa ada mesin (Crays) di mana
CHAR_BIT
jauh lebih besar dari 8. Itu berarti, IIRC,sizeof(int)
itu juga 1, karena keduanyachar
danint
32-bit.sumber
[u]int32_t
atau serupa, jika Anda ingin menggunakan 64 bit[u]int64_t
... jika Anda tidak memiliki header untuk mereka, unduh atau buat, sebaiknya dengan kompilasi waktu pemilihan jenis atau pernyataan statis untuk memverifikasi ukuran. pubs.opengroup.org/onlinepubs/009695299/basedefs/stdint.h.html Jika ukuran yang tepat tidak begitu penting dan Anda hanya peduli mereka setidaknya sebesar itu, maka saran Anda berlaku untuk platform PC / server modern yang umum.int get_char(FILE *fp, char *c)
yang mengembalikan EOF atau 0 dan set*c
.uint32_t x=1,y=2;
nilaix-y
harus 4294967295 pada platform di mana "int" adalah 32 bit atau lebih kecil, dan -1 pada platform di mana "int" adalah 33 bit atau lebih besar. Lebih jauh lagi, diperlukan bahwax*y
harus dievaluasi menggunakan modular aritmatika untuk semua nilai x dan y jika "int" adalah 32 bit atau lebih kecil, dan aritmatika konvensional jika 65 bit atau lebih besar, tetapi tidak menempatkan persyaratan apa pun pada apa yang mungkin terjadi dengan nilai besar dari x dan y jika "int" adalah 33 hingga 64 bit.Dalam prakteknya tidak ada hal seperti itu. Seringkali Anda bisa berharap
std::size_t
mewakili ukuran integer asli yang tidak ditandatangani pada arsitektur saat ini. yaitu 16-bit, 32-bit atau 64-bit tetapi tidak selalu seperti yang ditunjukkan dalam komentar untuk jawaban ini.Sejauh semua tipe bawaan lainnya berjalan, itu benar-benar tergantung pada kompiler. Berikut adalah dua kutipan yang diambil dari draft kerja standar C ++ terbaru:
Jika Anda mau, Anda dapat secara statis (waktu kompilasi) menyatakan ukuran dari tipe-tipe mendasar ini. Ini akan mengingatkan orang untuk berpikir tentang porting kode Anda jika ukuran asumsi berubah.
sumber
Ada standar.
Standar C90 mensyaratkan itu
Standar C99 mensyaratkan itu
Berikut adalah spesifikasi C99 . Halaman 22 merinci ukuran berbagai tipe integral.
Berikut adalah ukuran tipe int (bit) untuk platform Windows:
Jika Anda khawatir dengan portabilitas, atau Anda ingin nama tipe mencerminkan ukuran, Anda dapat melihat headernya
<inttypes.h>
, di mana makro berikut tersedia:int8_t
dijamin 8 bit, danint16_t
dijamin 16 bit, dll.sumber
sizeof(long) < sizeof(long long)
berlawanan dengan simetrissizeof(long) <= sizeof(long long)
?Jika Anda membutuhkan tipe ukuran tetap, gunakan tipe seperti uint32_t (unsigned integer 32 bits) yang didefinisikan di stdint.h . Mereka ditentukan dalam C99 .
sumber
CHAR_BIT == 16
, misalnya, tidak akan milikiint8_t
. Platform tidak menggunakan komplemen tidak akan memiliki setiap dari mereka (sebagai komplemen diperlukan oleh standar).Diperbarui: C ++ 11 membawa tipe-tipe dari TR1 secara resmi ke dalam standar:
Dan jenis "berukuran" dari
<cstdint>
Plus Anda mendapatkan:
Tipe-tipe ini mewakili tipe integer terkecil dengan setidaknya jumlah bit yang ditentukan. Demikian juga ada tipe integer "tercepat" dengan setidaknya jumlah bit yang ditentukan:
Apa yang dimaksud dengan "cepat", jika ada, terserah implementasi. Tidak perlu menjadi yang tercepat untuk semua keperluan juga.
sumber
Standar C ++ mengatakannya seperti ini:
3.9.1, §2:
Kesimpulannya: Itu tergantung pada arsitektur yang sedang Anda kerjakan. Asumsi lain salah.
sumber
Tidak, tidak ada standar untuk ukuran tipe. Standar hanya mensyaratkan bahwa:
Hal terbaik yang dapat Anda lakukan jika Anda ingin variabel ukuran tetap adalah menggunakan makro seperti ini:
Kemudian Anda bisa menggunakan WORD untuk mendefinisikan variabel Anda. Bukannya saya suka ini tapi ini cara yang paling portabel .
sumber
#include <boost/cstdint.hpp>
Kami diizinkan untuk menentukan sinonim untuk jenis sehingga kami dapat membuat "standar" kami sendiri.
Pada mesin di mana sizeof (int) == 4, kita dapat mendefinisikan:
Jadi ketika kita mentransfer kode ke mesin yang berbeda di mana sebenarnya ukuran int panjang adalah 4, kita bisa mendefinisikan ulang kejadian int tunggal.
sumber
<stdint.h>
(C99 dan yang lebih baru, dan mana pun standar C ++ yang mengadopsi versi C99 dari pustaka C).Untuk angka floating point ada standar (IEEE754) : floats adalah 32 bit dan double adalah 64. Ini adalah standar perangkat keras, bukan standar C ++, jadi kompiler secara teoritis dapat mendefinisikan float dan double ke beberapa ukuran lain, tetapi dalam praktiknya saya ' Saya belum pernah melihat arsitektur yang menggunakan sesuatu yang berbeda.
sumber
double
memiliki ukuran yang samafloat
(danint
sama sepertichar
, keduanya 16 bit). Tetapi mereka memiliki 64 bitlong double
.Ada standar dan ditentukan dalam berbagai dokumen standar (ISO, ANSI dan yang lainnya).
Wikipedia memiliki halaman yang bagus menjelaskan berbagai jenis dan maks yang dapat mereka simpan: Integer dalam Ilmu Komputer.
Namun bahkan dengan kompiler C ++ standar Anda dapat mengetahuinya dengan relatif mudah menggunakan potongan kode berikut:
Dokumentasi untuk std :: numeric_limits dapat ditemukan di Roguewave . Ini termasuk sejumlah perintah lain yang dapat Anda panggil untuk mengetahui berbagai batasan. Ini dapat digunakan dengan jenis sembarang yang menyampaikan ukuran, misalnya std :: streamsize.
Jawaban John berisi deskripsi terbaik, karena dijamin akan tetap berlaku. Tidak peduli platform apa yang Anda gunakan, ada halaman bagus lain yang menjelaskan lebih detail berapa banyak bit yang masing-masing harus isi: tipe int , yang didefinisikan dalam standar.
Saya harap ini membantu!
sumber
1) Tabel N1 dalam artikel " Masalah yang terlupakan dari pengembangan program 64-bit "
2) " Model data "
sumber
Kamu bisa menggunakan:
datatype = int
,long int
dll. Anda akan dapat melihat ukuran untuk tipe data apa pun yang Anda ketikkan.sumber
Ketika datang ke tipe built in untuk arsitektur yang berbeda dan kompiler yang berbeda jalankan saja kode berikut pada arsitektur Anda dengan kompiler Anda untuk melihat apa yang dihasilkannya. Di bawah ini menunjukkan keluaran Ubuntu 13.04 (Raring Ringtail) 64 bit g ++ 4.7.3 saya. Harap perhatikan juga apa yang dijawab di bawah ini sehingga outputnya dipesan seperti ini:
"Ada lima tipe integer bertanda tangan standar: char yang ditandatangani, int pendek, int, int panjang, dan int panjang. Dalam daftar ini, masing-masing jenis menyediakan penyimpanan setidaknya sebanyak yang sebelumnya dalam daftar."
sumber
sizeof(char)
seharusnya tidak dimasukkan.Seperti disebutkan ukurannya harus mencerminkan arsitektur saat ini. Anda dapat mengambil puncak di
limits.h
jika Anda ingin melihat bagaimana kompiler Anda saat ini menangani hal-hal.sumber
Seperti yang dijawab oleh orang lain, "standar" semuanya meninggalkan sebagian besar detail sebagai "implementasi yang ditentukan" dan hanya menyatakan bahwa tipe "char" setidaknya "char_bis" lebar, dan "char <= short <= int <= long < = long long "(float dan double cukup konsisten dengan standar floating point IEEE, dan double panjang biasanya sama dengan double - tetapi mungkin lebih besar pada implementasi yang lebih terkini).
Sebagian alasan untuk tidak memiliki nilai yang sangat spesifik dan tepat adalah karena bahasa seperti C / C ++ dirancang untuk portabel ke sejumlah besar platform perangkat keras - Termasuk sistem komputer di mana ukuran kata "char" mungkin 4-bit atau 7-bit, atau bahkan beberapa nilai selain dari komputer "8- / 16- / 32- / 64-bit" yang biasa dilihat oleh pengguna komputer rumahan. (Word-size di sini berarti berapa banyak bit lebar sistem biasanya beroperasi - Sekali lagi, itu tidak selalu 8-bit seperti yang diharapkan oleh pengguna komputer di rumah.)
Jika Anda benar-benar membutuhkan objek (dalam arti serangkaian bit yang mewakili nilai integral) dari jumlah bit tertentu, sebagian besar kompiler memiliki beberapa metode untuk menentukan itu; Tapi itu umumnya tidak portabel, bahkan antara kompiler yang dibuat oleh perusahaan ame tetapi untuk platform yang berbeda. Beberapa standar dan praktik (terutama limit.h dan sejenisnya) cukup umum sehingga sebagian besar penyusun akan memiliki dukungan untuk menentukan jenis yang paling cocok untuk rentang nilai tertentu, tetapi bukan jumlah bit yang digunakan. (Yaitu, jika Anda tahu Anda perlu menyimpan nilai antara 0 dan 127, Anda dapat menentukan bahwa kompiler Anda mendukung tipe 8-bit "int8" yang akan cukup besar untuk menampung rentang penuh yang diinginkan, tetapi bukan sesuatu seperti Tipe "int7" yang akan cocok dengan 7-bit.)
Catatan: Banyak paket sumber Un * x menggunakan skrip "./configure" yang akan menyelidiki kapabilitas kompiler / sistem dan menghasilkan Makefile dan config.h yang sesuai. Anda dapat memeriksa beberapa skrip ini untuk melihat cara kerjanya dan bagaimana mereka menyelidiki kemampuan comiler / sistem, dan mengikuti jejak mereka.
sumber
Jika Anda tertarik dengan solusi C ++ murni, saya menggunakan template dan hanya kode standar C ++ untuk mendefinisikan tipe pada waktu kompilasi berdasarkan pada ukuran bitnya. Ini membuat solusi portable di kompiler.
Gagasan di baliknya sangat sederhana: Buat daftar yang berisi tipe char, int, pendek, panjang, panjang (versi yang ditandatangani dan tidak ditandatangani) dan pindai daftar dan dengan menggunakan template numeric_limits pilih jenis dengan ukuran yang diberikan.
Termasuk tajuk ini, Anda mendapatkan 8 tipe stdtype :: int8, stdtype :: int16, stdtype :: int32, stdtype :: int64, stdtype :: uint8, stdtype :: uint16, stdtype :: uint32, stdtype :: uint64.
Jika beberapa jenis tidak dapat diwakili itu akan dievaluasi ke stdtype :: null_type juga dideklarasikan di header itu.
KODE DI BAWAH INI DIBERIKAN TANPA GARANSI, TOLONG GANDA CEK.
AKU BARU DI METAPROGRAMMING JUGA, MERASA GRATIS UNTUK MENGEDIT DAN MEMPERBAIKI KODE INI.
Diuji dengan DevC ++ (jadi versi gcc sekitar 3,5)
sumber
di mana
X
adalahchar
,int
,long
dll .. akan memberikan ukuranX
dalam bit.sumber
sizeof(type)*CHAR_BIT
memegangCHAR_BIT
dijamin menjadi 8 bit,<< 3
hanyalah cara yang membingungkan untuk menulis* 8
atau* CHAR_BIT
.Dari Alex B Standar C ++ tidak menentukan ukuran tipe integral dalam byte, tetapi menentukan rentang minimum yang harus mereka pegang. Anda dapat menyimpulkan ukuran minimum dalam bit dari rentang yang diperlukan. Anda dapat menyimpulkan ukuran minimum dalam byte dari itu dan nilai makro CHAR_BIT yang mendefinisikan jumlah bit dalam byte (di semua kecuali platform yang paling tidak jelas itu 8, dan tidak bisa kurang dari 8).
Satu kendala tambahan untuk char adalah ukurannya selalu 1 byte, atau CHAR_BIT bit (karena itu namanya).
Kisaran minimum yang disyaratkan oleh standar (halaman 22) adalah:
dan Kisaran Tipe Data di MSDN:
menandatangani char: -127 hingga 127 (catatan, bukan -128 hingga 127; ini mengakomodasi platform 1's-pelengkap) char tanpa tanda tangan: 0 hingga 255 char "polos": -127 hingga 127 atau 0 hingga 255 (tergantung pada penandatanganan char default) ditandatangani pendek: -32767 hingga 32767 unsigned pendek: 0 hingga 65535 ditandatangani int: -32767 hingga 32767 int ditandatangani: 0 hingga 65535 ditandatangani panjang: -2147483647 hingga 2147483647 unsigned panjang: 0 hingga 4294967295 ditandatangani lama: -9223372036854775807 0 hingga 18446744073709551615 Implementasi C ++ (atau C) dapat menentukan ukuran suatu tipe dalam byte sizeof (tipe) dengan nilai apa saja, selama
ekspresi sizeof (tipe) * CHAR_BIT mengevaluasi jumlah bit yang cukup untuk memuat rentang yang diperlukan, dan urutan tipe masih valid (mis. sizeof (int) <= sizeof (panjang)). Rentang implementasi spesifik yang sebenarnya dapat ditemukan di header di C, atau di C ++ (atau bahkan lebih baik, templated std :: numeric_limits di header).
Misalnya, ini adalah bagaimana Anda akan menemukan rentang maksimum untuk int:
C:
C ++:
Ini benar, namun, Anda juga benar dalam mengatakan bahwa: char: 1 byte pendek: 2 byte int: 4 byte panjang: 4 byte float: 4 byte ganda: 8 byte
Karena arsitektur 32 bit masih merupakan standar dan paling banyak digunakan, dan mereka telah mempertahankan ukuran standar ini sejak pra-32 bit saat memori kurang tersedia, dan untuk kompatibilitas dan standardisasi mundur tetap sama. Bahkan sistem 64 bit cenderung menggunakan ini dan memiliki perluasan / modifikasi. Silakan rujuk ini untuk informasi lebih lanjut:
http://en.cppreference.com/w/cpp/language/types
sumber
Saya perhatikan bahwa semua jawaban lain di sini telah berfokus hampir secara eksklusif pada tipe integral, sementara si penanya juga bertanya tentang poin-poin mengambang.
Saya tidak berpikir standar C ++ memerlukannya, tetapi kompiler untuk platform paling umum hari ini umumnya mengikuti standar IEEE754 untuk angka floating-point mereka. Standar ini menetapkan empat jenis biner floating-point (serta beberapa format BCD, yang belum pernah saya lihat dukungannya dalam kompiler C ++):
Bagaimana peta ini ke tipe C ++, lalu? Umumnya
float
menggunakan presisi tunggal; demikiansizeof(float) = 4
,. Kemudiandouble
gunakan presisi ganda (saya percaya itu sumber namanyadouble
), danlong double
mungkin presisi ganda atau empat kali lipat (itu empat kali lipat pada sistem saya, tetapi pada sistem 32-bit mungkin ganda). Saya tidak tahu ada kompiler yang menawarkan floating-point setengah presisi.Singkatnya, ini adalah yang biasa:
sizeof(float)
= 4sizeof(double)
= 8sizeof(long double)
= 8 atau 16sumber
Seperti yang Anda sebutkan - sebagian besar tergantung pada kompiler dan platform. Untuk ini, periksa standar ANSI, http://home.att.net/~jackklein/c/inttypes.html
Inilah yang untuk kompiler Microsoft: Kisaran Jenis Data .
sumber
Anda dapat menggunakan variabel yang disediakan oleh perpustakaan seperti OpenGL , Qt , dll.
Sebagai contoh, Qt menyediakan qint8 (dijamin 8-bit pada semua platform yang didukung oleh Qt), qint16, qint32, qint64, quint8, quint16, quint32, quint64, dll.
sumber
Pada mesin 64-bit:
sumber
int
adalah 8 byte, tetapi yang lain tidak dijamin. Tidak ada yang mengatakan bahwachar
seharusnya hanya 8 bit. Itu diizinkan untuk memilikisizeof(void*)==4
meskipun itu 64 bit.Ada empat jenis bilangan bulat berdasarkan ukuran:
sumber
short
,int
danlong
semua integer 32 bit.int
, bukan kata "integer".